Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Functions | Variables
callerid.c File Reference

CallerID Generation support. More...

#include "asterisk.h"
#include <time.h>
#include <math.h>
#include <ctype.h>
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/fskmodem.h"
#include "asterisk/utils.h"
#include "asterisk/format_cache.h"

Go to the source code of this file.

Data Structures

struct  ast_value_translation
 
struct  callerid_state
 

Macros

#define AST_CALLERID_UNKNOWN   "<unknown>"
 
#define CALLERID_MARK   1200.0
 
#define CALLERID_SPACE   2200.0
 
#define CAS_FREQ1   2130.0
 
#define CAS_FREQ2   2750.0
 
#define SAS_FREQ   440.0
 

Functions

static int __ast_callerid_generate (unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, int format, int callwaiting, struct ast_format *codec, const char *tz)
 
int ast_callerid_callwaiting_full_generate (unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec)
 Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) More...
 
int ast_callerid_callwaiting_full_tz_generate (unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec, const char *tz)
 Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) More...
 
int ast_callerid_callwaiting_generate (unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
 Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) More...
 
int ast_callerid_full_generate (unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec)
 Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format) More...
 
int ast_callerid_full_tz_generate (unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec, const char *tz)
 Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format) More...
 
int ast_callerid_generate (unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
 Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format) More...
 
char * ast_callerid_merge (char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
 
int ast_callerid_parse (char *input_str, char **name, char **location)
 Destructively parse inbuf into name and location (or number) More...
 
int ast_callerid_split (const char *buf, char *name, int namelen, char *num, int numlen)
 
int ast_callerid_vmwi_generate (unsigned char *buf, int active, int type, struct ast_format *codec, const char *name, const char *number, int flags)
 Generate message waiting indicator. More...
 
const char * ast_connected_line_source_describe (int data)
 Convert connected line update source value to explanatory string. More...
 
const char * ast_connected_line_source_name (int data)
 Convert connected line update source value to text code. More...
 
int ast_connected_line_source_parse (const char *data)
 Convert connected line update source text code to value (used in config file parsing) More...
 
const char * ast_describe_caller_presentation (int data)
 Convert caller ID pres value to explanatory string. More...
 
int ast_gen_cas (unsigned char *outbuf, int sendsas, int len, struct ast_format *codec)
 Generate a CAS (CPE Alert Signal) tone for 'n' samples. More...
 
int ast_is_shrinkable_phonenumber (const char *exten)
 Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_phone_number) More...
 
static int ast_is_valid_string (const char *exten, const char *valid)
 Checks if phone number consists of valid characters. More...
 
int ast_isphonenumber (const char *n)
 Check if a string consists only of digits and + #. More...
 
const char * ast_named_caller_presentation (int data)
 Convert caller ID pres value to text code. More...
 
int ast_parse_caller_presentation (const char *data)
 Convert caller ID text code to value (used in config file parsing) More...
 
const char * ast_party_name_charset_describe (int data)
 Convert ast_party_name.char_set value to explanatory string. More...
 
int ast_party_name_charset_parse (const char *data)
 Convert ast_party_name.char_set text code to value (used in config file parsing) More...
 
const char * ast_party_name_charset_str (int data)
 Convert ast_party_name.char_set value to text code. More...
 
const char * ast_redirecting_reason_describe (int data)
 Convert redirecting reason value to explanatory string. More...
 
const char * ast_redirecting_reason_name (const struct ast_party_redirecting_reason *data)
 Convert redirecting reason value to text code. More...
 
int ast_redirecting_reason_parse (const char *data)
 Convert redirecting reason text code to value (used in config file parsing) More...
 
void ast_shrink_phone_number (char *n)
 Clean up phone string. More...
 
static unsigned short calc_crc (unsigned short crc, unsigned char data)
 
int callerid_feed (struct callerid_state *cid, unsigned char *ubuf, int len, struct ast_format *codec)
 Read samples into the state machine. More...
 
int callerid_feed_jp (struct callerid_state *cid, unsigned char *ubuf, int len, struct ast_format *codec)
 Read samples into the state machine. More...
 
void callerid_free (struct callerid_state *cid)
 This function frees callerid_state cid. More...
 
int callerid_full_generate (unsigned char *buf, const char *number, const char *name, const char *ddn, int redirecting, int flags, int format, int callwaiting, struct ast_format *codec)
 Generates a CallerID FSK stream in ulaw format suitable for transmission. More...
 
int callerid_full_tz_generate (unsigned char *buf, const char *number, const char *name, const char *ddn, int redirecting, int flags, int format, int callwaiting, struct ast_format *codec, const char *tz)
 Generates a CallerID FSK stream in ulaw format suitable for transmission. More...
 
int callerid_generate (unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec)
 Generates a CallerID FSK stream in ulaw format suitable for transmission. More...
 
static int callerid_genmsg (char *msg, int size, const char *number, const char *name, int flags, int format, const char *ddn, int redirecting, const char *tz)
 
void callerid_get (struct callerid_state *cid, char **name, char **number, int *flags)
 Extract info out of callerID state machine. Flags are listed above. More...
 
void callerid_get_dtmf (char *cidstring, char *number, int *flags)
 Get and parse DTMF-based callerid. More...
 
void callerid_get_with_redirecting (struct callerid_state *cid, char **name, char **number, int *flags, int *redirecting)
 Extract info out of callerID state machine. Flags are listed above. More...
 
void callerid_init (void)
 Initialize stuff for inverse FFT. More...
 
struct callerid_statecallerid_new (int cid_signalling)
 Create a callerID state machine. More...
 
static void gen_tone (unsigned char *buf, int len, struct ast_format *codec, float ddr1, float ddi1, float *cr1, float *ci1)
 
static void gen_tones (unsigned char *buf, int len, struct ast_format *codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
 
static const char * mdmf_param_name (int param)
 

Variables

float casdi1
 
float casdi2
 
float casdr1
 
float casdr2
 
float cid_di [4]
 
float cid_dr [4]
 
float clidsb = 8000.0 / 1200.0
 
static const struct ast_value_translation connected_line_source_types []
 Translation table for connected line update source settings.
 
static const struct ast_value_translation party_name_charset_tbl []
 Translation table for ast_party_name char-set settings.
 
static const struct ast_value_translation pres_types []
 Translation table for Caller ID Presentation settings.
 
static const struct ast_value_translation redirecting_reason_types []
 Translation table for redirecting reason settings.
 
float sasdi
 
float sasdr
 

Detailed Description

CallerID Generation support.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file callerid.c.

Macro Definition Documentation

#define CALLERID_MARK   1200.0

1200 hz for "1"

Definition at line 71 of file callerid.c.

Referenced by callerid_init().

#define CALLERID_SPACE   2200.0

2200 hz for "0"

Definition at line 70 of file callerid.c.

Referenced by callerid_init().

Function Documentation

int ast_callerid_callwaiting_full_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
const char *  ddn,
int  redirecting,
int  pres,
int  qualifier,
struct ast_format codec 
)

Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)

See also
ast_callerid_generate() for other details

Definition at line 1253 of file callerid.c.

References CID_TYPE_MDMF.

1255 {
1256  /* Type II Caller ID (CWCID) only uses MDMF, so format isn't an argument */
1257  return __ast_callerid_generate(buf, name, number, ddn, redirecting, pres, qualifier, CID_TYPE_MDMF, 1, codec, NULL);
1258 }
#define CID_TYPE_MDMF
Definition: callerid.h:75
Number structure.
Definition: app_followme.c:154
int ast_callerid_callwaiting_full_tz_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
const char *  ddn,
int  redirecting,
int  pres,
int  qualifier,
struct ast_format codec,
const char *  tz 
)

Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)

Parameters
tzTZ-format time zone for date/time (NULL for system default)
See also
ast_callerid_generate() for other details

