Wed Oct 28 15:48:23 2009

Asterisk developer's documentation


callerid.c File Reference

CallerID Generation support. More...

#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/logger.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, char *name, char *number, int callwaiting, int codec)
int ast_callerid_callwaiting_generate (unsigned char *buf, char *name, 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, char *name, 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)
 parse string 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_isphonenumber (char *n)
 checks if string consists only of digits and * # and +
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)
 Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
int callerid_feed (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, char *number, 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, char *number, 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 {
   char *   description
   char *   name
   int   val
pres_types []
float sasdi
float sasdr


Detailed Description

CallerID Generation support.

Definition in file callerid.c.


Define Documentation

#define AST_CALLERID_UNKNOWN   "<unknown>"

Definition at line 73 of file callerid.c.

#define CALLERID_MARK   1200.0

1200 hz for "1"

Definition at line 68 of file callerid.c.

Referenced by callerid_init().

#define CALLERID_SPACE   2200.0

2200 hz for "0"

Definition at line 67 of file callerid.c.

Referenced by callerid_init().

#define CAS_FREQ1   2130.0

Definition at line 70 of file callerid.c.

Referenced by callerid_init().

#define CAS_FREQ2   2750.0

Definition at line 71 of file callerid.c.

Referenced by callerid_init().

#define SAS_FREQ   440.0

Definition at line 69 of file callerid.c.

Referenced by callerid_init().


Function Documentation

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

Definition at line 688 of file callerid.c.

References ast_strlen_zero(), and callerid_generate().

Referenced by ast_callerid_callwaiting_generate(), and ast_callerid_generate().

00689 {
00690    if (ast_strlen_zero(name))
00691       name = NULL;
00692    if (ast_strlen_zero(number))
00693       number = NULL;
00694    return callerid_generate(buf, number, name, 0, callwaiting, codec);
00695 }

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

References __ast_callerid_generate().

Referenced by send_cwcidspill().

00703 {
00704    return __ast_callerid_generate(buf, name, number, 1, codec);
00705 }

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

References __ast_callerid_generate().

Referenced by zt_call().

00698 {
00699    return __ast_callerid_generate(buf, name, number, 0, codec);
00700 }

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

Definition at line 707 of file callerid.c.

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

00708 {
00709    if (!unknown)
00710       unknown = "<unknown>";
00711    if (name && num)
00712       snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
00713    else if (name) 
00714       ast_copy_string(buf, name, bufsiz);
00715    else if (num)
00716       ast_copy_string(buf, num, bufsiz);
00717    else
00718       ast_copy_string(buf, unknown, bufsiz);
00719    return buf;
00720 }

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

parse string 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:
returns -1 on failure, otherwise 0

Definition at line 641 of file callerid.c.

References ast_isphonenumber(), ast_shrink_phone_number(), and ast_strlen_zero().

Referenced by action_originate(), adsi_message(), advanced_options(), ast_callerid_split(), ast_osp_lookup(), ast_osp_validate(), ast_privacy_check(), ast_privacy_set(), handle_setcallerid(), misdn_new(), play_message_callerid(), rpt_call(), rpt_exec(), setrdnis_exec(), and write_metadata().

00642 {
00643    char *ns, *ne;
00644    char *ls, *le;
00645    char tmp[256];
00646    /* Try for "name" <location> format or 
00647       name <location> format */
00648    if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
00649       /* Found the location */
00650       *le = '\0';
00651       *ls = '\0';
00652       *location = ls + 1;
00653       if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) {
00654          /* Get name out of quotes */
00655          *ns = '\0';
00656          *ne = '\0';
00657          *name = ns + 1;
00658          return 0;
00659       } else {
00660          /* Just trim off any trailing spaces */
00661          *name = instr;
00662          while(!ast_strlen_zero(instr) && (instr[strlen(instr) - 1] < 33))
00663             instr[strlen(instr) - 1] = '\0';
00664          /* And leading spaces */
00665          *name = ast_skip_blanks(*name);
00666          return 0;
00667       }
00668    } else {
00669       ast_copy_string(tmp, instr, sizeof(tmp));
00670       ast_shrink_phone_number(tmp);
00671       if (ast_isphonenumber(tmp)) {
00672          /* Assume it's just a location */
00673          *name = NULL;
00674          *location = instr;
00675       } else {
00676          /* Assume it's just a name.  Make sure it's not quoted though */
00677          *name = instr;
00678          while(*(*name) && ((*(*name) < 33) || (*(*name) == '\"'))) (*name)++;
00679          ne = *name + strlen(*name) - 1;
00680          while((ne > *name) && ((*ne < 33) || (*ne == '\"'))) { *ne = '\0'; ne--; }
00681          *location = NULL;
00682       }
00683       return 0;
00684    }
00685    return -1;
00686 }

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

