Wed Oct 28 11:45:51 2009

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"

Include dependency graph for callerid.c:

Go to the source code of this file.

Data Structures

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, int codec)
int ast_callerid_callwaiting_generate (unsigned char *buf, const char *name, const char *number, int codec)
 Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) See ast_callerid_generate() for other details.
int ast_callerid_generate (unsigned char *buf, const char *name, const char *number, int 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 instr for caller id information.
int ast_callerid_split (const char *buf, char *name, int namelen, char *num, int numlen)
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, int codec)
int ast_is_shrinkable_phonenumber (const char *exten)
 checks if string consists only of digits and ( ) - * # and + Pre-qualifies the string for 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)
 checks if string consists only of digits and * # 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.
void ast_shrink_phone_number (char *n)
 Clean up phone string remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets. Basically, remove anything that could be invalid in a pattern.
static unsigned short calc_crc (unsigned short crc, unsigned char data)
int callerid_feed (struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
 Read samples into the state machine.
int callerid_feed_jp (struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
 Read samples into the state machine.
void callerid_free (struct callerid_state *cid)
 Free a callerID state.
int callerid_generate (unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int 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)
void callerid_init (void)
 Initialize stuff for inverse FFT.
struct callerid_statecallerid_new (int cid_signalling)
 Create a callerID state machine.
static void gen_tone (unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
static void gen_tones (unsigned char *buf, int len, int codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
int vmwi_generate (unsigned char *buf, int active, int mdmf, int codec)
 Generate message waiting indicator (stutter tone).

Variables

float casdi1
float casdi2
float casdr1
float casdr2
float cid_di [4]
float cid_dr [4]
float clidsb = 8000.0 / 1200.0
struct {
   const char *   description
   const char *   name
   int   val
pres_types []
 Translation table for Caller ID Presentation 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,
int  codec 
) [static]

Definition at line 1028 of file callerid.c.

References ast_strlen_zero(), and callerid_generate().

Referenced by ast_callerid_callwaiting_generate(), and ast_callerid_generate().

01029 {
01030    if (ast_strlen_zero(name))
01031       name = NULL;
01032    if (ast_strlen_zero(number))
01033       number = NULL;
01034    return callerid_generate(buf, number, name, 0, callwaiting, codec);
01035 }

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

Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) See ast_callerid_generate() for other details.

Definition at line 1042 of file callerid.c.

References __ast_callerid_generate().

Referenced by send_cwcidspill().

01043 {
01044    return __ast_callerid_generate(buf, name, number, 1, codec);
01045 }

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

References __ast_callerid_generate().

Referenced by dahdi_call().

01038 {
01039    return __ast_callerid_generate(buf, name, number, 0, codec);
01040 }

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

Definition at line 1047 of file callerid.c.

References ast_copy_string().

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

01048 {
01049    if (!unknown)
01050       unknown = "<unknown>";
01051    if (name && num)
01052       snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
01053    else if (name) 
01054       ast_copy_string(buf, name, bufsiz);
01055    else if (num)
01056       ast_copy_string(buf, num, bufsiz);
01057    else
01058       ast_copy_string(buf, unknown, bufsiz);
01059    return buf;
01060 }

int ast_callerid_parse ( char *  instr,
char **  name,
char **  location 
)

Destructively parse instr for caller id information.

Destructively parse inbuf into name and location (or number) Parses callerid stream from inbuf and changes into useable form, outputed in name and location.

Returns:
always returns 0, as the code always returns something.
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.

Definition at line 981 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(), adsi_message(), advanced_options(), ast_callerid_split(), ast_privacy_check(), ast_privacy_set(), handle_setcallerid(), misdn_new(), play_message_callerid(), rpt_call(), unistim_new(), and write_metadata().

00982 {
00983    char *ns, *ne, *ls, *le;
00984 
00985    /* Try "name" <location> format or name <location> format */
00986    if ((ls = strrchr(instr, '<')) && (le = strrchr(ls, '>'))) {
00987       *ls = *le = '\0'; /* location found, trim off the brackets */
00988       *location = ls + 1;  /* and this is the result */
00989       if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
00990          *ns = *ne = '\0'; /* trim off the quotes */
00991          *name = ns + 1;      /* and this is the name */
00992       } else if (ns) {
00993          /* An opening quote was found but no closing quote was. The closing
00994           * quote may actually be after the end of the bracketed number
00995           */
00996          if (strchr(le + 1, '\"')) {
00997             *ns = '\0';
00998             *name = ns + 1;
00999             ast_trim_blanks(*name);
01000          }
01001       } else { /* no quotes, trim off leading and trailing spaces */
01002          *name = ast_skip_blanks(instr);
01003          ast_trim_blanks(*name);
01004       }
01005    } else { /* no valid brackets */
01006       char tmp[256];
01007 
01008       ast_copy_string(tmp, instr, sizeof(tmp));
01009       ast_shrink_phone_number(tmp);
01010       if (ast_isphonenumber(tmp)) { /* Assume it's just a location */
01011          *name = NULL;
01012          strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
01013          *location = instr;
01014       } else { /* Assume it's just a name. */
01015          *location = NULL;
01016          if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
01017             *ns = *ne = '\0'; /* trim off the quotes */
01018             *name = ns + 1;      /* and this is the name */
01019          } else { /* no quotes, trim off leading and trailing spaces */
01020             *name = ast_skip_blanks(instr);
01021             ast_trim_blanks(*name);
01022          }
01023       }
01024    }
01025    return 0;
01026 }

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

Definition at line 1062 of file callerid.c.

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

Referenced by apply_outgoing(), build_device(), build_gateway(), build_peer(), build_user(), callerid_read(), callerid_write(), disa_exec(), load_module(), prep_email_sub_vars(), process_dahdi(), store_callerid(), and update_common_options().

01063 {
01064    char *tmp;
01065    char *l = NULL, *n = NULL;
01066 
01067    tmp = ast_strdupa(buf);
01068    ast_callerid_parse(tmp, &n, &l);
01069    if (n)
01070       ast_copy_string(name, n, namelen);
01071    else
01072       name[0] = '\0';
01073    if (l) {
01074       ast_shrink_phone_number(l);
01075       ast_copy_string(num, l, numlen);
01076    } else
01077       num[0] = '\0';
01078    return 0;
01079 }

const char* ast_describe_caller_presentation ( int  data  ) 

Convert caller ID pres value to explanatory string.

Parameters:
data value (see callerid.h AST_PRES_ )
Returns:
string for human presentation

Definition at line 1122 of file callerid.c.

References ARRAY_LEN, and pres_types.

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

01123 {
01124    int i;
01125 
01126    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01127       if (pres_types[i].val == data)
01128          return pres_types[i].description;
01129    }
01130 
01131    return "unknown";
01132 }