Definition at line 1266 of file callerid.c.

References CID_TYPE_MDMF.

1268 {
1269  /* Type II Caller ID (CWCID) only uses MDMF, so format isn't an argument */
1270  return __ast_callerid_generate(buf, name, number, ddn, redirecting, pres, qualifier, CID_TYPE_MDMF, 1, codec, tz);
1271 }
#define CID_TYPE_MDMF
Definition: callerid.h:75
Number structure.
Definition: app_followme.c:154
int ast_callerid_callwaiting_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
struct ast_format codec 
)

Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)

See also
ast_callerid_generate() for other details

Definition at line 1242 of file callerid.c.

References CID_TYPE_MDMF.

1243 {
1244  return __ast_callerid_generate(buf, name, number, "", -1, 0, 0, CID_TYPE_MDMF, 1, codec, NULL);
1245 }
#define CID_TYPE_MDMF
Definition: callerid.h:75
Number structure.
Definition: app_followme.c:154
int ast_callerid_full_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
const char *  ddn,
int  redirecting,
int  pres,
int  qualifier,
int  format,
struct ast_format codec 
)

Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)

Parameters
bufbuffer for output samples. See callerid_generate() for details regarding buffer.
nameCaller-ID Name
numberCaller-ID Number
ddnDialable Directory Number (or NULL)
redirectingRedirecting Reason (-1 if N/A)
presPresentation (0 for default)
qualifierCall Qualifier (0 for no, 1 for yes)
formatMessage Format
codecAsterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)

Like ast_callerid_generate but with additional parameters.

Definition at line 1247 of file callerid.c.

1249 {
1250  return __ast_callerid_generate(buf, name, number, ddn, redirecting, pres, qualifier, format, 0, codec, NULL);
1251 }
Number structure.
Definition: app_followme.c:154
int ast_callerid_full_tz_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
const char *  ddn,
int  redirecting,
int  pres,
int  qualifier,
int  format,
struct ast_format codec,
const char *  tz 
)

Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)

Parameters
bufbuffer for output samples. See callerid_generate() for details regarding buffer.
nameCaller-ID Name
numberCaller-ID Number
ddnDialable Directory Number (or NULL)
redirectingRedirecting Reason (-1 if N/A)
presPresentation (0 for default)
qualifierCall Qualifier (0 for no, 1 for yes)
formatMessage Format
codecAsterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)
tzTZ-format time zone name to use for date/time (NULL for system default)

Like ast_callerid_generate but with additional parameters.

Definition at line 1260 of file callerid.c.

1262 {
1263  return __ast_callerid_generate(buf, name, number, ddn, redirecting, pres, qualifier, format, 0, codec, tz);
1264 }
Number structure.
Definition: app_followme.c:154
int ast_callerid_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
struct ast_format codec 
)

Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)

Parameters
bufbuffer for output samples. See callerid_generate() for details regarding buffer.
nameCaller-ID Name
numberCaller-ID Number
codecAsterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)

Acts like callerid_generate except uses an asterisk format callerid string.

Definition at line 1237 of file callerid.c.

References CID_TYPE_MDMF.

1238 {
1239  return __ast_callerid_generate(buf, name, number, "", -1, 0, 0, CID_TYPE_MDMF, 0, codec, NULL);
1240 }
#define CID_TYPE_MDMF
Definition: callerid.h:75
Number structure.
Definition: app_followme.c:154
int ast_callerid_parse ( char *  instr,
char **  name,
char **  location 
)

Destructively parse inbuf into name and location (or number)

Parses callerid stream from inbuf and changes into useable form, outputted in name and location.

Parameters
instrbuffer of callerid stream (in audio form) to be parsed. Warning, data in buffer is changed.
nameaddress of a pointer-to-char for the name value of the stream.
locationaddress of a pointer-to-char for the phone number value of the stream.
Note
XXX 'name' is not parsed consistently e.g. we have input location name " foo bar " <123> 123 ' foo bar ' (with spaces around) " foo bar " NULL 'foo bar' (without spaces around) The parsing of leading and trailing space/quotes should be more consistent.
Return values
0on success
-1on failure

Definition at line 1162 of file callerid.c.

References ast_copy_string(), ast_isphonenumber(), ast_shrink_phone_number(), ast_strip(), ast_strip_quoted(), and ast_unescape_quoted().

Referenced by advanced_options(), dial_exec_full(), and unistim_new().

1163 {
1164  char *ls;
1165  char *le;
1166  char *name_start;
1167  char *instr;
1168  int quotes_stripped = 0;
1169 
1170  /* Handle surrounding quotes */
1171  input_str = ast_strip(input_str);
1172  instr = ast_strip_quoted(input_str, "\"", "\"");
1173  if (instr != input_str) {
1174  quotes_stripped = 1;
1175  }
1176 
1177  /* Try "name" <location> format or name <location> format or with a missing > */
1178  if ((ls = strrchr(instr, '<'))) {
1179  if ((le = strrchr(ls, '>'))) {
1180  *le = '\0'; /* location found, trim off the brackets */
1181  }
1182  *ls = '\0';
1183  *location = ls + 1; /* and this is the result */
1184 
1185  name_start = ast_strip_quoted(instr, "\"", "\"");
1186  } else { /* no valid brackets */
1187  char tmp[256];
1188 
1189  ast_copy_string(tmp, instr, sizeof(tmp));
1191  if (!quotes_stripped && ast_isphonenumber(tmp)) { /* Assume it's just a location */
1192  name_start = NULL;
1193  strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
1194  *location = instr;
1195  } else { /* Assume it's just a name. */
1196  *location = NULL;
1197  name_start = ast_strip_quoted(instr, "\"", "\"");
1198  }
1199  }
1200 
1201  if (name_start) {
1202  ast_unescape_quoted(name_start);
1203  }
1204  *name = name_start;
1205  return 0;
1206 }
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1818
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
Definition: utils.c:842
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
void ast_shrink_phone_number(char *n)
Clean up phone string.
Definition: callerid.c:1101
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_isphonenumber(const char *n)
Check if a string consists only of digits and + #.
Definition: callerid.c:1152
int ast_callerid_vmwi_generate ( unsigned char *  buf,
int  active,
int  type,
struct ast_format codec,
const char *  name,
const char *  number,
int  flags 
)

Generate message waiting indicator.

Parameters
buf
activeThe message indicator state – either 0 no messages in mailbox or 1 messages in mailbox
typeFormat of message (any of CID_MWI_TYPE_*)
codec
name
number
flags
See also
callerid_generate() for more info as it uses the same encoding
Version
1.6.1 changed mdmf parameter to type, added name, number and flags for caller id message generation

Definition at line 952 of file callerid.c.

References CID_MWI_TYPE_MDMF, CID_MWI_TYPE_MDMF_FULL, and CID_TYPE_MDMF.

