Sat Mar 10 01:54:47 2012

Asterisk developer's documentation


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"

Go to the source code of this file.

Data Structures

struct  ast_value_translation
struct  callerid_state

Defines

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

Variables

float casdi1
float casdi2
float casdr1
float casdr2
float cid_di [4]
float cid_dr [4]
float clidsb = 8000.0 / 1200.0
static struct ast_value_translation connected_line_source_types []
 Translation table for connected line update source settings.
static struct ast_value_translation party_name_charset_tbl []
 Translation table for ast_party_name char-set settings.
static struct ast_value_translation pres_types []
 Translation table for Caller ID Presentation settings.
static 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 <markster@digium.com>

Definition in file callerid.c.


Define Documentation

#define AST_CALLERID_UNKNOWN   "<unknown>"

Definition at line 72 of file callerid.c.

#define CALLERID_MARK   1200.0

1200 hz for "1"

Definition at line 67 of file callerid.c.

Referenced by callerid_init().

#define CALLERID_SPACE   2200.0

2200 hz for "0"

Definition at line 66 of file callerid.c.

Referenced by callerid_init().

#define CAS_FREQ1   2130.0

Definition at line 69 of file callerid.c.

Referenced by callerid_init().

#define CAS_FREQ2   2750.0

Definition at line 70 of file callerid.c.

Referenced by callerid_init().

#define SAS_FREQ   440.0

Definition at line 68 of file callerid.c.

Referenced by callerid_init().


Function Documentation

static int __ast_callerid_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
int  callwaiting,
format_t  codec 
) [static]

Definition at line 1054 of file callerid.c.

References ast_strlen_zero(), and callerid_generate().

Referenced by ast_callerid_callwaiting_generate(), and ast_callerid_generate().

01055 {
01056    if (ast_strlen_zero(name))
01057       name = NULL;
01058    if (ast_strlen_zero(number))
01059       number = NULL;
01060    return callerid_generate(buf, number, name, 0, callwaiting, codec);
01061 }

int ast_callerid_callwaiting_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
format_t  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 1068 of file callerid.c.

References __ast_callerid_generate().

Referenced by my_send_callerid(), and send_cwcidspill().

01069 {
01070    return __ast_callerid_generate(buf, name, number, 1, codec);
01071 }

int ast_callerid_generate ( unsigned char *  buf,
const char *  name,
const char *  number,
format_t  codec 
)

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

Parameters:
buf buffer for output samples. See callerid_generate() for details regarding buffer.
name Caller-ID Name
number Caller-ID Number
codec Asterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)
Acts like callerid_generate except uses an asterisk format callerid string.

Definition at line 1063 of file callerid.c.

References __ast_callerid_generate().

Referenced by my_send_callerid().

01064 {
01065    return __ast_callerid_generate(buf, name, number, 0, codec);
01066 }

char* ast_callerid_merge ( char *  buf,
int  bufsiz,
const char *  name,
const char *  num,
const char *  unknown 
)

Definition at line 1073 of file callerid.c.

References ast_copy_string().

Referenced by _sip_show_peer(), _skinny_show_line(), handle_cli_iax2_show_peer(), leave_voicemail(), prep_email_sub_vars(), set_one_cid(), and sip_show_user().

01074 {
01075    if (!unknown)
01076       unknown = "<unknown>";
01077    if (name && num)
01078       snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
01079    else if (name) 
01080       ast_copy_string(buf, name, bufsiz);
01081    else if (num)
01082       ast_copy_string(buf, num, bufsiz);
01083    else
01084       ast_copy_string(buf, unknown, bufsiz);
01085    return buf;
01086 }

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, outputed in name and location.

Parameters:
instr buffer of callerid stream (in audio form) to be parsed. Warning, data in buffer is changed.
name address of a pointer-to-char for the name value of the stream.
location address 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.
Returns:
Returns 0 on success, -1 on failure.

Definition at line 1005 of file callerid.c.

References ast_copy_string(), ast_isphonenumber(), ast_shrink_phone_number(), ast_skip_blanks(), and ast_trim_blanks().

Referenced by action_originate(), advanced_options(), ast_callerid_split(), ast_privacy_check(), ast_privacy_set(), dial_exec_full(), handle_setcallerid(), misdn_new(), play_message_callerid(), read_config(), rpt_call(), and unistim_new().

01006 {
01007    char *ns, *ne, *ls, *le;
01008 
01009    /* Try "name" <location> format or name <location> format */
01010    if ((ls = strrchr(instr, '<')) && (le = strrchr(ls, '>'))) {
01011       *ls = *le = '\0'; /* location found, trim off the brackets */
01012       *location = ls + 1;  /* and this is the result */
01013       if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
01014          *ns = *ne = '\0'; /* trim off the quotes */
01015          *name = ns + 1;      /* and this is the name */
01016       } else if (ns) {
01017          /* An opening quote was found but no closing quote was. The closing
01018           * quote may actually be after the end of the bracketed number
01019           */
01020          if (strchr(le + 1, '\"')) {
01021             *ns = '\0';
01022             *name = ns + 1;
01023             ast_trim_blanks(*name);
01024          } else {
01025             *name = NULL;
01026          }
01027       } else { /* no quotes, trim off leading and trailing spaces */
01028          *name = ast_skip_blanks(instr);
01029          ast_trim_blanks(*name);
01030       }
01031    } else { /* no valid brackets */
01032       char tmp[256];
01033 
01034       ast_copy_string(tmp, instr, sizeof(tmp));
01035       ast_shrink_phone_number(tmp);
01036       if (ast_isphonenumber(tmp)) { /* Assume it's just a location */
01037          *name = NULL;
01038          strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
01039          *location = instr;
01040       } else { /* Assume it's just a name. */
01041          *location = NULL;
01042          if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
01043             *ns = *ne = '\0'; /* trim off the quotes */
01044             *name = ns + 1;      /* and this is the name */
01045          } else { /* no quotes, trim off leading and trailing spaces */
01046             *name = ast_skip_blanks(instr);
01047             ast_trim_blanks(*name);
01048          }
01049       }
01050    }
01051    return 0;
01052 }

int ast_callerid_split ( const char *  buf,
char *  name,
int  namelen,
char *  num,
int  numlen 
)

Definition at line 1088 of file callerid.c.

References ast_callerid_parse(), ast_copy_string(), ast_shrink_phone_number(), and ast_strdupa.

Referenced by apply_outgoing(), build_peer(), build_user(), callerid_read(), config_parse_variables(), load_module(), party_id_write(), prep_email_sub_vars(), store_callerid(), and update_common_options().