int ast_gen_cas ( unsigned char *  outbuf,
int  sas,
int  len,
int  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(), and dahdi_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  ) 

checks if string consists only of digits and ( ) - * # and + Pre-qualifies the string for ast_shrink_phone_number()

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

Returns:
1 if string is valid AST shrinkable phone number

0 if not

Definition at line 967 of file callerid.c.

References ast_is_valid_string().

Referenced by check_peer_ok(), check_user_full(), check_user_ok(), and replace_cid().

00968 {
00969    return ast_is_valid_string(exten, "0123456789*#+()-.");
00970 }

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
Returns:
1 if valid string, 0 if string contains invalid characters

Definition at line 941 of file callerid.c.

References ast_strlen_zero().

Referenced by ast_is_shrinkable_phonenumber(), and ast_isphonenumber().

00942 {
00943    int x;
00944 
00945    if (ast_strlen_zero(exten))
00946       return 0;
00947    for (x = 0; exten[x]; x++)
00948       if (!strchr(valid, exten[x]))
00949          return 0;
00950    return 1;
00951 }

int ast_isphonenumber ( const char *  n  ) 

checks if string consists only of digits and * # and +

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

Returns:
1 if string is valid AST phone number

0 if not

Definition at line 957 of file callerid.c.

References ast_is_valid_string().

Referenced by ast_callerid_parse().

00958 {
00959    return ast_is_valid_string(n, "0123456789*#+");
00960 }

const char* ast_named_caller_presentation ( int  data  ) 

Convert caller ID pres value to text code.

Parameters:
data text string
Returns:
string for config file

Definition at line 1138 of file callerid.c.

References ARRAY_LEN, and pres_types.

Referenced by callerid_read(), and callerpres_read().

01139 {
01140    int i;
01141 
01142    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01143       if (pres_types[i].val == data)
01144          return pres_types[i].name;
01145    }
01146 
01147    return "unknown";
01148 }

int ast_parse_caller_presentation ( const char *  data  ) 

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

Parameters:
data text string
Returns:
value AST_PRES_ from callerid.h

Definition at line 1103 of file callerid.c.

References ARRAY_LEN, name, and pres_types.

Referenced by build_peer(), build_user(), callerid_write(), callerpres_write(), and setcallerid_pres_exec().