953 {
954  char msg[256];
955  int len = 0;
956  int sum;
957  int x;
958  int bytes = 0;
959  float cr = 1.0;
960  float ci = 0.0;
961  float scont = 0.0;
962 
963  if (type == CID_MWI_TYPE_MDMF_FULL) {
964  /* MDMF Message waiting with date, number, name and MWI parameter */
965  msg[0] = 0x82;
966 
967  /* put date, number info at the right place */
968  len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags, CID_TYPE_MDMF, "", -1, NULL);
969 
970  /* length of MDMF CLI plus Message Waiting Structure */
971  msg[1] = len+3;
972 
973  /* Go to the position to write to */
974  len = len+2;
975 
976  /* "Message Waiting Parameter" */
977  msg[len++] = 0x0b;
978  /* Length of IE is one */
979  msg[len++] = 1;
980  /* Active or not */
981  if (active)
982  msg[len++] = 0xff;
983  else
984  msg[len++] = 0x00;
985 
986  } else if (type == CID_MWI_TYPE_MDMF) {
987  /* MDMF Message waiting only */
988  /* same as above except that the we only put MWI parameter */
989  msg[len++] = 0x82;
990  /* Length is 3 */
991  msg[len++] = 3;
992  /* IE is "Message Waiting Parameter" */
993  msg[len++] = 0x0b;
994  /* Length of IE is one */
995  msg[len++] = 1;
996  /* Active or not */
997  if (active)
998  msg[len++] = 0xff;
999  else
1000  msg[len++] = 0x00;
1001  } else {
1002  /* SDMF Message waiting */
1003  msg[len++] = 0x6;
1004  /* Length is 3 */
1005  msg[len++] = 3;
1006  if (active) {
1007  msg[len++] = 0x42;
1008  msg[len++] = 0x42;
1009  msg[len++] = 0x42;
1010  } else {
1011  msg[len++] = 0x6f;
1012  msg[len++] = 0x6f;
1013  msg[len++] = 0x6f;
1014  }
1015  }
1016  sum = 0;
1017  for (x = 0; x < len; x++)
1018  sum += msg[x];
1019  sum = (256 - (sum & 255));
1020  msg[len++] = sum;
1021  /* Wait a half a second */
1022  for (x = 0; x < 4000; x++)
1023  PUT_BYTE(0x7f);
1024  /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
1025  for (x = 0; x < 30; x++)
1026  PUT_CLID(0x55);
1027  /* Send 170ms of callerid marks */
1028  for (x = 0; x < 170; x++)
1029  PUT_CLID_MARKMS;
1030  for (x = 0; x < len; x++) {
1031  PUT_CLID(msg[x]);
1032  }
1033  /* Send 50 more ms of marks */
1034  for (x = 0; x < 50; x++)
1035  PUT_CLID_MARKMS;
1036  return bytes;
1037 }
#define CID_TYPE_MDMF
Definition: callerid.h:75
#define CID_MWI_TYPE_MDMF_FULL
Definition: callerid.h:83
Number structure.
Definition: app_followme.c:154
#define CID_MWI_TYPE_MDMF
Definition: callerid.h:81
const char* ast_connected_line_source_describe ( int  data)

Convert connected line update source value to explanatory string.

Since
1.8
Parameters
dataAST_CONNECTED_LINE_UPDATE_SOURCE from callerid.h
Returns
string for human presentation

Definition at line 1492 of file callerid.c.

1493 {
1494  int index;
1495 
1496  for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1497  if (connected_line_source_types[index].value == data) {
1498  return connected_line_source_types[index].description;
1499  }
1500  }
1501 
1502  return "not-known";
1503 }
static const struct ast_value_translation connected_line_source_types[]
Translation table for connected line update source settings.
Definition: callerid.c:1468
const char* ast_connected_line_source_name ( int  data)

Convert connected line update source value to text code.

Since
1.8
Parameters
dataAST_CONNECTED_LINE_UPDATE_SOURCE from callerid.h
Returns
string for config file

Definition at line 1505 of file callerid.c.

1506 {
1507  int index;
1508 
1509  for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1510  if (connected_line_source_types[index].value == data) {
1511  return connected_line_source_types[index].name;
1512  }
1513  }
1514 
1515  return "not-known";
1516 }
static const struct ast_value_translation connected_line_source_types[]
Translation table for connected line update source settings.
Definition: callerid.c:1468
int ast_connected_line_source_parse ( const char *  data)

Convert connected line update source text code to value (used in config file parsing)

Since
1.8
Parameters
datatext string from config file
Return values
AST_CONNECTED_LINE_UPDATE_SOURCEfrom callerid.h
-1if not in table

Definition at line 1479 of file callerid.c.

1480 {
1481  int index;
1482 
1483  for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1484  if (!strcasecmp(connected_line_source_types[index].name, data)) {
1485  return connected_line_source_types[index].value;
1486  }
1487  }
1488 
1489  return -1;
1490 }
static const struct ast_value_translation connected_line_source_types[]
Translation table for connected line update source settings.
Definition: callerid.c:1468
const char* ast_describe_caller_presentation ( int  data)

Convert caller ID pres value to explanatory string.

Parameters
dataAST_PRES_ value from callerid.h
Returns
string for human presentation

Definition at line 1364 of file callerid.c.

Referenced by ast_json_party_id().

1365 {
1366  int index;
1367 
1368  for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1369  if (pres_types[index].value == data) {
1370  return pres_types[index].description;
1371  }
1372  }
1373 
1374  return "unknown";
1375 }
static const struct ast_value_translation pres_types[]
Translation table for Caller ID Presentation settings.
Definition: callerid.c:1318
int ast_gen_cas ( unsigned char *  outbuf,
int  sas,
int  len,
struct ast_format codec 
)

Generate a CAS (CPE Alert Signal) tone for 'n' samples.

Parameters
outbufAllocated buffer for data. Must be at least 2400 bytes unless no SAS is desired
sasNon-zero if CAS should be preceeded by SAS
lenHow many samples to generate.
codecWhich codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
Return values
-1on error (if len is less than 2400)
0on success

Definition at line 271 of file callerid.c.

272 {
273  int pos = 0;
274  int saslen = 2400;
275  float cr1 = 1.0;
276  float ci1 = 0.0;
277  float cr2 = 1.0;
278  float ci2 = 0.0;
279 
280  if (sendsas) {
281  if (len < saslen)
282  return -1;
283  gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
284  len -= saslen;
285  pos += saslen;
286  cr2 = cr1;
287  ci2 = ci1;
288  }
289  gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
290  return 0;
291 }
int ast_is_shrinkable_phonenumber ( const char *  exten)

Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_phone_number)

Parameters
extenThe extension (or URI) to be checked.
Return values
1if exten is valid AST shrinkable phone number
0if not

Definition at line 1157 of file callerid.c.

References ast_is_valid_string().

1158 {
1159  return ast_is_valid_string(exten, "0123456789*#+()-.");
1160 }
static int ast_is_valid_string(const char *exten, const char *valid)
Checks if phone number consists of valid characters.
Definition: callerid.c:1140
static int ast_is_valid_string ( const char *  exten,
const char *  valid 
)
static

Checks if phone number consists of valid characters.

Parameters
extenString that needs to be checked
validValid characters in string
Return values
1if valid string
0if string contains invalid characters

Definition at line 1140 of file callerid.c.

Referenced by ast_is_shrinkable_phonenumber(), and ast_isphonenumber().

1141 {
1142  int x;
1143 
1144  if (ast_strlen_zero(exten))
1145  return 0;
1146  for (x = 0; exten[x]; x++)
1147  if (!strchr(valid, exten[x]))
1148  return 0;
1149  return 1;
1150 }
int ast_isphonenumber ( const char *  n)

Check if a string consists only of digits and + #.

Parameters
nnumber to be checked.
Return values
0if n is a number
1if not

Definition at line 1152 of file callerid.c.

References ast_is_valid_string().

Referenced by ast_callerid_parse(), and hfp_parse_clip().

1153 {
1154  return ast_is_valid_string(n, "0123456789*#+");
1155 }
static int ast_is_valid_string(const char *exten, const char *valid)
Checks if phone number consists of valid characters.
Definition: callerid.c:1140
const char* ast_named_caller_presentation ( int  data)

Convert caller ID pres value to text code.

Parameters
dataAST_PRES_ value from callerid.h
Returns
string for config file

Definition at line 1382 of file callerid.c.

1383 {
1384  int index;
1385 
1386  for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1387  if (pres_types[index].value == data) {
1388  return pres_types[index].name;
1389  }
1390  }
1391 
1392  return "unknown";
1393 }
static const struct ast_value_translation pres_types[]
Translation table for Caller ID Presentation settings.
Definition: callerid.c:1318
int ast_parse_caller_presentation ( const char *  data)