01089 {
01090    char *tmp;
01091    char *l = NULL, *n = NULL;
01092 
01093    tmp = ast_strdupa(buf);
01094    ast_callerid_parse(tmp, &n, &l);
01095    if (n)
01096       ast_copy_string(name, n, namelen);
01097    else
01098       name[0] = '\0';
01099    if (l) {
01100       ast_shrink_phone_number(l);
01101       ast_copy_string(num, l, numlen);
01102    } else
01103       num[0] = '\0';
01104    return 0;
01105 }

int ast_callerid_vmwi_generate ( unsigned char *  buf,
int  active,
int  type,
format_t  codec,
const char *  name,
const char *  number,
int  flags 
)

Generate message waiting indicator.

Parameters:
buf 
active The message indicator state -- either 0 no messages in mailbox or 1 messages in mailbox
type Format 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 807 of file callerid.c.

References callerid_genmsg(), CID_MWI_TYPE_MDMF, CID_MWI_TYPE_MDMF_FULL, len(), PUT_BYTE, PUT_CLID, and PUT_CLID_MARKMS.

Referenced by mwi_send_init().

00809 {
00810    char msg[256];
00811    int len = 0;
00812    int sum;
00813    int x;
00814    int bytes = 0;
00815    float cr = 1.0;
00816    float ci = 0.0;
00817    float scont = 0.0;
00818    
00819    if (type == CID_MWI_TYPE_MDMF_FULL) {
00820       /* MDMF Message waiting with date, number, name and MWI parameter */
00821       msg[0] = 0x82;
00822 
00823       /* put date, number info at the right place */
00824       len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags); 
00825       
00826       /* length of MDMF CLI plus Message Waiting Structure */
00827       msg[1] = len+3;
00828       
00829       /* Go to the position to write to */
00830       len = len+2;
00831       
00832       /* "Message Waiting Parameter" */
00833       msg[len++] = 0x0b;
00834       /* Length of IE is one */
00835       msg[len++] = 1;
00836       /* Active or not */
00837       if (active)
00838          msg[len++] = 0xff;
00839       else
00840          msg[len++] = 0x00;
00841       
00842    } else if (type == CID_MWI_TYPE_MDMF) {
00843       /* MDMF Message waiting only */
00844       /* same as above except that the we only put MWI parameter */
00845       msg[len++] = 0x82;
00846       /* Length is 3 */
00847       msg[len++] = 3;
00848       /* IE is "Message Waiting Parameter" */
00849       msg[len++] = 0x0b;
00850       /* Length of IE is one */
00851       msg[len++] = 1;
00852       /* Active or not */
00853       if (active)
00854          msg[len++] = 0xff;
00855       else
00856          msg[len++] = 0x00;
00857    } else {
00858       /* SDMF Message waiting */
00859       msg[len++] = 0x6;
00860       /* Length is 3 */
00861       msg[len++] = 3;
00862       if (active) {
00863          msg[len++] = 0x42;
00864          msg[len++] = 0x42;
00865          msg[len++] = 0x42;
00866       } else {
00867          msg[len++] = 0x6f;
00868          msg[len++] = 0x6f;
00869          msg[len++] = 0x6f;
00870       }
00871    }
00872    sum = 0;
00873    for (x = 0; x < len; x++)
00874       sum += msg[x];
00875    sum = (256 - (sum & 255));
00876    msg[len++] = sum;
00877    /* Wait a half a second */
00878    for (x = 0; x < 4000; x++)
00879       PUT_BYTE(0x7f);
00880    /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00881    for (x = 0; x < 30; x++)
00882       PUT_CLID(0x55);
00883    /* Send 170ms of callerid marks */
00884    for (x = 0; x < 170; x++)
00885       PUT_CLID_MARKMS;
00886    for (x = 0; x < len; x++) {
00887       PUT_CLID(msg[x]);
00888    }
00889    /* Send 50 more ms of marks */
00890    for (x = 0; x < 50; x++)
00891       PUT_CLID_MARKMS;
00892    return bytes;
00893 }

const char* ast_connected_line_source_describe ( int  data  ) 

Convert connected line update source value to explanatory string.

Since:
1.8
Parameters:
data AST_CONNECTED_LINE_UPDATE_SOURCE from callerid.h
Returns:
string for human presentation

Definition at line 1273 of file callerid.c.

References ARRAY_LEN, connected_line_source_types, ast_value_translation::description, and value.

01274 {
01275    int index;
01276 
01277    for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
01278       if (connected_line_source_types[index].value == data) {
01279          return connected_line_source_types[index].description;
01280       }
01281    }
01282 
01283    return "not-known";
01284 }

const char* ast_connected_line_source_name ( int  data  ) 

Convert connected line update source value to text code.

Since:
1.8
Parameters:
data AST_CONNECTED_LINE_UPDATE_SOURCE from callerid.h
Returns:
string for config file

Definition at line 1286 of file callerid.c.

References ARRAY_LEN, connected_line_source_types, ast_value_translation::name, and value.

Referenced by connectedline_read().

01287 {
01288    int index;
01289 
01290    for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
01291       if (connected_line_source_types[index].value == data) {
01292          return connected_line_source_types[index].name;
01293       }
01294    }
01295 
01296    return "not-known";
01297 }

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:
data text string from config file
Return values:
AST_CONNECTED_LINE_UPDATE_SOURCE from callerid.h
-1 if not in table

Definition at line 1260 of file callerid.c.

References ARRAY_LEN, connected_line_source_types, name, and ast_value_translation::value.

Referenced by connectedline_write().

01261 {
01262    int index;
01263 
01264    for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
01265       if (!strcasecmp(connected_line_source_types[index].name, data)) {
01266          return connected_line_source_types[index].value;
01267       }
01268    }
01269 
01270    return -1;
01271 }

const char* ast_describe_caller_presentation ( int  data  ) 

Convert caller ID pres value to explanatory string.

Parameters:
data AST_PRES_ value from callerid.h
Returns:
string for human presentation

Definition at line 1160 of file callerid.c.

References ARRAY_LEN, ast_value_translation::description, pres_types, and value.

Referenced by _sip_show_peer(), peers_data_provider_get(), report_new_callerid(), sig_pri_event_party_id(), and sip_show_user().

01161 {
01162    int index;
01163 
01164    for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
01165       if (pres_types[index].value == data) {
01166          return pres_types[index].description;
01167       }
01168    }
01169 
01170    return "unknown";
01171 }

int ast_gen_cas ( unsigned char *  outbuf,
int  sas,
int  len,
format_t  codec 
)

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

Parameters:
outbuf Allocated buffer for data. Must be at least 2400 bytes unless no SAS is desired
sas Non-zero if CAS should be preceeded by SAS
len How many samples to generate.
codec Which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
Returns:
Returns -1 on error (if len is less than 2400), 0 on success.

Definition at line 258 of file callerid.c.

References gen_tone(), gen_tones(), and callerid_state::pos.

Referenced by __adsi_transmit_messages(), dahdi_callwait(), and my_callwait().