Definition at line 722 of file callerid.c.

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

Referenced by apply_outgoing(), build_device(), build_gateway(), build_peer(), build_user(), callerid_write(), disa_exec(), load_module(), monitor_handle_notowned(), setcallerid_exec(), setup_zap(), and vpb_new().

00723 {
00724    char *tmp;
00725    char *l = NULL, *n = NULL;
00726    tmp = ast_strdupa(buf);
00727    if (!tmp) {
00728       name[0] = '\0';
00729       num[0] = '\0';
00730       return -1;
00731    }
00732    ast_callerid_parse(tmp, &n, &l);
00733    if (n)
00734       ast_copy_string(name, n, namelen);
00735    else
00736       name[0] = '\0';
00737    if (l) {
00738       ast_shrink_phone_number(l);
00739       ast_copy_string(num, l, numlen);
00740    } else
00741       num[0] = '\0';
00742    return 0;
00743 }

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

References pres_types.

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

00783 {
00784    int i;
00785 
00786    for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
00787       if (pres_types[i].val == data)
00788          return pres_types[i].description;
00789    }
00790 
00791    return "unknown";
00792 }

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

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

Referenced by __adsi_transmit_messages(), and zt_callwait().

00234 {
00235    int pos = 0;
00236    int saslen=2400;
00237    float cr1 = 1.0;
00238    float ci1 = 0.0;
00239    float cr2 = 1.0;
00240    float ci2 = 0.0;
00241    if (sendsas) {
00242       if (len < saslen)
00243          return -1;
00244       gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
00245       len -= saslen;
00246       pos += saslen;
00247       cr2 = cr1;
00248       ci2 = ci1;
00249    }
00250    gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
00251    return 0;
00252 }

int ast_isphonenumber ( char *  n  ) 

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

Check if a string consists only of digits.

Returns:
1 if string is valid AST phone number

0 if not

Definition at line 627 of file callerid.c.

References ast_strlen_zero().

Referenced by ast_callerid_parse(), ast_osp_lookup(), and ast_osp_validate().

00628 {
00629    int x;
00630    if (ast_strlen_zero(n))
00631       return 0;
00632    for (x=0;n[x];x++)
00633       if (!strchr("0123456789*#+", n[x]))
00634          return 0;
00635    return 1;
00636 }

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

References name, and pres_types.

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

00767 {
00768    int i;
00769 
00770    for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
00771       if (!strcasecmp(pres_types[i].name, data))
00772          return pres_types[i].val;
00773    }
00774 
00775    return -1;
00776 }

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...

Parameters:
n The number to be stripped/shrunk
Returns:
Returns nothing important

Definition at line 593 of file callerid.c.

Referenced by action_originate(), ast_callerid_parse(), ast_callerid_split(), ast_osp_lookup(), ast_osp_validate(), ast_privacy_check(), ast_privacy_set(), check_access(), check_user_full(), dial_exec_full(), get_callerid_ast(), handle_setcallerid(), pbx_load_module(), rpt_exec(), setrdnis_exec(), ss_thread(), and write_metadata().

00594 {
00595    int x,y=0;
00596    int bracketed=0;
00597    for (x=0;n[x];x++) {
00598       switch(n[x]) {
00599       case '[':
00600          bracketed++;
00601          n[y++] = n[x];
00602          break;
00603       case ']':
00604          bracketed--;
00605          n[y++] = n[x];
00606          break;
00607       case '-':
00608          if (bracketed)
00609             n[y++] = n[x];
00610          break;
00611       case '.':
00612          if (!n[x+1])
00613             n[y++] = n[x];
00614          break;
00615       default:
00616          if (!strchr("( )", n[x]))
00617             n[y++] = n[x];
00618       }
00619    }
00620    n[y] = '\0';
00621 }

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