Convert caller ID text code to value (used in config file parsing)

Parameters
datatext string from config file
Return values
valueAST_PRES_ from callerid.h
-1if not in table

Definition at line 1343 of file callerid.c.

Referenced by dial_exec_full().

1344 {
1345  int index;
1346  if (!data) {
1347  return -1;
1348  }
1349 
1350  for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1351  if (!strcasecmp(pres_types[index].name, data)) {
1352  return pres_types[index].value;
1353  }
1354  }
1355 
1356  return -1;
1357 }
static const struct ast_value_translation pres_types[]
Translation table for Caller ID Presentation settings.
Definition: callerid.c:1318
const char* ast_party_name_charset_describe ( int  data)

Convert ast_party_name.char_set value to explanatory string.

Since
1.8
Parameters
dataAST_PARTY_CHAR_SET from channel.h
Returns
string for human presentation

Definition at line 1547 of file callerid.c.

1548 {
1549  int index;
1550 
1551  for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1552  if (party_name_charset_tbl[index].value == data) {
1553  return party_name_charset_tbl[index].description;
1554  }
1555  }
1556 
1557  return "not-known";
1558 }
static const struct ast_value_translation party_name_charset_tbl[]
Translation table for ast_party_name char-set settings.
Definition: callerid.c:1519
int ast_party_name_charset_parse ( const char *  data)

Convert ast_party_name.char_set text code to value (used in config file parsing)

Since
1.8
Parameters
datatext string from config file
Return values
AST_PARTY_CHAR_SETfrom channel.h
-1if not in table

Definition at line 1534 of file callerid.c.

1535 {
1536  int index;
1537 
1538  for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1539  if (!strcasecmp(party_name_charset_tbl[index].name, data)) {
1540  return party_name_charset_tbl[index].value;
1541  }
1542  }
1543 
1544  return -1;
1545 }
static const struct ast_value_translation party_name_charset_tbl[]
Translation table for ast_party_name char-set settings.
Definition: callerid.c:1519
const char* ast_party_name_charset_str ( int  data)

Convert ast_party_name.char_set value to text code.

Since
1.8
Parameters
dataAST_PARTY_CHAR_SET from channel.h
Returns
string for config file

Definition at line 1560 of file callerid.c.

1561 {
1562  int index;
1563 
1564  for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1565  if (party_name_charset_tbl[index].value == data) {
1566  return party_name_charset_tbl[index].name;
1567  }
1568  }
1569 
1570  return "not-known";
1571 }
static const struct ast_value_translation party_name_charset_tbl[]
Translation table for ast_party_name char-set settings.
Definition: callerid.c:1519
const char* ast_redirecting_reason_describe ( int  data)

Convert redirecting reason value to explanatory string.

Since
1.8
Parameters
dataQ931_REDIRECTING_REASON from callerid.h
Returns
string for human presentation

Definition at line 1436 of file callerid.c.

1437 {
1438  int index;
1439 
1440  for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1441  if (redirecting_reason_types[index].value == data) {
1442  return redirecting_reason_types[index].description ?: "Redirecting reason alias-bug";
1443  }
1444  }
1445 
1446  return "not-known";
1447 }
static const struct ast_value_translation redirecting_reason_types[]
Translation table for redirecting reason settings.
Definition: callerid.c:1396
const char* ast_redirecting_reason_name ( const struct ast_party_redirecting_reason data)

Convert redirecting reason value to text code.

Since
1.8
Parameters
dataast_party_redirecting_reason structure from channel.h
Returns
string for config file

Definition at line 1449 of file callerid.c.

References ast_party_redirecting_reason::code, and ast_party_redirecting_reason::str.

1450 {
1451  int index;
1452 
1453  if (!ast_strlen_zero(data->str)) {
1454  /* Use this string if it has been set. Otherwise, use the table. */
1455  return data->str;
1456  }
1457 
1458  for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1459  if (redirecting_reason_types[index].value == data->code) {
1460  return redirecting_reason_types[index].name;
1461  }
1462  }
1463 
1464  return "not-known";
1465 }
int code
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:510
char * str
a string value for the redirecting reason
Definition: channel.h:507
static const struct ast_value_translation redirecting_reason_types[]
Translation table for redirecting reason settings.
Definition: callerid.c:1396
int ast_redirecting_reason_parse ( const char *  data)

Convert redirecting reason text code to value (used in config file parsing)

Since
1.8
Parameters
datatext string from config file
Return values
Q931_REDIRECTING_REASONfrom callerid.h
-1if not in table

Definition at line 1423 of file callerid.c.

1424 {
1425  int index;
1426 
1427  for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1428  if (!strcasecmp(redirecting_reason_types[index].name, data)) {
1429  return redirecting_reason_types[index].value;
1430  }
1431  }
1432 
1433  return -1;
1434 }
static const struct ast_value_translation redirecting_reason_types[]
Translation table for redirecting reason settings.
Definition: callerid.c:1396
void ast_shrink_phone_number ( char *  n)

Clean up phone string.

Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...

Remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets. Basically, remove anything that could be invalid in a pattern.

Definition at line 1101 of file callerid.c.

Referenced by ast_callerid_parse(), setup_privacy_args(), and write_metadata().

1102 {
1103  int x, y = 0;
1104  int bracketed = 0;
1105 
1106  for (x = 0; n[x]; x++) {
1107  switch (n[x]) {
1108  case '[':
1109  bracketed++;
1110  n[y++] = n[x];
1111  break;
1112  case ']':
1113  bracketed--;
1114  n[y++] = n[x];
1115  break;
1116  case '-':
1117  if (bracketed)
1118  n[y++] = n[x];
1119  break;
1120  case '.':
1121  if (!n[x+1])
1122  n[y++] = n[x];
1123  break;
1124  default:
1125  /* ignore parenthesis and whitespace */
1126  if (!strchr("( )", n[x]))
1127  n[y++] = n[x];
1128  }
1129  }
1130  n[y] = '\0';
1131 }
int callerid_feed ( struct callerid_state cid,
unsigned char *  ubuf,
int  samples,
struct ast_format codec 
)

Read samples into the state machine.

Parameters
cidWhich state machine to act upon
ubufcontaining your samples
samplesnumber of samples contained within the buffer.
codecwhich codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)

Send received audio to the Caller*ID demodulator.

Return values
-1on error
0for "needs more samples"
1if the CallerID spill reception is complete.

Definition at line 570 of file callerid.c.

References ast_alloca, ast_copy_string(), ast_debug, and fsk_serial().