01104 {
01105    int i;
01106    if (!data) {
01107       return -1;
01108    }
01109 
01110    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01111       if (!strcasecmp(pres_types[i].name, data))
01112          return pres_types[i].val;
01113    }
01114 
01115    return -1;
01116 }

void ast_shrink_phone_number ( char *  n  ) 

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

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

Definition at line 904 of file callerid.c.

Referenced by action_originate(), ast_callerid_parse(), ast_callerid_split(), ast_privacy_check(), ast_privacy_set(), check_access(), check_peer_ok(), check_user_full(), check_user_ok(), handle_setcallerid(), pbx_load_config(), replace_cid(), setup_privacy_args(), ss_thread(), and write_metadata().

00905 {
00906    int x, y = 0;
00907    int bracketed = 0;
00908 
00909    for (x = 0; n[x]; x++) {
00910       switch (n[x]) {
00911       case '[':
00912          bracketed++;
00913          n[y++] = n[x];
00914          break;
00915       case ']':
00916          bracketed--;
00917          n[y++] = n[x];
00918          break;
00919       case '-':
00920          if (bracketed)
00921             n[y++] = n[x];
00922          break;
00923       case '.':
00924          if (!n[x+1])
00925             n[y++] = n[x];
00926          break;
00927       default:
00928          /* ignore parenthesis and whitespace */
00929          if (!strchr("( )", n[x]))
00930             n[y++] = n[x];
00931       }
00932    }
00933    n[y] = '\0';
00934 }

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,
int  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.
Returns:
Returns -1 on error, 0 for "needs more samples", and 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, buf, 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 mwi_thread(), and ss_thread().

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

int callerid_feed_jp ( struct callerid_state cid,
unsigned char *  ubuf,
int  samples,
int  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).
Returns:
Returns -1 on error, 0 for "needs more samples", and 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, buf, 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 ss_thread().

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  ) 

Free a callerID state.

Parameters:
cid This is the callerid_state state machine to free This function frees callerid_state cid.

Definition at line 718 of file callerid.c.

References ast_free.

Referenced by mwi_thread(), and ss_thread().

00719 {
00720    ast_free(cid);
00721 }

int callerid_generate ( unsigned char *  buf,
const char *  number,
const char *  name,
int  flags,
int  callwaiting,
int  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 857 of file callerid.c.

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

Referenced by __ast_callerid_generate().

00858 {
00859    int bytes = 0;
00860    int x, sum;
00861    int len;
00862 
00863    /* Initial carriers (real/imaginary) */
00864    float cr = 1.0;
00865    float ci = 0.0;
00866    float scont = 0.0;
00867    char msg[256];
00868    len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
00869    if (!callwaiting) {
00870       /* Wait a half a second */
00871       for (x = 0; x < 4000; x++)
00872          PUT_BYTE(0x7f);
00873       /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00874       for (x = 0; x < 30; x++)
00875          PUT_CLID(0x55);
00876    }
00877    /* Send 150ms of callerid marks */
00878    for (x = 0; x < 150; x++)
00879       PUT_CLID_MARKMS;
00880    /* Send 0x80 indicating MDMF format */
00881    PUT_CLID(0x80);
00882    /* Put length of whole message */
00883    PUT_CLID(len);
00884    sum = 0x80 + strlen(msg);
00885    /* Put each character of message and update checksum */
00886    for (x = 0; x < len; x++) {
00887       PUT_CLID(msg[x]);
00888       sum += msg[x];
00889    }
00890    /* Send 2's compliment of sum */
00891    PUT_CLID(256 - (sum & 255));
00892 
00893    /* Send 50 more ms of marks */
00894    for (x = 0; x < 50; x++)
00895       PUT_CLID_MARKMS;
00896    
00897    return bytes;
00898 }

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

Definition at line 723 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 callerid_generate().

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

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 mwi_thread(), and ss_thread().

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. This function parses DTMF callerid.

Definition at line 198 of file callerid.c.

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

Referenced by 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   ) 

Initialize stuff for inverse FFT.

CallerID Initialization.

Definition at line 112 of file callerid.c.

References CALLERID_MARK, CALLERID_SPACE, CAS_FREQ1, CAS_FREQ2, cos, 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  )  [read]

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, fsk_data::bw, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, fsk_data::f_mark_idx, fsk_data::f_space_idx, callerid_state::flags, callerid_state::fskd, fskmodem_init(), fsk_data::icont, fsk_data::instop, fsk_data::ispb, fsk_data::nbit, fsk_data::nstop, fsk_data::pllids, fsk_data::pllispb, fsk_data::pllispb2, and fsk_data::spb.