References ast_log(), ast_strlen_zero(), AST_XLAW, CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, callerid_state::cksum, callerid_state::flags, free, fsk_serie(), callerid_state::fskd, callerid_state::len, LOG_ERROR, LOG_NOTICE, LOG_WARNING, malloc, 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 get_callerid_ast(), and ss_thread().

00255 {
00256    int mylen = len;
00257    int olen;
00258    int b = 'X';
00259    int res;
00260    int x;
00261    short *buf = malloc(2 * len + cid->oldlen);
00262    short *obuf = buf;
00263    if (!buf) {
00264       ast_log(LOG_WARNING, "Out of memory\n");
00265       return -1;
00266    }
00267    memset(buf, 0, 2 * len + cid->oldlen);
00268    memcpy(buf, cid->oldstuff, cid->oldlen);
00269    mylen += cid->oldlen/2;
00270    for (x=0;x<len;x++) 
00271       buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
00272    while(mylen >= 160) {
00273       olen = mylen;
00274       res = fsk_serie(&cid->fskd, buf, &mylen, &b);
00275       if (mylen < 0) {
00276          ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
00277          free(obuf);
00278          return -1;
00279       }
00280       buf += (olen - mylen);
00281       if (res < 0) {
00282          ast_log(LOG_NOTICE, "fsk_serie failed\n");
00283          free(obuf);
00284          return -1;
00285       }
00286       if (res == 1) {
00287          /* Ignore invalid bytes */
00288          if (b > 0xff)
00289             continue;
00290          switch(cid->sawflag) {
00291          case 0: /* Look for flag */
00292             if (b == 'U')
00293                cid->sawflag = 2;
00294             break;
00295          case 2: /* Get lead-in */
00296             if ((b == 0x04) || (b == 0x80)) {
00297                cid->type = b;
00298                cid->sawflag = 3;
00299                cid->cksum = b;
00300             }
00301             break;
00302          case 3:  /* Get length */
00303             /* Not a lead in.  We're ready  */
00304             cid->sawflag = 4;
00305             cid->len = b;
00306             cid->pos = 0;
00307             cid->cksum += b;
00308             break;
00309          case 4: /* Retrieve message */
00310             if (cid->pos >= 128) {
00311                ast_log(LOG_WARNING, "Caller ID too long???\n");
00312                free(obuf);
00313                return -1;
00314             }
00315             cid->rawdata[cid->pos++] = b;
00316             cid->len--;
00317             cid->cksum += b;
00318             if (!cid->len) {
00319                cid->rawdata[cid->pos] = '\0';
00320                cid->sawflag = 5;
00321             }
00322             break;
00323          case 5: /* Check checksum */
00324             if (b != (256 - (cid->cksum & 0xff))) {
00325                ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
00326                /* Try again */
00327                cid->sawflag = 0;
00328                break;
00329             }
00330       
00331             cid->number[0] = '\0';
00332             cid->name[0] = '\0';
00333             /* If we get this far we're fine.  */
00334             if (cid->type == 0x80) {
00335                /* MDMF */
00336                /* Go through each element and process */
00337                for (x=0;x< cid->pos;) {
00338                   switch(cid->rawdata[x++]) {
00339                   case 1:
00340                      /* Date */
00341                      break;
00342                   case 2: /* Number */
00343                   case 3: /* Number (for Zebble) */
00344                   case 4: /* Number */
00345                      res = cid->rawdata[x];
00346                      if (res > 32) {
00347                         ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
00348                         res = 32; 
00349                      }
00350                      if (ast_strlen_zero(cid->number)) {
00351                         memcpy(cid->number, cid->rawdata + x + 1, res);
00352                         /* Null terminate */
00353                         cid->number[res] = '\0';
00354                      }
00355                      break;
00356                   case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
00357                      break;
00358                   case 7: /* Name */
00359                   case 8: /* Name */
00360                      res = cid->rawdata[x];
00361                      if (res > 32) {
00362                         ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
00363                         res = 32; 
00364                      }
00365                      memcpy(cid->name, cid->rawdata + x + 1, res);
00366                      cid->name[res] = '\0';
00367                      break;
00368                   case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
00369                   case 19: /* UK: Network message system status (Number of messages waiting) */
00370                   case 22: /* Something French */
00371                      break;
00372                   default:
00373                      ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
00374                   }
00375                   x += cid->rawdata[x];
00376                   x++;
00377                }
00378             } else {
00379                /* SDMF */
00380                ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
00381             }
00382             /* Update flags */
00383             cid->flags = 0;
00384             if (!strcmp(cid->number, "P")) {
00385                strcpy(cid->number, "");
00386                cid->flags |= CID_PRIVATE_NUMBER;
00387             } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
00388                strcpy(cid->number, "");
00389                cid->flags |= CID_UNKNOWN_NUMBER;
00390             }
00391             if (!strcmp(cid->name, "P")) {
00392                strcpy(cid->name, "");
00393                cid->flags |= CID_PRIVATE_NAME;
00394             } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
00395                strcpy(cid->name, "");
00396                cid->flags |= CID_UNKNOWN_NAME;
00397             }
00398             free(obuf);
00399             return 1;
00400             break;
00401          default:
00402             ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
00403          }
00404       }
00405    }
00406    if (mylen) {
00407       memcpy(cid->oldstuff, buf, mylen * 2);
00408       cid->oldlen = mylen * 2;
00409    } else
00410       cid->oldlen = 0;
00411    free(obuf);
00412    return 0;
00413 }

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