00259 {
00260    int pos = 0;
00261    int saslen = 2400;
00262    float cr1 = 1.0;
00263    float ci1 = 0.0;
00264    float cr2 = 1.0;
00265    float ci2 = 0.0;
00266 
00267    if (sendsas) {
00268       if (len < saslen)
00269          return -1;
00270       gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
00271       len -= saslen;
00272       pos += saslen;
00273       cr2 = cr1;
00274       ci2 = ci1;
00275    }
00276    gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
00277    return 0;
00278 }

int ast_is_shrinkable_phonenumber ( const char *  exten  ) 

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

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

Definition at line 1000 of file callerid.c.

References ast_is_valid_string().

Referenced by check_peer_ok(), check_user_full(), get_pai(), and get_rpid().

01001 {
01002    return ast_is_valid_string(exten, "0123456789*#+()-.");
01003 }

static int ast_is_valid_string ( const char *  exten,
const char *  valid 
) [static]

Checks if phone number consists of valid characters.

Parameters:
exten String that needs to be checked
valid Valid characters in string
Return values:
1 if valid string
0 if string contains invalid characters

Definition at line 983 of file callerid.c.

References ast_strlen_zero().

Referenced by ast_is_shrinkable_phonenumber(), and ast_isphonenumber().

00984 {
00985    int x;
00986 
00987    if (ast_strlen_zero(exten))
00988       return 0;
00989    for (x = 0; exten[x]; x++)
00990       if (!strchr(valid, exten[x]))
00991          return 0;
00992    return 1;
00993 }

int ast_isphonenumber ( const char *  n  ) 

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

Parameters:
n number to be checked.
Returns:
Returns 0 if n is a number, 1 if it's not.

Definition at line 995 of file callerid.c.

References ast_is_valid_string().

Referenced by ast_callerid_parse().

00996 {
00997    return ast_is_valid_string(n, "0123456789*#+");
00998 }

const char* ast_named_caller_presentation ( int  data  ) 

Convert caller ID pres value to text code.

Parameters:
data AST_PRES_ value from callerid.h
Returns:
string for config file

Definition at line 1178 of file callerid.c.

References ARRAY_LEN, ast_value_translation::name, pres_types, and value.

Referenced by callerpres_read(), party_id_read(), party_name_read(), party_number_read(), and redirecting_read().

01179 {
01180    int index;
01181 
01182    for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
01183       if (pres_types[index].value == data) {
01184          return pres_types[index].name;
01185       }
01186    }
01187 
01188    return "unknown";
01189 }

int ast_parse_caller_presentation ( const char *  data  ) 

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

Parameters:
data text string from config file
Return values:
value AST_PRES_ from callerid.h
-1 if not in table

Definition at line 1139 of file callerid.c.

References ARRAY_LEN, name, pres_types, and ast_value_translation::value.

Referenced by build_peer(), callerpres_write(), dial_exec_full(), party_id_write(), party_name_write(), party_number_write(), redirecting_write(), and setcallerid_pres_exec().

01140 {
01141    int index;
01142    if (!data) {
01143       return -1;
01144    }
01145 
01146    for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
01147       if (!strcasecmp(pres_types[index].name, data)) {
01148          return pres_types[index].value;
01149       }
01150    }
01151 
01152    return -1;
01153 }

const char* ast_party_name_charset_describe ( int  data  ) 

Convert ast_party_name.char_set value to explanatory string.

Since:
1.8
Parameters:
data AST_PARTY_CHAR_SET from channel.h
Returns:
string for human presentation

Definition at line 1328 of file callerid.c.

References ARRAY_LEN, ast_value_translation::description, party_name_charset_tbl, and value.

Referenced by sig_pri_event_party_id().

01329 {
01330    int index;
01331 
01332    for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
01333       if (party_name_charset_tbl[index].value == data) {
01334          return party_name_charset_tbl[index].description;
01335       }
01336    }
01337 
01338    return "not-known";
01339 }

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:
data text string from config file
Return values:
AST_PARTY_CHAR_SET from channel.h
-1 if not in table

Definition at line 1315 of file callerid.c.

References ARRAY_LEN, name, party_name_charset_tbl, and ast_value_translation::value.

Referenced by party_name_write().

01316 {
01317    int index;
01318 
01319    for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
01320       if (!strcasecmp(party_name_charset_tbl[index].name, data)) {
01321          return party_name_charset_tbl[index].value;
01322       }
01323    }
01324 
01325    return -1;
01326 }

const char* ast_party_name_charset_str ( int  data  ) 

Convert ast_party_name.char_set value to text code.

Since:
1.8
Parameters:
data AST_PARTY_CHAR_SET from channel.h
Returns:
string for config file

Definition at line 1341 of file callerid.c.

References ARRAY_LEN, ast_value_translation::name, party_name_charset_tbl, and value.

Referenced by party_name_read().

01342 {
01343    int index;
01344 
01345    for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
01346       if (party_name_charset_tbl[index].value == data) {
01347          return party_name_charset_tbl[index].name;
01348       }
01349    }
01350 
01351    return "not-known";
01352 }

const char* ast_redirecting_reason_describe ( int  data  ) 

Convert redirecting reason value to explanatory string.

Since:
1.8
Parameters:
data Q931_REDIRECTING_REASON from callerid.h
Returns:
string for human presentation

Definition at line 1222 of file callerid.c.

References ARRAY_LEN, ast_value_translation::description, redirecting_reason_types, and value.

01223 {
01224    int index;
01225 
01226    for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
01227       if (redirecting_reason_types[index].value == data) {
01228          return redirecting_reason_types[index].description;
01229       }
01230    }
01231 
01232    return "not-known";
01233 }

const char* ast_redirecting_reason_name ( int  data  ) 

Convert redirecting reason value to text code.

Since:
1.8
Parameters:
data Q931_REDIRECTING_REASON from callerid.h
Returns:
string for config file

Definition at line 1235 of file callerid.c.

References ARRAY_LEN, ast_value_translation::name, redirecting_reason_types, and value.

Referenced by redirecting_read().

01236 {
01237    int index;
01238 
01239    for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
01240       if (redirecting_reason_types[index].value == data) {
01241          return redirecting_reason_types[index].name;
01242       }
01243    }
01244 
01245    return "not-known";
01246 }

int ast_redirecting_reason_parse ( const char *  data  ) 

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

Since:
1.8
Parameters:
data text string from config file
Return values:
Q931_REDIRECTING_REASON from callerid.h
-1 if not in table

Definition at line 1209 of file callerid.c.

References ARRAY_LEN, name, redirecting_reason_types, and ast_value_translation::value.

Referenced by redirecting_write().

01210 {
01211    int index;
01212 
01213    for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
01214       if (!strcasecmp(redirecting_reason_types[index].name, data)) {
01215          return redirecting_reason_types[index].value;
01216       }
01217    }
01218 
01219    return -1;
01220 }