571 {
572  int mylen = len;
573  int olen;
574  int b = 'X';
575  int res;
576  int x;
577  short *buf;
578 
579  buf = ast_alloca(2 * len + cid->oldlen);
580 
581  memcpy(buf, cid->oldstuff, cid->oldlen);
582  mylen += cid->oldlen/2;
583 
584  for (x = 0; x < len; x++)
585  buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
586  while (mylen >= 160) {
587  olen = mylen;
588  res = fsk_serial(&cid->fskd, buf, &mylen, &b);
589  if (mylen < 0) {
590  ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
591  return -1;
592  }
593  buf += (olen - mylen);
594  if (res < 0) {
595  ast_log(LOG_NOTICE, "fsk_serial failed\n");
596  return -1;
597  }
598  if (res == 1) {
599  if (b > 0xff) {
600  if (cid->sawflag != 5) {
601  /* Ignore invalid bytes */
602  continue;
603  }
604  /*
605  * We can tolerate an error on the checksum character since the
606  * checksum character is the last character in the message and
607  * it validates the message.
608  *
609  * Remove character error flags.
610  * Bit 8 : Parity error
611  * Bit 9 : Framing error
612  */
613  b &= 0xff;
614  }
615  switch (cid->sawflag) {
616  case 0: /* Look for flag */
617  if (b == 'U')
618  cid->sawflag = 2;
619  break;
620  case 2: /* Get lead-in */
621  if ((b == 0x04) || (b == 0x80) || (b == 0x06) || (b == 0x82)) {
622  cid->type = b;
623  cid->sawflag = 3;
624  cid->cksum = b;
625  }
626  break;
627  case 3: /* Get length */
628  /* Not a lead in. We're ready */
629  cid->sawflag = 4;
630  cid->len = b;
631  cid->pos = 0;
632  cid->cksum += b;
633  break;
634  case 4: /* Retrieve message */
635  if (cid->pos >= 128) {
636  ast_log(LOG_WARNING, "Caller ID too long???\n");
637  return -1;
638  }
639  cid->rawdata[cid->pos++] = b;
640  cid->len--;
641  cid->cksum += b;
642  if (!cid->len) {
643  cid->rawdata[cid->pos] = '\0';
644  cid->sawflag = 5;
645  }
646  break;
647  case 5: /* Check checksum */
648  if ((b + cid->cksum) & 0xff) {
649  ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
650  /* Try again */
651  cid->sawflag = 0;
652  break;
653  }
654 
655  cid->number[0] = '\0';
656  cid->name[0] = '\0';
657  /* Update flags */
658  cid->flags = 0;
659  cid->redirecting = 0;
660  /* If we get this far we're fine. */
661  if ((cid->type == 0x80) || (cid->type == 0x82)) {
662  /* MDMF */
663  ast_debug(6, "%s Caller*ID spill received\n", cid->type == 0x80 ? "MDMF" : "MDMF Message Waiting");
664  /* Go through each element and process */
665  for (x = 0; x < cid->pos;) {
666  int param = cid->rawdata[x++];
667  ast_debug(7, "Caller*ID parameter %d (%s), length %d\n", param, mdmf_param_name(param), cid->rawdata[x]);
668  switch (param) {
669  case 1:
670  /* Date/Time... in theory we could synchronize our time according to the Caller*ID,
671  * but it would be silly for a telephone switch to do that. */
672  break;
673  /* For MDMF spills, we would expect to get an "O" or a "P"
674  * for paramter 4 (or 8) as opposed to 2 (or 7) to indicate
675  * a blocked or out of area presentation.
676  * However, for SDMF, which doesn't have parameters,
677  * there is no differentiation, which is why the logic below
678  * just checks the number and name field and here, we use the same
679  * parsing logic for both parameters. Technically, it would be wrong
680  * to receive an 'O' or 'P' for parameters 2 or 7 and treat it as
681  * the reason for absence fields, but that is not likely to happen,
682  * and if it did, could possibly be buggy Caller ID generation we would
683  * want to treat the same way, anyways.
684  *
685  * The "Dialable Directory Number" is how the number would be called back.
686  * Asterisk doesn't really have a corresponding thing for this,
687  * so log it if we get it for debugging, but treat the same otherwise.
688  */
689  case 3: /* Dialable Directory Number / Number (for Zebble) */
690  ast_debug(3, "Caller*ID Dialable Directory Number: '%.*s'\n", cid->rawdata[x], cid->rawdata + x + 1);
691  /* Fall through */
692  case 2: /* Number */
693  case 4: /* Reason for Absence of Number. */
694  res = cid->rawdata[x];
695  if (res > 32) {
696  ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
697  res = 32;
698  }
699  if (ast_strlen_zero(cid->number)) {
700  memcpy(cid->number, cid->rawdata + x + 1, res);
701  /* Null terminate */
702  cid->number[res] = '\0';
703  }
704  break;
705  case 5: /* Reason for Redirection */
706  res = cid->rawdata[x];
707  if (res != 1) {
708  ast_log(LOG_WARNING, "Redirecting parameter length is %d?\n", res);
709  break;
710  }
711  switch (*(cid->rawdata + x + 1)) {
712  case 0x1:
713  cid->redirecting = AST_REDIRECTING_REASON_USER_BUSY;
714  break;
715  case 0x2:
716  cid->redirecting = AST_REDIRECTING_REASON_NO_ANSWER;
717  break;
718  case 0x3:
719  cid->redirecting = AST_REDIRECTING_REASON_UNCONDITIONAL;
720  break;
721  case 0x4:
722  cid->redirecting = AST_REDIRECTING_REASON_CALL_FWD_DTE;
723  break;
724  case 0x5:
725  cid->redirecting = AST_REDIRECTING_REASON_DEFLECTION;
726  break;
727  default:
728  ast_log(LOG_WARNING, "Redirecting reason is %02x?\n", *(cid->rawdata + x + 1));
729  break;
730  }
731  break;
732  case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
733  res = cid->rawdata[x];
734  if (res == 1 && *(cid->rawdata + x + 1) == 'L') {
735  cid->flags |= CID_QUALIFIER;
736  } else if (res >= 1) {
737  ast_debug(2, "Invalid value (len %d) received for Call Qualifier: '%c'\n", res, *(cid->rawdata + x + 1));
738  }
739  break;
740  case 7: /* Name */
741  case 8: /* Reason for Absence of Name */
742  res = cid->rawdata[x];
743  if (res > 32) {
744  ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
745  res = 32;
746  }
747  memcpy(cid->name, cid->rawdata + x + 1, res);
748  cid->name[res] = '\0';
749  break;
750  case 11: /* Message Waiting */
751  res = cid->rawdata[x + 1];
752  if (res)
753  cid->flags |= CID_MSGWAITING;
754  else
755  cid->flags |= CID_NOMSGWAITING;
756  break;
757  case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */
758  case 19: /* UK: Network message system status (Number of messages waiting) */
759  case 22: /* Something French */
760  break;
761  default:
762  ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]);
763  }
764  res = cid->rawdata[x];
765  if (0 > res){ /* Negative offset in the CID Spill */
766  ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
767  /* Try again */
768  cid->sawflag = 0;
769  break; /* Exit the loop */
770  }
771  x += cid->rawdata[x];
772  x++;
773  }
774  } else if (cid->type == 0x6) {
775  /* VMWI SDMF */
776  ast_debug(6, "VMWI SDMF Caller*ID spill received\n");
777  if (cid->rawdata[2] == 0x42) {
778  cid->flags |= CID_MSGWAITING;
779  } else if (cid->rawdata[2] == 0x6f) {
780  cid->flags |= CID_NOMSGWAITING;
781  }
782  } else {
783  /* SDMF */
784  ast_debug(6, "SDMF Caller*ID spill received\n");
785  ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
786  }
787  if (!strcmp(cid->number, "P")) {
788  ast_debug(6, "Caller*ID number is private\n");
789  strcpy(cid->number, "");
790  cid->flags |= CID_PRIVATE_NUMBER;
791  } else if (!strcmp(cid->number, "O")) {
792  ast_debug(6, "Caller*ID number is out of area\n");
793  strcpy(cid->number, "");
794  cid->flags |= CID_UNKNOWN_NUMBER;
795  } else if (ast_strlen_zero(cid->number)) {
796  ast_debug(6, "No Caller*ID number provided, and no reason provided for its absence\n");
797  strcpy(cid->number, "");
798  cid->flags |= CID_UNKNOWN_NUMBER;
799  } else {
800  ast_debug(6, "Caller*ID number is '%s'\n", cid->number);
801  }
802  if (!strcmp(cid->name, "P")) {
803  ast_debug(6, "Caller*ID name is private\n");
804  strcpy(cid->name, "");
805  cid->flags |= CID_PRIVATE_NAME;
806  } else if (!strcmp(cid->name, "O")) {
807  ast_debug(6, "Caller*ID name is out of area\n");
808  strcpy(cid->name, "");
809  cid->flags |= CID_UNKNOWN_NAME;
810  } else if (ast_strlen_zero(cid->name)) {
811  ast_debug(6, "No Caller*ID name provided, and no reason provided for its absence\n");
812  strcpy(cid->name, "");
813  cid->flags |= CID_UNKNOWN_NAME;
814  } else {
815  ast_debug(6, "Caller*ID name is '%s'\n", cid->name);
816  }
817  return 1;
818  break;
819  default:
820  ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
821  }
822  }
823  }
824  if (mylen) {
825  memcpy(cid->oldstuff, buf, mylen * 2);
826  cid->oldlen = mylen * 2;
827  } else
828  cid->oldlen = 0;
829 
830  return 0;
831 }
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte)
Retrieve a serial byte into outbyte. Buffer is a pointer into a series of shorts and len records the ...
int callerid_feed_jp ( struct callerid_state cid,
unsigned char *  ubuf,
int  samples,
struct ast_format codec 
)