References free.

Referenced by get_callerid_ast(), and ss_thread().

00416 {
00417    free(cid);
00418 }

int callerid_generate ( unsigned char *  buf,
char *  number,
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 551 of file callerid.c.

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

Referenced by __ast_callerid_generate().

00552 {
00553    int bytes=0;
00554    int x, sum;
00555    int len;
00556    /* Initial carriers (real/imaginary) */
00557    float cr = 1.0;
00558    float ci = 0.0;
00559    float scont = 0.0;
00560    char msg[256];
00561    len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
00562    if (!callwaiting) {
00563       /* Wait a half a second */
00564       for (x=0;x<4000;x++)
00565          PUT_BYTE(0x7f);
00566       /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00567       for (x=0;x<30;x++)
00568          PUT_CLID(0x55);
00569    }
00570    /* Send 150ms of callerid marks */
00571    for (x=0;x<150;x++)
00572       PUT_CLID_MARKMS;
00573    /* Send 0x80 indicating MDMF format */
00574    PUT_CLID(0x80);
00575    /* Put length of whole message */
00576    PUT_CLID(len);
00577    sum = 0x80 + strlen(msg);
00578    /* Put each character of message and update checksum */
00579    for (x=0;x<len; x++) {
00580       PUT_CLID(msg[x]);
00581       sum += msg[x];
00582    }
00583    /* Send 2's compliment of sum */
00584    PUT_CLID(256 - (sum & 255));
00585 
00586    /* Send 50 more ms of marks */
00587    for (x=0;x<50;x++)
00588       PUT_CLID_MARKMS;
00589    
00590    return bytes;
00591 }

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

Definition at line 420 of file callerid.c.

References ast_strlen_zero(), CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, and t.

Referenced by callerid_generate().

00421 {
00422    time_t t;
00423    struct tm tm;
00424    char *ptr;
00425    int res;
00426    int i,x;
00427    /* Get the time */
00428    time(&t);
00429    localtime_r(&t,&tm);
00430    
00431    ptr = msg;
00432    
00433    /* Format time and message header */
00434    res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
00435             tm.tm_mday, tm.tm_hour, tm.tm_min);
00436    size -= res;
00437    ptr += res;
00438    if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
00439       /* Indicate number not known */
00440       res = snprintf(ptr, size, "\004\001O");
00441       size -= res;
00442       ptr += res;
00443    } else if (flags & CID_PRIVATE_NUMBER) {
00444       /* Indicate number is private */
00445       res = snprintf(ptr, size, "\004\001P");
00446       size -= res;
00447       ptr += res;
00448    } else {
00449       /* Send up to 16 digits of number MAX */
00450       i = strlen(number);
00451       if (i > 16) i = 16;
00452       res = snprintf(ptr, size, "\002%c", i);
00453       size -= res;
00454       ptr += res;
00455       for (x=0;x<i;x++)
00456          ptr[x] = number[x];
00457       ptr[i] = '\0';
00458       ptr += i;
00459       size -= i;
00460    }
00461 
00462    if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
00463       /* Indicate name not known */
00464       res = snprintf(ptr, size, "\010\001O");
00465       size -= res;
00466       ptr += res;
00467    } else if (flags & CID_PRIVATE_NAME) {
00468       /* Indicate name is private */
00469       res = snprintf(ptr, size, "\010\001P");
00470       size -= res;
00471       ptr += res;
00472    } else {
00473       /* Send up to 16 digits of name MAX */
00474       i = strlen(name);
00475       if (i > 16) i = 16;
00476       res = snprintf(ptr, size, "\007%c", i);
00477       size -= res;
00478       ptr += res;
00479       for (x=0;x<i;x++)
00480          ptr[x] = name[x];
00481       ptr[i] = '\0';
00482       ptr += i;
00483       size -= i;
00484    }
00485    return (ptr - msg);
00486    
00487 }

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

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