void ast_shrink_phone_number ( char *  n  ) 

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 944 of file callerid.c.

Referenced by __analog_ss_thread(), action_originate(), ast_callerid_parse(), ast_callerid_split(), ast_privacy_check(), ast_privacy_set(), check_access(), check_peer_ok(), check_user_full(), get_pai(), get_rpid(), handle_setcallerid(), rpt_exec(), setup_privacy_args(), and write_metadata().

00945 {
00946    int x, y = 0;
00947    int bracketed = 0;
00948 
00949    for (x = 0; n[x]; x++) {
00950       switch (n[x]) {
00951       case '[':
00952          bracketed++;
00953          n[y++] = n[x];
00954          break;
00955       case ']':
00956          bracketed--;
00957          n[y++] = n[x];
00958          break;
00959       case '-':
00960          if (bracketed)
00961             n[y++] = n[x];
00962          break;
00963       case '.':
00964          if (!n[x+1])
00965             n[y++] = n[x];
00966          break;
00967       default:
00968          /* ignore parenthesis and whitespace */
00969          if (!strchr("( )", n[x]))
00970             n[y++] = n[x];
00971       }
00972    }
00973    n[y] = '\0';
00974 }

static unsigned short calc_crc ( unsigned short  crc,
unsigned char  data 
) [static]

Definition at line 280 of file callerid.c.

References org.

Referenced by callerid_feed_jp().

00281 {
00282    unsigned int i, j, org, dst;
00283    org = data;
00284    dst = 0;
00285 
00286    for (i = 0; i < CHAR_BIT; i++) {
00287       org <<= 1;
00288       dst >>= 1;
00289       if (org & 0x100) 
00290          dst |= 0x80;
00291    }
00292    data = (unsigned char) dst;
00293    crc ^= (unsigned int) data << (16 - CHAR_BIT);
00294    for (j = 0; j < CHAR_BIT; j++) {
00295       if (crc & 0x8000U)
00296          crc = (crc << 1) ^ 0x1021U ;
00297       else
00298          crc <<= 1 ;
00299    }
00300       return crc;
00301 }

int callerid_feed ( struct callerid_state cid,
unsigned char *  ubuf,
int  samples,
format_t  codec 
)

Read samples into the state machine.

Parameters:
cid Which state machine to act upon
ubuf containing your samples
samples number of samples contained within the buffer.
codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
Send received audio to the Caller*ID demodulator.
Return values:
-1 on error
0 for "needs more samples"
1 if the CallerID spill reception is complete.

Definition at line 542 of file callerid.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), AST_XLAW, CID_MSGWAITING, CID_NOMSGWAITING, CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, callerid_state::cksum, callerid_state::flags, fsk_serial(), callerid_state::fskd, callerid_state::len, LOG_ERROR, LOG_NOTICE, LOG_WARNING, callerid_state::name, callerid_state::number, callerid_state::oldlen, callerid_state::oldstuff, callerid_state::pos, callerid_state::rawdata, callerid_state::sawflag, and callerid_state::type.

Referenced by analog_ss_thread(), mwi_thread(), and my_get_callerid().

00543 {
00544    int mylen = len;
00545    int olen;
00546    int b = 'X';
00547    int res;
00548    int x;
00549    short *buf;
00550 
00551    buf = alloca(2 * len + cid->oldlen);
00552 
00553    memcpy(buf, cid->oldstuff, cid->oldlen);
00554    mylen += cid->oldlen/2;
00555 
00556    for (x = 0; x < len; x++) 
00557       buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
00558    while (mylen >= 160) {
00559       olen = mylen;
00560       res = fsk_serial(&cid->fskd, buf, &mylen, &b);
00561       if (mylen < 0) {
00562          ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
00563          return -1;
00564       }
00565       buf += (olen - mylen);
00566       if (res < 0) {
00567          ast_log(LOG_NOTICE, "fsk_serial failed\n");
00568          return -1;
00569       }
00570       if (res == 1) {
00571          if (b > 0xff) {
00572             if (cid->sawflag != 5) {
00573                /* Ignore invalid bytes */
00574                continue;
00575             }
00576             /*
00577              * We can tollerate an error on the checksum character since the
00578              * checksum character is the last character in the message and
00579              * it validates the message.
00580              *
00581              * Remove character error flags.
00582              * Bit 8 : Parity error
00583              * Bit 9 : Framing error
00584              */
00585             b &= 0xff;
00586          }
00587          switch (cid->sawflag) {
00588          case 0: /* Look for flag */
00589             if (b == 'U')
00590                cid->sawflag = 2;
00591             break;
00592          case 2: /* Get lead-in */
00593             if ((b == 0x04) || (b == 0x80) || (b == 0x06) || (b == 0x82)) {
00594                cid->type = b;
00595                cid->sawflag = 3;
00596                cid->cksum = b;
00597             }
00598             break;
00599          case 3:  /* Get length */
00600             /* Not a lead in.  We're ready  */
00601             cid->sawflag = 4;
00602             cid->len = b;
00603             cid->pos = 0;
00604             cid->cksum += b;
00605             break;
00606          case 4: /* Retrieve message */
00607             if (cid->pos >= 128) {
00608                ast_log(LOG_WARNING, "Caller ID too long???\n");
00609                return -1;
00610             }
00611             cid->rawdata[cid->pos++] = b;
00612             cid->len--;
00613             cid->cksum += b;
00614             if (!cid->len) {
00615                cid->rawdata[cid->pos] = '\0';
00616                cid->sawflag = 5;
00617             }
00618             break;
00619          case 5: /* Check checksum */
00620             if (b != (256 - (cid->cksum & 0xff))) {
00621                ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
00622                /* Try again */
00623                cid->sawflag = 0;
00624                break;
00625             }
00626       
00627             cid->number[0] = '\0';
00628             cid->name[0] = '\0';
00629             /* Update flags */
00630             cid->flags = 0;
00631             /* If we get this far we're fine.  */
00632             if ((cid->type == 0x80) || (cid->type == 0x82)) {
00633                /* MDMF */
00634                /* Go through each element and process */
00635                for (x = 0; x < cid->pos;) {
00636                   switch (cid->rawdata[x++]) {
00637                   case 1:
00638                      /* Date */
00639                      break;
00640                   case 2: /* Number */
00641                   case 3: /* Number (for Zebble) */
00642                   case 4: /* Number */
00643                      res = cid->rawdata[x];
00644                      if (res > 32) {
00645                         ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
00646                         res = 32; 
00647                      }
00648                      if (ast_strlen_zero(cid->number)) {
00649                         memcpy(cid->number, cid->rawdata + x + 1, res);
00650                         /* Null terminate */
00651                         cid->number[res] = '\0';
00652                      }
00653                      break;
00654                   case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
00655                      break;
00656                   case 7: /* Name */
00657                   case 8: /* Name */
00658                      res = cid->rawdata[x];
00659                      if (res > 32) {
00660                         ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
00661                         res = 32; 
00662                      }
00663                      memcpy(cid->name, cid->rawdata + x + 1, res);
00664                      cid->name[res] = '\0';
00665                      break;
00666                   case 11: /* Message Waiting */
00667                      res = cid->rawdata[x + 1];
00668                      if (res)
00669                         cid->flags |= CID_MSGWAITING;
00670                      else
00671                         cid->flags |= CID_NOMSGWAITING;
00672                      break;
00673                   case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
00674                   case 19: /* UK: Network message system status (Number of messages waiting) */
00675                   case 22: /* Something French */
00676                      break;
00677                   default:
00678                      ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]);
00679                   }
00680                   res = cid->rawdata[x];
00681                   if (0 > res){  /* Negative offset in the CID Spill */
00682                      ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
00683                      /* Try again */
00684                      cid->sawflag = 0;
00685                      break;   /* Exit the loop */
00686                   }
00687                   x += cid->rawdata[x];
00688                   x++;
00689                }
00690             } else if (cid->type == 0x6) {
00691                /* VMWI SDMF */
00692                if (cid->rawdata[2] == 0x42) {
00693                   cid->flags |= CID_MSGWAITING;
00694                } else if (cid->rawdata[2] == 0x6f) {
00695                   cid->flags |= CID_NOMSGWAITING;
00696                }
00697             } else {
00698                /* SDMF */
00699                ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
00700             }
00701             if (!strcmp(cid->number, "P")) {
00702                strcpy(cid->number, "");
00703                cid->flags |= CID_PRIVATE_NUMBER;
00704             } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
00705                strcpy(cid->number, "");
00706                cid->flags |= CID_UNKNOWN_NUMBER;
00707             }
00708             if (!strcmp(cid->name, "P")) {
00709                strcpy(cid->name, "");
00710                cid->flags |= CID_PRIVATE_NAME;
00711             } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
00712                strcpy(cid->name, "");
00713                cid->flags |= CID_UNKNOWN_NAME;
00714             }
00715             return 1;
00716             break;
00717          default:
00718             ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
00719          }
00720       }
00721    }
00722    if (mylen) {
00723       memcpy(cid->oldstuff, buf, mylen * 2);
00724       cid->oldlen = mylen * 2;
00725    } else
00726       cid->oldlen = 0;
00727 
00728    return 0;
00729 }