Referenced by mwi_thread(), and ss_thread().

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,
int  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,
int  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 }

int vmwi_generate ( unsigned char *  buf,
int  active,
int  mdmf,
int  codec 
)

Generate message waiting indicator (stutter tone).

Definition at line 794 of file callerid.c.

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

Referenced by do_monitor().

00795 {
00796    unsigned char msg[256];
00797    int len = 0;
00798    int sum;
00799    int x;
00800    int bytes = 0;
00801    float cr = 1.0;
00802    float ci = 0.0;
00803    float scont = 0.0;
00804 
00805    if (mdmf) {
00806       /* MDMF Message waiting */
00807       msg[len++] = 0x82;
00808       /* Length is 3 */
00809       msg[len++] = 3;
00810       /* IE is "Message Waiting Parameter" */
00811       msg[len++] = 0xb;
00812       /* Length of IE is one */
00813       msg[len++] = 1;
00814       /* Active or not */
00815       if (active)
00816          msg[len++] = 0xff;
00817       else
00818          msg[len++] = 0x00;
00819    } else {
00820       /* SDMF Message waiting */
00821       msg[len++] = 0x6;
00822       /* Length is 3 */
00823       msg[len++] = 3;
00824       if (active) {
00825          msg[len++] = 0x42;
00826          msg[len++] = 0x42;
00827          msg[len++] = 0x42;
00828       } else {
00829          msg[len++] = 0x6f;
00830          msg[len++] = 0x6f;
00831          msg[len++] = 0x6f;
00832       }
00833    }
00834    sum = 0;
00835    for (x = 0; x < len; x++)
00836       sum += msg[x];
00837    sum = (256 - (sum & 255));
00838    msg[len++] = sum;
00839    /* Wait a half a second */
00840    for (x = 0; x < 4000; x++)
00841       PUT_BYTE(0x7f);
00842    /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00843    for (x = 0; x < 30; x++)
00844       PUT_CLID(0x55);
00845    /* Send 170ms of callerid marks */
00846    for (x = 0; x < 170; x++)
00847       PUT_CLID_MARKMS;
00848    for (x = 0; x < len; x++) {
00849       PUT_CLID(msg[x]);
00850    }
00851    /* Send 50 more ms of marks */
00852    for (x = 0; x < 50; x++)
00853       PUT_CLID_MARKMS;
00854    return bytes;
00855 }


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.

const char* description

Definition at line 1085 of file callerid.c.

Referenced by jingle_newcall(), and jingle_transmit_invite().

const char* name

Definition at line 1084 of file callerid.c.

Referenced by __ast_channel_alloc_ap(), __iax2_show_peers(), _sip_show_peers(), action_getvar(), action_hangup(), action_originate(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), adsi_load(), adsi_message(), advanced_options(), aji_test(), ast_change_name(), ast_channel_free(), ast_do_masquerade(), ast_dsp_set_call_progress_zone(), ast_getformatname_multiple(), ast_jb_read_conf(), ast_make_file_from_fd(), ast_module_helper(), ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), ast_parse_caller_presentation(), ast_rtp_lookup_mime_multiple(), ast_setstate(), ast_str2tos(), ast_tos2str(), ast_var_name(), callerid_read(), callerid_write(), change_monitor_action(), channel_spy(), config_ldap(), do_pause_or_unpause(), dump_ies(), dump_prov_ies(), entry_cmp_fn(), fac2str(), find_peer(), get_dahdi_channel_locked(), group_cmp_fn(), handle_register_message(), handle_showchan(), httpd_helper_thread(), load_module(), load_rpt_vars(), lua_func_read(), lua_get_variable(), lua_get_variable_value(), lua_set_variable(), lua_set_variable_value(), map_video_codec(), mgcp_new(), misdn_cfg_get_config_string(), misdn_cfg_get_name(), mwi_thread(), oss_call(), oss_request(), parse_cookies(), parse_uri(), phone_request(), phoneprov_callback(), play_message_callerid(), process_echocancel(), process_opcode(), process_returncode(), register_verify(), rpt_call(), rpt_master(), show_config_description(), sip_prepare_socket(), sip_prune_realtime(), softhangup_exec(), ss_thread(), start_monitor_action(), stop_monitor_action(), unistim_new(), unload_module(), update_call_counter(), and update_name().

struct { ... } pres_types[] [static]

Translation table for Caller ID Presentation settings.

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

float sasdi

Definition at line 63 of file callerid.c.

float sasdr

Definition at line 63 of file callerid.c.

int val

Definition at line 1083 of file callerid.c.


Generated on Wed Oct 28 11:45:51 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6