Read samples into the state machine.

Parameters
cidWhich state machine to act upon
ubufcontaining your samples
samplesnumber of samples contained within the buffer.
codecwhich codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)

Send received audio to the Caller*ID demodulator (for japanese style lines).

Return values
-1on error
0for "needs more samples"
1if the CallerID spill reception is complete.

Definition at line 316 of file callerid.c.

References ast_alloca, ast_copy_string(), ast_debug, and fsk_serial().

317 {
318  int mylen = len;
319  int olen;
320  int b = 'X';
321  int b2;
322  int res;
323  int x;
324  short *buf;
325 
326  buf = ast_alloca(2 * len + cid->oldlen);
327 
328  memcpy(buf, cid->oldstuff, cid->oldlen);
329  mylen += cid->oldlen / 2;
330 
331  for (x = 0; x < len; x++)
332  buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
333 
334  while (mylen >= 160) {
335  b = b2 = 0;
336  olen = mylen;
337  res = fsk_serial(&cid->fskd, buf, &mylen, &b);
338 
339  if (mylen < 0) {
340  ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
341  return -1;
342  }
343 
344  buf += (olen - mylen);
345 
346  if (res < 0) {
347  ast_log(LOG_NOTICE, "fsk_serial failed\n");
348  return -1;
349  }
350 
351  if (res == 1) {
352  b2 = b;
353  b &= 0x7f;
354 
355  /* crc checksum calculation */
356  if (cid->sawflag > 1)
357  cid->crc = calc_crc(cid->crc, (unsigned char) b2);
358 
359  /* Ignore invalid bytes */
360  if (b > 0xff)
361  continue;
362 
363  /* skip DLE if needed */
364  if (cid->sawflag > 0) {
365  if (cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10) {
366  cid->skipflag = 1 ;
367  continue ;
368  }
369  }
370  if (cid->skipflag == 1)
371  cid->skipflag = 0 ;
372 
373  /* caller id retrieval */
374  switch (cid->sawflag) {
375  case 0: /* DLE */
376  if (b == 0x10) {
377  cid->sawflag = 1;
378  cid->skipflag = 0;
379  cid->crc = 0;
380  }
381  break;
382  case 1: /* SOH */
383  if (b == 0x01)
384  cid->sawflag = 2;
385  break ;
386  case 2: /* HEADER */
387  if (b == 0x07)
388  cid->sawflag = 3;
389  break;
390  case 3: /* STX */
391  if (b == 0x02)
392  cid->sawflag = 4;
393  break;
394  case 4: /* SERVICE TYPE */
395  if (b == 0x40)
396  cid->sawflag = 5;
397  break;
398  case 5: /* Frame Length */
399  cid->sawflag = 6;
400  break;
401  case 6: /* NUMBER TYPE */
402  cid->sawflag = 7;
403  cid->pos = 0;
404  cid->rawdata[cid->pos++] = b;
405  break;
406  case 7: /* NUMBER LENGTH */
407  cid->sawflag = 8;
408  cid->len = b;
409  if ((cid->len+2) >= sizeof(cid->rawdata)) {
410  ast_log(LOG_WARNING, "too long caller id string\n") ;
411  return -1;
412  }
413  cid->rawdata[cid->pos++] = b;
414  break;
415  case 8: /* Retrieve message */
416  cid->rawdata[cid->pos++] = b;
417  cid->len--;
418  if (cid->len<=0) {
419  cid->rawdata[cid->pos] = '\0';
420  cid->sawflag = 9;
421  }
422  break;
423  case 9: /* ETX */
424  cid->sawflag = 10;
425  break;
426  case 10: /* CRC Checksum 1 */
427  cid->sawflag = 11;
428  break;
429  case 11: /* CRC Checksum 2 */
430  cid->sawflag = 12;
431  if (cid->crc != 0) {
432  ast_log(LOG_WARNING, "crc checksum error\n") ;
433  return -1;
434  }
435  /* extract caller id data */
436  for (x = 0; x < cid->pos;) {
437  switch (cid->rawdata[x++]) {
438  case 0x02: /* caller id number */
439  cid->number[0] = '\0';
440  cid->name[0] = '\0';
441  cid->flags = 0;
442  res = cid->rawdata[x++];
443  ast_copy_string(cid->number, &cid->rawdata[x], res+1);
444  x += res;
445  break;
446  case 0x21: /* additional information */
447  /* length */
448  x++;
449  /* number type */
450  switch (cid->rawdata[x]) {
451  case 0x00: /* unknown */
452  case 0x01: /* international number */
453  case 0x02: /* domestic number */
454  case 0x03: /* network */
455  case 0x04: /* local call */
456  case 0x06: /* short dial number */
457  case 0x07: /* reserved */
458  default: /* reserved */
459  ast_debug(2, "cid info:#1=%X\n", (unsigned)cid->rawdata[x]);
460  break ;
461  }
462  x++;
463  /* numbering plan octed 4 */
464  x++;
465  /* numbering plan octed 5 */
466  switch (cid->rawdata[x]) {
467  case 0x00: /* unknown */
468  case 0x01: /* recommendation E.164 ISDN */
469  case 0x03: /* recommendation X.121 */
470  case 0x04: /* telex dial plan */
471  case 0x08: /* domestic dial plan */
472  case 0x09: /* private dial plan */
473  case 0x05: /* reserved */
474  default: /* reserved */
475  ast_debug(2, "cid info:#2=%X\n", (unsigned)cid->rawdata[x]);
476  break ;
477  }
478  x++;
479  break ;
480  case 0x04: /* no callerid reason */
481  /* length */
482  x++;
483  /* no callerid reason code */
484  switch (cid->rawdata[x]) {
485  case 'P': /* caller id denied by user */
486  case 'O': /* service not available */
487  case 'C': /* pay phone */
488  case 'S': /* service congested */
489  cid->flags |= CID_UNKNOWN_NUMBER;
490  ast_debug(2, "no cid reason:%c\n", cid->rawdata[x]);
491  break ;
492  }
493  x++;
494  break ;
495  case 0x09: /* dialed number */
496  /* length */
497  res = cid->rawdata[x++];
498  /* dialed number */
499  x += res;
500  break ;
501  case 0x22: /* dialed number additional information */
502  /* length */
503  x++;
504  /* number type */
505  switch (cid->rawdata[x]) {
506  case 0x00: /* unknown */
507  case 0x01: /* international number */
508  case 0x02: /* domestic number */
509  case 0x03: /* network */
510  case 0x04: /* local call */
511  case 0x06: /* short dial number */
512  case 0x07: /* reserved */
513  default: /* reserved */
514  if (DEBUG_ATLEAST(2))
515  ast_log(LOG_NOTICE, "did info:#1=%X\n", (unsigned)cid->rawdata[x]);
516  break ;
517  }
518  x++;
519  /* numbering plan octed 4 */
520  x++;
521  /* numbering plan octed 5 */
522  switch (cid->rawdata[x]) {
523  case 0x00: /* unknown */
524  case 0x01: /* recommendation E.164 ISDN */
525  case 0x03: /* recommendation X.121 */
526  case 0x04: /* telex dial plan */
527  case 0x08: /* domestic dial plan */
528  case 0x09: /* private dial plan */
529  case 0x05: /* reserved */
530  default: /* reserved */
531  ast_debug(2, "did info:#2=%X\n", (unsigned)cid->rawdata[x]);
532  break ;
533  }
534  x++;
535  break ;
536  }
537  }
538  return 1;
539  break;
540  default:
541  ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
542  }
543  }
544  }
545  if (mylen) {
546  memcpy(cid->oldstuff, buf, mylen * 2);
547  cid->oldlen = mylen * 2;
548  } else
549  cid->oldlen = 0;
550 
551  return 0;
552 }
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte)
Retrieve a serial byte into outbyte. Buffer is a pointer into a series of shorts and len records the ...
void callerid_free ( struct callerid_state cid)