int callerid_feed_jp ( struct callerid_state cid,
unsigned char *  ubuf,
int  samples,
format_t  codec 
)

Read samples into the state machine.

Parameters:
cid Which state machine to act upon
ubuf containing your samples
samples number of samples contained within the buffer.
codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
Send received audio to the Caller*ID demodulator (for japanese style lines).
Return values:
-1 on error
0 for "needs more samples"
1 if the CallerID spill reception is complete.

Definition at line 303 of file callerid.c.

References ast_copy_string(), ast_debug, ast_log(), AST_XLAW, calc_crc(), CID_UNKNOWN_NUMBER, callerid_state::crc, callerid_state::flags, fsk_serial(), callerid_state::fskd, callerid_state::len, LOG_ERROR, LOG_NOTICE, LOG_WARNING, callerid_state::name, callerid_state::number, callerid_state::oldlen, callerid_state::oldstuff, option_debug, callerid_state::pos, callerid_state::rawdata, callerid_state::sawflag, and callerid_state::skipflag.

Referenced by analog_ss_thread(), and my_get_callerid().

00304 {
00305    int mylen = len;
00306    int olen;
00307    int b = 'X';
00308    int b2;
00309    int res;
00310    int x;
00311    short *buf;
00312 
00313    buf = alloca(2 * len + cid->oldlen);
00314 
00315    memcpy(buf, cid->oldstuff, cid->oldlen);
00316    mylen += cid->oldlen / 2;
00317 
00318    for (x = 0; x < len; x++) 
00319       buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
00320 
00321    while (mylen >= 160) {
00322       b = b2 = 0;
00323       olen = mylen;
00324       res = fsk_serial(&cid->fskd, buf, &mylen, &b);
00325 
00326       if (mylen < 0) {
00327          ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
00328          return -1;
00329       }
00330 
00331       buf += (olen - mylen);
00332 
00333       if (res < 0) {
00334          ast_log(LOG_NOTICE, "fsk_serial failed\n");
00335          return -1;
00336       }
00337 
00338       if (res == 1) {
00339          b2 = b;
00340          b  &= 0x7f;
00341 
00342          /* crc checksum calculation */
00343          if (cid->sawflag > 1)
00344             cid->crc = calc_crc(cid->crc, (unsigned char) b2);
00345 
00346          /* Ignore invalid bytes */
00347          if (b > 0xff)
00348             continue;
00349 
00350          /* skip DLE if needed */
00351          if (cid->sawflag > 0) {
00352             if (cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10) {
00353                cid->skipflag = 1 ;
00354                continue ;
00355             }
00356          }
00357          if (cid->skipflag == 1)
00358             cid->skipflag = 0 ;
00359 
00360          /* caller id retrieval */
00361          switch (cid->sawflag) {
00362          case 0: /* DLE */
00363             if (b == 0x10) {
00364                cid->sawflag = 1;
00365                cid->skipflag = 0;
00366                cid->crc = 0;
00367             }
00368             break;
00369          case 1: /* SOH */
00370             if (b == 0x01) 
00371                cid->sawflag = 2;
00372             break ;
00373          case 2: /* HEADER */
00374             if (b == 0x07) 
00375                cid->sawflag = 3;
00376             break;
00377          case 3: /* STX */
00378             if (b == 0x02) 
00379                cid->sawflag = 4;
00380             break;
00381          case 4: /* SERVICE TYPE */
00382             if (b == 0x40) 
00383                cid->sawflag = 5;
00384             break;
00385          case 5: /* Frame Length */
00386             cid->sawflag = 6;
00387             break;   
00388          case 6: /* NUMBER TYPE */
00389             cid->sawflag = 7;
00390             cid->pos = 0;
00391             cid->rawdata[cid->pos++] = b;
00392             break;
00393          case 7:  /* NUMBER LENGTH */
00394             cid->sawflag = 8;
00395             cid->len = b;
00396             if ((cid->len+2) >= sizeof(cid->rawdata)) {
00397                ast_log(LOG_WARNING, "too long caller id string\n") ;
00398                return -1;
00399             }
00400             cid->rawdata[cid->pos++] = b;
00401             break;
00402          case 8:  /* Retrieve message */
00403             cid->rawdata[cid->pos++] = b;
00404             cid->len--;
00405             if (cid->len<=0) {
00406                cid->rawdata[cid->pos] = '\0';
00407                cid->sawflag = 9;
00408             }
00409             break;
00410          case 9:  /* ETX */
00411             cid->sawflag = 10;
00412             break;
00413          case 10: /* CRC Checksum 1 */
00414             cid->sawflag = 11;
00415             break;
00416          case 11: /* CRC Checksum 2 */
00417             cid->sawflag = 12;
00418             if (cid->crc != 0) {
00419                ast_log(LOG_WARNING, "crc checksum error\n") ;
00420                return -1;
00421             } 
00422             /* extract caller id data */
00423             for (x = 0; x < cid->pos;) {
00424                switch (cid->rawdata[x++]) {
00425                case 0x02: /* caller id  number */
00426                   cid->number[0] = '\0';
00427                   cid->name[0] = '\0';
00428                   cid->flags = 0;
00429                   res = cid->rawdata[x++];
00430                   ast_copy_string(cid->number, &cid->rawdata[x], res+1);
00431                   x += res;
00432                   break;
00433                case 0x21: /* additional information */
00434                   /* length */
00435                   x++; 
00436                   /* number type */
00437                   switch (cid->rawdata[x]) { 
00438                   case 0x00: /* unknown */
00439                   case 0x01: /* international number */
00440                   case 0x02: /* domestic number */
00441                   case 0x03: /* network */
00442                   case 0x04: /* local call */
00443                   case 0x06: /* short dial number */
00444                   case 0x07: /* reserved */
00445                   default:   /* reserved */
00446                      ast_debug(2, "cid info:#1=%X\n", cid->rawdata[x]);
00447                      break ;
00448                   }
00449                   x++; 
00450                   /* numbering plan octed 4 */
00451                   x++; 
00452                   /* numbering plan octed 5 */
00453                   switch (cid->rawdata[x]) { 
00454                   case 0x00: /* unknown */
00455                   case 0x01: /* recommendation E.164 ISDN */
00456                   case 0x03: /* recommendation X.121 */
00457                   case 0x04: /* telex dial plan */
00458                   case 0x08: /* domestic dial plan */
00459                   case 0x09: /* private dial plan */
00460                   case 0x05: /* reserved */
00461                   default:   /* reserved */
00462                      ast_debug(2, "cid info:#2=%X\n", cid->rawdata[x]);
00463                      break ;
00464                   }
00465                   x++; 
00466                   break ;
00467                case 0x04: /* no callerid reason */
00468                   /* length */
00469                   x++; 
00470                   /* no callerid reason code */
00471                   switch (cid->rawdata[x]) {
00472                   case 'P': /* caller id denied by user */
00473                   case 'O': /* service not available */
00474                   case 'C': /* pay phone */
00475                   case 'S': /* service congested */
00476                      cid->flags |= CID_UNKNOWN_NUMBER;
00477                      ast_debug(2, "no cid reason:%c\n", cid->rawdata[x]);
00478                      break ;
00479                   }
00480                   x++; 
00481                   break ;
00482                case 0x09: /* dialed number */
00483                   /* length */
00484                   res = cid->rawdata[x++];
00485                   /* dialed number */
00486                   x += res;
00487                   break ;
00488                case 0x22: /* dialed number additional information */
00489                   /* length */
00490                   x++;
00491                   /* number type */
00492                   switch (cid->rawdata[x]) {
00493                   case 0x00: /* unknown */
00494                   case 0x01: /* international number */
00495                   case 0x02: /* domestic number */
00496                   case 0x03: /* network */
00497                   case 0x04: /* local call */
00498                   case 0x06: /* short dial number */
00499                   case 0x07: /* reserved */
00500                   default:   /* reserved */
00501                      if (option_debug > 1)
00502                         ast_log(LOG_NOTICE, "did info:#1=%X\n", cid->rawdata[x]);
00503                      break ;
00504                   }
00505                   x++;
00506                   /* numbering plan octed 4 */
00507                   x++;
00508                   /* numbering plan octed 5 */
00509                   switch (cid->rawdata[x]) {
00510                   case 0x00: /* unknown */
00511                   case 0x01: /* recommendation E.164 ISDN */
00512                   case 0x03: /* recommendation X.121 */
00513                   case 0x04: /* telex dial plan */
00514                   case 0x08: /* domestic dial plan */
00515                   case 0x09: /* private dial plan */
00516                   case 0x05: /* reserved */
00517                   default:   /* reserved */
00518                      ast_debug(2, "did info:#2=%X\n", cid->rawdata[x]);
00519                      break ;
00520                   }
00521                   x++;
00522                   break ;
00523                }
00524             }
00525             return 1;
00526             break;
00527          default:
00528             ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
00529          }
00530       }
00531    }
00532    if (mylen) {
00533       memcpy(cid->oldstuff, buf, mylen * 2);
00534       cid->oldlen = mylen * 2;
00535    } else
00536       cid->oldlen = 0;
00537    
00538    return 0;
00539 }