Referenced by get_callerid_ast(), and ss_thread().

00160 {
00161    *flags = cid->flags;
00162    if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER))
00163       *name = NULL;
00164    else
00165       *name = cid->name;
00166    if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
00167       *number = NULL;
00168    else
00169       *number = cid->number;
00170 }

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

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

Referenced by ss_thread().

00173 {
00174    int i;
00175    int code;
00176 
00177    /* "Clear" the number-buffer. */
00178    number[0] = 0;
00179 
00180    if (strlen(cidstring) < 2) {
00181       ast_log(LOG_DEBUG, "No cid detected\n");
00182       *flags = CID_UNKNOWN_NUMBER;
00183       return;
00184    }
00185    
00186    /* Detect protocol and special types */
00187    if (cidstring[0] == 'B') {
00188       /* Handle special codes */
00189       code = atoi(&cidstring[1]);
00190       if (code == 0)
00191          *flags = CID_UNKNOWN_NUMBER;
00192       else if (code == 10) 
00193          *flags = CID_PRIVATE_NUMBER;
00194       else
00195          ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code);
00196    } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
00197       /* .DK special code */
00198       if (cidstring[1] == '1')
00199          *flags = CID_PRIVATE_NUMBER;
00200       if (cidstring[1] == '2' || cidstring[1] == '3')
00201          *flags = CID_UNKNOWN_NUMBER;
00202    } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
00203       /* "Standard" callerid */
00204       for (i = 1; i < strlen(cidstring); i++ ) {
00205          if (cidstring[i] == 'C' || cidstring[i] == '#')
00206             break;
00207          if (isdigit(cidstring[i]))
00208             number[i-1] = cidstring[i];
00209          else
00210             ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n",
00211                cidstring[i]);
00212       }
00213       number[i-1] = 0;
00214    } else if (isdigit(cidstring[0])) {
00215       /* It begins with a digit, so we parse it as a number and hope
00216        * for the best */
00217       ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
00218          "parsing might be unreliable\n");
00219       for (i = 0; i < strlen(cidstring); i++) {
00220          if (isdigit(cidstring[i]))
00221                                 number[i] = cidstring[i];
00222          else
00223             break;
00224       }
00225       number[i] = 0;
00226    } else {
00227       ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n", 
00228          cidstring[0]);
00229       *flags = CID_UNKNOWN_NUMBER;
00230    }
00231 }

void callerid_init ( void   ) 

Initialize stuff for inverse FFT.

CallerID Initialization.

Definition at line 113 of file callerid.c.

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

Referenced by main().

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

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

References ast_log(), fsk_data::bw, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, fsk_data::cont, fsk_data::f_mark_idx, fsk_data::f_space_idx, callerid_state::flags, callerid_state::fskd, fsk_data::hdlc, LOG_WARNING, malloc, callerid_state::name, fsk_data::nbit, fsk_data::nstop, callerid_state::number, fsk_data::paridad, fsk_data::pcola, callerid_state::pos, fsk_data::spb, fsk_data::state, and fsk_data::x0.

Referenced by get_callerid_ast(), and ss_thread().