This function frees callerid_state cid.

Parameters
cidThis is the callerid_state state machine to free

Definition at line 833 of file callerid.c.

834 {
835  ast_free(cid);
836 }
int callerid_full_generate ( unsigned char *  buf,
const char *  number,
const char *  name,
const char *  ddn,
int  redirecting,
int  flags,
int  format,
int  callwaiting,
struct ast_format codec 
)

Generates a CallerID FSK stream in ulaw format suitable for transmission.

Parameters
bufBuffer to use. If "buf" is supplied, it will use that buffer instead of allocating its own. "buf" must be at least 32000 bytes in size of you want to be sure you don't have an overrun.
numberUse NULL for no number or "P" for "private"
namename to be used
ddnDialable Directory Number (or NULL)
redirectingRedirecting reason
flagspassed flags
formatMessage format
callwaitingcallwaiting flag
codec– either AST_FORMAT_ULAW or AST_FORMAT_ALAW

This function creates a stream of callerid (a callerid spill) data in ulaw format.

Returns
It returns the size (in bytes) of the data (if it returns a size of 0, there is probably an error)

Definition at line 1044 of file callerid.c.

References callerid_full_tz_generate().

Referenced by callerid_generate().

1046 {
1047  /* Default time zone is NULL (system time zone) */
1048  return callerid_full_tz_generate(buf, number, name, ddn, redirecting, flags, format, callwaiting, codec, NULL);
1049 }
int callerid_full_tz_generate(unsigned char *buf, const char *number, const char *name, const char *ddn, int redirecting, int flags, int format, int callwaiting, struct ast_format *codec, const char *tz)
Generates a CallerID FSK stream in ulaw format suitable for transmission.
Definition: callerid.c:1051
Number structure.
Definition: app_followme.c:154
int callerid_full_tz_generate ( unsigned char *  buf,
const char *  number,
const char *  name,
const char *  ddn,
int  redirecting,
int  flags,
int  format,
int  callwaiting,
struct ast_format codec,
const char *  tz 
)

Generates a CallerID FSK stream in ulaw format suitable for transmission.

Parameters
bufBuffer to use. If "buf" is supplied, it will use that buffer instead of allocating its own. "buf" must be at least 32000 bytes in size of you want to be sure you don't have an overrun.
numberUse NULL for no number or "P" for "private"
namename to be used
ddnDialable Directory Number (or NULL)
redirectingRedirecting reason
flagspassed flags
formatMessage format
callwaitingcallwaiting flag
codec– either AST_FORMAT_ULAW or AST_FORMAT_ALAW
tzTZ-format time zone to use for date/time (NULL for system default)

This function creates a stream of callerid (a callerid spill) data in ulaw format.

Returns
It returns the size (in bytes) of the data (if it returns a size of 0, there is probably an error)

Definition at line 1051 of file callerid.c.

Referenced by callerid_full_generate().

1053 {
1054  int bytes = 0;
1055  int x, sum;
1056  int len;
1057 
1058  /* Initial carriers (real/imaginary) */
1059  float cr = 1.0;
1060  float ci = 0.0;
1061  float scont = 0.0;
1062  char msg[256];
1063  len = callerid_genmsg(msg, sizeof(msg), number, name, flags, format, ddn, redirecting, tz);
1064  if (!callwaiting) {
1065  /* Wait a half a second */
1066  for (x = 0; x < 4000; x++)
1067  PUT_BYTE(0x7f);
1068  /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
1069  for (x = 0; x < 30; x++)
1070  PUT_CLID(0x55);
1071  }
1072  /* Send 150ms of callerid marks */
1073  for (x = 0; x < 150; x++)
1074  PUT_CLID_MARKMS;
1075  /* Send 0x80 indicating MDMF format */
1076  PUT_CLID(0x80);
1077  /* Put length of whole message */
1078  PUT_CLID(len);
1079  sum = 0x80 + strlen(msg);
1080  /* Put each character of message and update checksum */
1081  for (x = 0; x < len; x++) {
1082  PUT_CLID(msg[x]);
1083  sum += msg[x];
1084  }
1085  /* Send 2's compliment of sum */
1086  PUT_CLID(256 - (sum & 255));
1087 
1088  /* Send 50 more ms of marks */
1089  for (x = 0; x < 50; x++)
1090  PUT_CLID_MARKMS;
1091 
1092  return bytes;
1093 }
Number structure.
Definition: app_followme.c:154
int callerid_generate ( unsigned char *  buf,
const char *  number,
const char *  name,
int  flags,
int  callwaiting,
struct ast_format codec 
)

Generates a CallerID FSK stream in ulaw format suitable for transmission.

Parameters
bufBuffer to use. If "buf" is supplied, it will use that buffer instead of allocating its own. "buf" must be at least 32000 bytes in size of you want to be sure you don't have an overrun.
numberUse NULL for no number or "P" for "private"
namename to be used
flagspassed flags
callwaitingcallwaiting flag
codec– either AST_FORMAT_ULAW or AST_FORMAT_ALAW

This function creates a stream of callerid (a callerid spill) data in ulaw format.

Returns
It returns the size (in bytes) of the data (if it returns a size of 0, there is probably an error)

Definition at line 1039 of file callerid.c.

References callerid_full_generate(), and CID_TYPE_MDMF.

1040 {
1041  return callerid_full_generate(buf, number, name, NULL, -1, flags, CID_TYPE_MDMF, callwaiting, codec);
1042 }
#define CID_TYPE_MDMF
Definition: callerid.h:75
int callerid_full_generate(unsigned char *buf, const char *number, const char *name, const char *ddn, int redirecting, int flags, int format, int callwaiting, struct ast_format *codec)
Generates a CallerID FSK stream in ulaw format suitable for transmission.
Definition: callerid.c:1044
Number structure.
Definition: app_followme.c:154
void callerid_get ( struct callerid_state cid,
char **  number,
char **  name,
int *  flags 
)

Extract info out of callerID state machine. Flags are listed above.

Parameters
cidCallerid state machine to act upon
numberPass the address of a pointer-to-char (will contain the phone number)
namePass the address of a pointer-to-char (will contain the name)
flagsPass the address of an int variable (will contain the various callerid flags - presentation flags and call qualifier)

This function extracts a callerid string out of a callerid_state state machine. If no number is found, *number will be set to NULL. Likewise for the name. Flags can contain any of the following: CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, CID_MSGWAITING, CID_NOMSGWAITING, CID_QUALIFIER

Definition at line 205 of file callerid.c.

References callerid_get_with_redirecting().

206 {
207  int redirecting;
208  return callerid_get_with_redirecting(cid, name, number, flags, &redirecting);
209 }
Number structure.
Definition: app_followme.c:154
void callerid_get_with_redirecting(struct callerid_state *cid, char **name, char **number, int *flags, int *redirecting)
Extract info out of callerID state machine. Flags are listed above.
Definition: callerid.c:189
void callerid_get_dtmf ( char *  cidstring,
char *  number,
int *  flags 
)