void callerid_free ( struct callerid_state cid  ) 

This function frees callerid_state cid.

Parameters:
cid This is the callerid_state state machine to free

Definition at line 731 of file callerid.c.

References ast_free.

Referenced by __analog_ss_thread(), analog_ss_thread(), mwi_thread(), my_get_callerid(), and my_stop_cid_detect().

00732 {
00733    ast_free(cid);
00734 }

int callerid_generate ( unsigned char *  buf,
const char *  number,
const char *  name,
int  flags,
int  callwaiting,
format_t  codec 
)

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

Parameters:
buf Buffer 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.
number Use NULL for no number or "P" for "private"
name name to be used
flags passed flags
callwaiting callwaiting 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 895 of file callerid.c.

References callerid_genmsg(), len(), PUT_BYTE, PUT_CLID, and PUT_CLID_MARKMS.

Referenced by __ast_callerid_generate().

00896 {
00897    int bytes = 0;
00898    int x, sum;
00899    int len;
00900 
00901    /* Initial carriers (real/imaginary) */
00902    float cr = 1.0;
00903    float ci = 0.0;
00904    float scont = 0.0;
00905    char msg[256];
00906    len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
00907    if (!callwaiting) {
00908       /* Wait a half a second */
00909       for (x = 0; x < 4000; x++)
00910          PUT_BYTE(0x7f);
00911       /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00912       for (x = 0; x < 30; x++)
00913          PUT_CLID(0x55);
00914    }
00915    /* Send 150ms of callerid marks */
00916    for (x = 0; x < 150; x++)
00917       PUT_CLID_MARKMS;
00918    /* Send 0x80 indicating MDMF format */
00919    PUT_CLID(0x80);
00920    /* Put length of whole message */
00921    PUT_CLID(len);
00922    sum = 0x80 + strlen(msg);
00923    /* Put each character of message and update checksum */
00924    for (x = 0; x < len; x++) {
00925       PUT_CLID(msg[x]);
00926       sum += msg[x];
00927    }
00928    /* Send 2's compliment of sum */
00929    PUT_CLID(256 - (sum & 255));
00930 
00931    /* Send 50 more ms of marks */
00932    for (x = 0; x < 50; x++)
00933       PUT_CLID_MARKMS;
00934    
00935    return bytes;
00936 }