00128 {
00129    struct callerid_state *cid;
00130    cid = malloc(sizeof(struct callerid_state));
00131    if (cid) {
00132       memset(cid, 0, sizeof(struct callerid_state));
00133       cid->fskd.spb = 7;      /* 1200 baud */
00134       cid->fskd.hdlc = 0;     /* Async */
00135       cid->fskd.nbit = 8;     /* 8 bits */
00136       cid->fskd.nstop = 1; /* 1 stop bit */
00137       cid->fskd.paridad = 0;  /* No parity */
00138       cid->fskd.bw=1;         /* Filter 800 Hz */
00139       if (cid_signalling == 2) { /* v23 signalling */
00140          cid->fskd.f_mark_idx =  4; /* 1300 Hz */
00141          cid->fskd.f_space_idx = 5; /* 2100 Hz */
00142       } else { /* Bell 202 signalling as default */ 
00143          cid->fskd.f_mark_idx =  2; /* 1200 Hz */
00144          cid->fskd.f_space_idx = 3; /* 2200 Hz */
00145       }
00146       cid->fskd.pcola = 0;    /* No clue */
00147       cid->fskd.cont = 0;        /* Digital PLL reset */
00148       cid->fskd.x0 = 0.0;
00149       cid->fskd.state = 0;
00150       memset(cid->name, 0, sizeof(cid->name));
00151       memset(cid->number, 0, sizeof(cid->number));
00152       cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
00153       cid->pos = 0;
00154    } else
00155       ast_log(LOG_WARNING, "Out of memory\n");
00156    return cid;
00157 }

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

Definition at line 97 of file callerid.c.

References AST_LIN2X, and t.

Referenced by ast_gen_cas().

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

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

References AST_LIN2X, and t.

Referenced by ast_gen_cas().

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

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

Generate message waiting indicator (stutter tone).

Definition at line 489 of file callerid.c.

References PUT_BYTE, PUT_CLID, and PUT_CLID_MARKMS.

Referenced by do_monitor().

00490 {
00491    unsigned char msg[256];
00492    int len=0;
00493    int sum;
00494    int x;
00495    int bytes = 0;
00496    float cr = 1.0;
00497    float ci = 0.0;
00498    float scont = 0.0;
00499    if (mdmf) {
00500       /* MDMF Message waiting */
00501       msg[len++] = 0x82;
00502       /* Length is 3 */
00503       msg[len++] = 3;
00504       /* IE is "Message Waiting Parameter" */
00505       msg[len++] = 0xb;
00506       /* Length of IE is one */
00507       msg[len++] = 1;
00508       /* Active or not */
00509       if (active)
00510          msg[len++] = 0xff;
00511       else
00512          msg[len++] = 0x00;
00513    } else {
00514       /* SDMF Message waiting */
00515       msg[len++] = 0x6;
00516       /* Length is 3 */
00517       msg[len++] = 3;
00518       if (active) {
00519          msg[len++] = 0x42;
00520          msg[len++] = 0x42;
00521          msg[len++] = 0x42;
00522       } else {
00523          msg[len++] = 0x6f;
00524          msg[len++] = 0x6f;
00525          msg[len++] = 0x6f;
00526       }
00527    }
00528    sum = 0;
00529    for (x=0;x<len;x++)
00530       sum += msg[x];
00531    sum = (256 - (sum & 255));
00532    msg[len++] = sum;
00533    /* Wait a half a second */
00534    for (x=0;x<4000;x++)
00535       PUT_BYTE(0x7f);
00536    /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00537    for (x=0;x<30;x++)
00538       PUT_CLID(0x55);
00539    /* Send 170ms of callerid marks */
00540    for (x=0;x<170;x++)
00541       PUT_CLID_MARKMS;
00542    for (x=0;x<len;x++) {
00543       PUT_CLID(msg[x]);
00544    }
00545    /* Send 50 more ms of marks */
00546    for (x=0;x<50;x++)
00547       PUT_CLID_MARKMS;
00548    return bytes;
00549 }


Variable Documentation

float casdi1

Definition at line 65 of file callerid.c.

float casdi2

Definition at line 65 of file callerid.c.

float casdr1

Definition at line 65 of file callerid.c.

float casdr2

Definition at line 65 of file callerid.c.

float cid_di[4]

Definition at line 62 of file callerid.c.

Referenced by callerid_getcarrier().

float cid_dr[4]

Definition at line 62 of file callerid.c.

Referenced by callerid_getcarrier().

float clidsb = 8000.0 / 1200.0

Definition at line 63 of file callerid.c.

char* description

Definition at line 748 of file callerid.c.

Referenced by handle_show_application(), handle_show_function(), and load_pbx().

char* name

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

float sasdi

Definition at line 64 of file callerid.c.

float sasdr

Definition at line 64 of file callerid.c.

int val

Definition at line 746 of file callerid.c.


Generated on Wed Oct 28 15:48:23 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6