Get and parse DTMF-based callerid.

Parameters
cidstringThe actual transmitted string.
numberThe cid number is returned here.
flagsThe cid flags are returned here.

Definition at line 211 of file callerid.c.

References ast_debug.

212 {
213  int i;
214  int code;
215 
216  /* "Clear" the number-buffer. */
217  number[0] = 0;
218 
219  if (strlen(cidstring) < 2) {
220  ast_debug(1, "No cid detected\n");
221  *flags = CID_UNKNOWN_NUMBER;
222  return;
223  }
224 
225  /* Detect protocol and special types */
226  if (cidstring[0] == 'B') {
227  /* Handle special codes */
228  code = atoi(&cidstring[1]);
229  if (code == 0)
230  *flags = CID_UNKNOWN_NUMBER;
231  else if (code == 10)
232  *flags = CID_PRIVATE_NUMBER;
233  else
234  ast_debug(1, "Unknown DTMF code %d\n", code);
235  } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
236  /* .DK special code */
237  if (cidstring[1] == '1')
238  *flags = CID_PRIVATE_NUMBER;
239  if (cidstring[1] == '2' || cidstring[1] == '3')
240  *flags = CID_UNKNOWN_NUMBER;
241  } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
242  /* "Standard" callerid */
243  for (i = 1; i < strlen(cidstring); i++) {
244  if (cidstring[i] == 'C' || cidstring[i] == '#')
245  break;
246  if (isdigit(cidstring[i]))
247  number[i-1] = cidstring[i];
248  else
249  ast_debug(1, "Unknown CID digit '%c'\n",
250  cidstring[i]);
251  }
252  number[i-1] = 0;
253  } else if (isdigit(cidstring[0])) {
254  /* It begins with a digit, so we parse it as a number and hope
255  * for the best */
256  ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
257  "parsing might be unreliable\n");
258  for (i = 0; i < strlen(cidstring); i++) {
259  if (isdigit(cidstring[i]))
260  number[i] = cidstring[i];
261  else
262  break;
263  }
264  number[i] = 0;
265  } else {
266  ast_debug(1, "Unknown CID protocol, start digit '%c'\n", cidstring[0]);
267  *flags = CID_UNKNOWN_NUMBER;
268  }
269 }
Number structure.
Definition: app_followme.c:154
#define ast_debug(level,...)
Log a DEBUG message.
void callerid_get_with_redirecting ( struct callerid_state cid,
char **  name,
char **  number,
int *  flags,
int *  redirecting 
)

Extract info out of callerID state machine. Flags are listed above.

Parameters
cidCallerid state machine to act upon
[out]numberPass the address of a pointer-to-char (will contain the phone number)
[out]namePass the address of a pointer-to-char (will contain the name)
[out]flagsPass the address of an int variable (will contain the various callerid flags)
[out]redirectingPass the address of an int variable (will contain the redirecting reason, if received - presentation flags and call qualifier)

This function extracts a callerid string out of a callerid_state state machine. If no number is found, *number will be set to NULL. Likewise for the name. Flags can contain any of the following: CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, CID_MSGWAITING, CID_NOMSGWAITING, CID_QUALIFIER

Definition at line 189 of file callerid.c.

Referenced by callerid_get().

190 {
191  *flags = cid->flags;
192  if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NAME)) {
193  *name = NULL;
194  } else {
195  *name = cid->name;
196  }
197  if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER)) {
198  *number = NULL;
199  } else {
200  *number = cid->number;
201  }
202  *redirecting = cid->redirecting;
203 }
Number structure.
Definition: app_followme.c:154
void callerid_init ( void  )

Initialize stuff for inverse FFT.

CallerID Initialization.

Definition at line 116 of file callerid.c.

References CALLERID_MARK, and CALLERID_SPACE.

117 {
118  cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
119  cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
120  cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
121  cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
122  sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
123  sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
124  casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
125  casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
126  casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
127  casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
128 }
#define CALLERID_MARK
Definition: callerid.c:71
#define CALLERID_SPACE
Definition: callerid.c:70
struct callerid_state* callerid_new ( int  cid_signalling)

Create a callerID state machine.

Parameters
cid_signallingType of signalling in use

This function returns a malloc'd instance of the callerid_state data structure.

Returns
Returns a pointer to a malloc'd callerid_state structure, or NULL on error.

Definition at line 130 of file callerid.c.

References ast_calloc, fsk_data::bw, fsk_data::f_mark_idx, fsk_data::f_space_idx, fsk_data::instop, fsk_data::nbit, fsk_data::nstop, fsk_data::pllispb, and fsk_data::spb.

131 {
132  struct callerid_state *cid;
133 
134  if ((cid = ast_calloc(1, sizeof(*cid)))) {
135 #ifdef INTEGER_CALLERID
136  cid->fskd.ispb = 7; /* 1200 baud */
137  /* Set up for 1200 / 8000 freq *32 to allow ints */
138  cid->fskd.pllispb = (int)(8000 * 32 / 1200);
139  cid->fskd.pllids = cid->fskd.pllispb/32;
140  cid->fskd.pllispb2 = cid->fskd.pllispb/2;
141 
142  cid->fskd.icont = 0; /* PLL REset */
143  /* cid->fskd.hdlc = 0; */ /* Async */
144  cid->fskd.nbit = 8; /* 8 bits */
145  cid->fskd.instop = 1; /* 1 stop bit */
146  /* cid->fskd.paridad = 0; */ /* No parity */
147  cid->fskd.bw = 1; /* Filter 800 Hz */
148  if (cid_signalling == 2) { /* v23 signalling */
149  cid->fskd.f_mark_idx = 4; /* 1300 Hz */
150  cid->fskd.f_space_idx = 5; /* 2100 Hz */
151  } else { /* Bell 202 signalling as default */
152  cid->fskd.f_mark_idx = 2; /* 1200 Hz */
153  cid->fskd.f_space_idx = 3; /* 2200 Hz */
154  }
155  /* cid->fskd.pcola = 0; */ /* No clue */
156  /* cid->fskd.cont = 0.0; */ /* Digital PLL reset */
157  /* cid->fskd.x0 = 0.0; */
158  /* cid->fskd.state = 0; */
159  cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
160  /* cid->pos = 0; */
161 
162  fskmodem_init(&cid->fskd);
163 #else
164  cid->fskd.spb = 7.0; /* 1200 baud */
165  /* cid->fskd.hdlc = 0; */ /* Async */
166  cid->fskd.nbit = 8; /* 8 bits */
167  cid->fskd.nstop = 1.0; /* 1 stop bit */
168  /* cid->fskd.paridad = 0; */ /* No parity */
169  cid->fskd.bw = 1; /* Filter 800 Hz */
170  if (cid_signalling == 2) { /* v23 signalling */
171  cid->fskd.f_mark_idx = 4; /* 1300 Hz */
172  cid->fskd.f_space_idx = 5; /* 2100 Hz */
173  } else { /* Bell 202 signalling as default */
174  cid->fskd.f_mark_idx = 2; /* 1200 Hz */
175  cid->fskd.f_space_idx = 3; /* 2200 Hz */
176  }
177  /* cid->fskd.pcola = 0; */ /* No clue */
178  /* cid->fskd.cont = 0.0; */ /* Digital PLL reset */
179  /* cid->fskd.x0 = 0.0; */
180  /* cid->fskd.state = 0; */
181  cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
182  /* cid->pos = 0; */
183 #endif
184  }
185 
186  return cid;
187 }
float nstop
int instop
Definition: fskmodem_int.h:46
int pllispb
Definition: fskmodem_int.h:59
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int f_space_idx
int f_mark_idx