static int callerid_genmsg ( char *  msg,
int  size,
const char *  number,
const char *  name,
int  flags 
) [static]

Definition at line 736 of file callerid.c.

References ast_localtime(), ast_strlen_zero(), ast_tvnow(), CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by ast_callerid_vmwi_generate(), and callerid_generate().

00737 {
00738    struct timeval now = ast_tvnow();
00739    struct ast_tm tm;
00740    char *ptr;
00741    int res;
00742    int i, x;
00743 
00744    /* Get the time */
00745    ast_localtime(&now, &tm, NULL);
00746    
00747    ptr = msg;
00748    
00749    /* Format time and message header */
00750    res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
00751             tm.tm_mday, tm.tm_hour, tm.tm_min);
00752    size -= res;
00753    ptr += res;
00754    if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
00755       /* Indicate number not known */
00756       res = snprintf(ptr, size, "\004\001O");
00757       size -= res;
00758       ptr += res;
00759    } else if (flags & CID_PRIVATE_NUMBER) {
00760       /* Indicate number is private */
00761       res = snprintf(ptr, size, "\004\001P");
00762       size -= res;
00763       ptr += res;
00764    } else {
00765       /* Send up to 16 digits of number MAX */
00766       i = strlen(number);
00767       if (i > 16)
00768          i = 16;
00769       res = snprintf(ptr, size, "\002%c", i);
00770       size -= res;
00771       ptr += res;
00772       for (x = 0; x < i; x++)
00773          ptr[x] = number[x];
00774       ptr[i] = '\0';
00775       ptr += i;
00776       size -= i;
00777    }
00778 
00779    if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
00780       /* Indicate name not known */
00781       res = snprintf(ptr, size, "\010\001O");
00782       size -= res;
00783       ptr += res;
00784    } else if (flags & CID_PRIVATE_NAME) {
00785       /* Indicate name is private */
00786       res = snprintf(ptr, size, "\010\001P");
00787       size -= res;
00788       ptr += res;
00789    } else {
00790       /* Send up to 16 digits of name MAX */
00791       i = strlen(name);
00792       if (i > 16)
00793          i = 16;
00794       res = snprintf(ptr, size, "\007%c", i);
00795       size -= res;
00796       ptr += res;
00797       for (x = 0; x < i; x++)
00798          ptr[x] = name[x];
00799       ptr[i] = '\0';
00800       ptr += i;
00801       size -= i;
00802    }
00803    return (ptr - msg);
00804    
00805 }

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:
cid Callerid state machine to act upon
number Pass the address of a pointer-to-char (will contain the phone number)
name Pass the address of a pointer-to-char (will contain the name)
flags Pass the address of an int variable(will contain the various callerid flags)
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:

Returns:
Returns nothing.

Definition at line 185 of file callerid.c.

References CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, callerid_state::flags, callerid_state::name, and callerid_state::number.

Referenced by analog_ss_thread(), and my_get_callerid().

00186 {
00187    *flags = cid->flags;
00188    if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NAME))
00189       *name = NULL;
00190    else
00191       *name = cid->name;
00192    if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
00193       *number = NULL;
00194    else
00195       *number = cid->number;
00196 }

void callerid_get_dtmf ( char *  cidstring,
char *  number,
int *  flags 
)

Get and parse DTMF-based callerid.

Parameters:
cidstring The actual transmitted string.
number The cid number is returned here.
flags The cid flags are returned here.

Definition at line 198 of file callerid.c.

References ast_debug, ast_log(), CID_PRIVATE_NUMBER, CID_UNKNOWN_NUMBER, and LOG_WARNING.

Referenced by __analog_ss_thread(), and analog_ss_thread().

00199 {
00200    int i;
00201    int code;
00202 
00203    /* "Clear" the number-buffer. */
00204    number[0] = 0;
00205 
00206    if (strlen(cidstring) < 2) {
00207       ast_debug(1, "No cid detected\n");
00208       *flags = CID_UNKNOWN_NUMBER;
00209       return;
00210    }
00211    
00212    /* Detect protocol and special types */
00213    if (cidstring[0] == 'B') {
00214       /* Handle special codes */
00215       code = atoi(&cidstring[1]);
00216       if (code == 0)
00217          *flags = CID_UNKNOWN_NUMBER;
00218       else if (code == 10) 
00219          *flags = CID_PRIVATE_NUMBER;
00220       else
00221          ast_debug(1, "Unknown DTMF code %d\n", code);
00222    } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
00223       /* .DK special code */
00224       if (cidstring[1] == '1')
00225          *flags = CID_PRIVATE_NUMBER;
00226       if (cidstring[1] == '2' || cidstring[1] == '3')
00227          *flags = CID_UNKNOWN_NUMBER;
00228    } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
00229       /* "Standard" callerid */
00230       for (i = 1; i < strlen(cidstring); i++) {
00231          if (cidstring[i] == 'C' || cidstring[i] == '#')
00232             break;
00233          if (isdigit(cidstring[i]))
00234             number[i-1] = cidstring[i];
00235          else
00236             ast_debug(1, "Unknown CID digit '%c'\n",
00237                cidstring[i]);
00238       }
00239       number[i-1] = 0;
00240    } else if (isdigit(cidstring[0])) {
00241       /* It begins with a digit, so we parse it as a number and hope
00242        * for the best */
00243       ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
00244          "parsing might be unreliable\n");
00245       for (i = 0; i < strlen(cidstring); i++) {
00246          if (isdigit(cidstring[i]))
00247             number[i] = cidstring[i];
00248          else
00249             break;
00250       }
00251       number[i] = 0;
00252    } else {
00253       ast_debug(1, "Unknown CID protocol, start digit '%c'\n", cidstring[0]);
00254       *flags = CID_UNKNOWN_NUMBER;
00255    }
00256 }

void callerid_init ( void   ) 

CallerID Initialization.

Initializes the callerid system. Mostly stuff for inverse FFT

Definition at line 112 of file callerid.c.

References CALLERID_MARK, CALLERID_SPACE, CAS_FREQ1, CAS_FREQ2, cos, M_PI, and SAS_FREQ.

Referenced by main().

00113 {
00114    cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
00115    cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
00116    cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
00117    cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
00118    sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
00119    sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
00120    casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
00121    casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
00122    casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
00123    casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
00124 }

struct callerid_state* callerid_new ( int  cid_signalling  ) 

Create a callerID state machine.

Parameters:
cid_signalling Type 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 126 of file callerid.c.

References ast_calloc, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, callerid_state::fskd, fskmodem_init(), and fsk_data::ispb.

Referenced by analog_ss_thread(), mwi_thread(), and my_start_cid_detect().

00127 {
00128    struct callerid_state *cid;
00129 
00130    if ((cid = ast_calloc(1, sizeof(*cid)))) {
00131 #ifdef INTEGER_CALLERID
00132       cid->fskd.ispb = 7;           /* 1200 baud */   
00133       /* Set up for 1200 / 8000 freq *32 to allow ints */
00134       cid->fskd.pllispb  = (int)(8000 * 32  / 1200);
00135       cid->fskd.pllids   = cid->fskd.pllispb/32;
00136       cid->fskd.pllispb2 = cid->fskd.pllispb/2;
00137       
00138       cid->fskd.icont = 0;           /* PLL REset */
00139       /* cid->fskd.hdlc = 0; */        /* Async */
00140       cid->fskd.nbit = 8;              /* 8 bits */
00141       cid->fskd.instop = 1;         /* 1 stop bit */
00142       /* cid->fskd.paridad = 0; */     /* No parity */
00143       cid->fskd.bw = 1;                /* Filter 800 Hz */
00144       if (cid_signalling == 2) {       /* v23 signalling */
00145          cid->fskd.f_mark_idx  = 4; /* 1300 Hz */
00146          cid->fskd.f_space_idx = 5; /* 2100 Hz */
00147       } else {                         /* Bell 202 signalling as default */
00148          cid->fskd.f_mark_idx  = 2; /* 1200 Hz */
00149          cid->fskd.f_space_idx = 3; /* 2200 Hz */
00150       }
00151       /* cid->fskd.pcola = 0; */       /* No clue */
00152       /* cid->fskd.cont = 0.0; */      /* Digital PLL reset */
00153       /* cid->fskd.x0 = 0.0; */
00154       /* cid->fskd.state = 0; */
00155       cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
00156       /* cid->pos = 0; */
00157 
00158       fskmodem_init(&cid->fskd);
00159 #else
00160       cid->fskd.spb = 7.0;             /* 1200 baud */
00161       /* cid->fskd.hdlc = 0; */        /* Async */
00162       cid->fskd.nbit = 8;              /* 8 bits */
00163       cid->fskd.nstop = 1.0;           /* 1 stop bit */
00164       /* cid->fskd.paridad = 0; */     /* No parity */
00165       cid->fskd.bw = 1;                /* Filter 800 Hz */
00166       if (cid_signalling == 2) {       /* v23 signalling */
00167          cid->fskd.f_mark_idx =  4; /* 1300 Hz */
00168          cid->fskd.f_space_idx = 5; /* 2100 Hz */
00169       } else {                         /* Bell 202 signalling as default */
00170          cid->fskd.f_mark_idx =  2; /* 1200 Hz */
00171          cid->fskd.f_space_idx = 3; /* 2200 Hz */
00172       }
00173       /* cid->fskd.pcola = 0; */       /* No clue */
00174       /* cid->fskd.cont = 0.0; */      /* Digital PLL reset */
00175       /* cid->fskd.x0 = 0.0; */
00176       /* cid->fskd.state = 0; */
00177       cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
00178       /* cid->pos = 0; */
00179 #endif
00180    }
00181 
00182    return cid;
00183 }

static void gen_tone ( unsigned char *  buf,
int  len,
format_t  codec,
float  ddr1,
float  ddi1,
float *  cr1,
float *  ci1 
) [inline, static]

Definition at line 96 of file callerid.c.

References AST_LIN2X.

Referenced by ast_gen_cas().

00097 {
00098    int x;
00099    float t;
00100    for (x = 0; x < len; x++) {
00101       t = *cr1 * ddr1 - *ci1 * ddi1;
00102       *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00103       *cr1 = t;
00104       t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00105       *cr1 *= t;
00106       *ci1 *= t;  
00107       buf[x] = AST_LIN2X(*cr1 * 8192.0);
00108    }
00109 }

static void gen_tones ( unsigned char *  buf,
int  len,
format_t  codec,
float  ddr1,
float  ddi1,
float  ddr2,
float  ddi2,
float *  cr1,
float *  ci1,
float *  cr2,
float *  ci2 
) [inline, static]

Definition at line 74 of file callerid.c.

References AST_LIN2X.

Referenced by ast_gen_cas().

00075 {
00076    int x;
00077    float t;
00078    for (x = 0; x < len; x++) {
00079       t = *cr1 * ddr1 - *ci1 * ddi1;
00080       *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00081       *cr1 = t;
00082       t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00083       *cr1 *= t;
00084       *ci1 *= t;  
00085 
00086       t = *cr2 * ddr2 - *ci2 * ddi2;
00087       *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
00088       *cr2 = t;
00089       t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
00090       *cr2 *= t;
00091       *ci2 *= t;  
00092       buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
00093    }
00094 }


Variable Documentation

float casdi1

Definition at line 64 of file callerid.c.

float casdi2

Definition at line 64 of file callerid.c.

float casdr1

Definition at line 64 of file callerid.c.

float casdr2

Definition at line 64 of file callerid.c.

float cid_di[4]

Definition at line 61 of file callerid.c.

Referenced by callerid_getcarrier().

float cid_dr[4]

Definition at line 61 of file callerid.c.

Referenced by callerid_getcarrier().

float clidsb = 8000.0 / 1200.0

Definition at line 62 of file callerid.c.

struct ast_value_translation connected_line_source_types[] [static]

Translation table for connected line update source settings.

Definition at line 1249 of file callerid.c.

Referenced by ast_connected_line_source_describe(), ast_connected_line_source_name(), and ast_connected_line_source_parse().

struct ast_value_translation party_name_charset_tbl[] [static]

Translation table for ast_party_name char-set settings.

Definition at line 1300 of file callerid.c.

Referenced by ast_party_name_charset_describe(), ast_party_name_charset_parse(), and ast_party_name_charset_str().

struct ast_value_translation pres_types[] [static]

Translation table for Caller ID Presentation settings.

Definition at line 1114 of file callerid.c.

Referenced by ast_describe_caller_presentation(), ast_named_caller_presentation(), and ast_parse_caller_presentation().

struct ast_value_translation redirecting_reason_types[] [static]

Translation table for redirecting reason settings.

Definition at line 1192 of file callerid.c.

Referenced by ast_redirecting_reason_describe(), ast_redirecting_reason_name(), and ast_redirecting_reason_parse().

float sasdi

Definition at line 63 of file callerid.c.

float sasdr

Definition at line 63 of file callerid.c.


Generated on Sat Mar 10 01:54:47 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7