Wed Oct 28 11:51:43 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 type, int codec, const char *name, const char *number, int flags)
 Generate message waiting indicator.

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

References ast_strlen_zero(), and callerid_generate().

Referenced by ast_callerid_callwaiting_generate(), and ast_callerid_generate().

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

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

References __ast_callerid_generate().

Referenced by send_cwcidspill().

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

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

References __ast_callerid_generate().

Referenced by dahdi_call().

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

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

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

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

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 1006 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(), rpt_exec(), unistim_new(), and write_metadata().

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

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

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

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

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

References ARRAY_LEN, and pres_types.

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

01148 {
01149    int i;
01150 
01151    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01152       if (pres_types[i].val == data)
01153          return pres_types[i].description;
01154    }
01155 
01156    return "unknown";
01157 }

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

References ast_is_valid_string().

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

00993 {
00994    return ast_is_valid_string(exten, "0123456789*#+()-.");
00995 }

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

References ast_strlen_zero().

Referenced by ast_is_shrinkable_phonenumber(), and ast_isphonenumber().

00967 {
00968    int x;
00969 
00970    if (ast_strlen_zero(exten))
00971       return 0;
00972    for (x = 0; exten[x]; x++)
00973       if (!strchr(valid, exten[x]))
00974          return 0;
00975    return 1;
00976 }

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

References ast_is_valid_string().

Referenced by ast_callerid_parse().

00983 {
00984    return ast_is_valid_string(n, "0123456789*#+");
00985 }

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

References ARRAY_LEN, and pres_types.

Referenced by callerid_read(), and callerpres_read().

01164 {
01165    int i;
01166 
01167    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01168       if (pres_types[i].val == data)
01169          return pres_types[i].name;
01170    }
01171 
01172    return "unknown";
01173 }

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

References ARRAY_LEN, name, and pres_types.

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

01129 {
01130    int i;
01131    if (!data) {
01132       return -1;
01133    }
01134 
01135    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01136       if (!strcasecmp(pres_types[i].name, data))
01137          return pres_types[i].val;
01138    }
01139 
01140    return -1;
01141 }

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 929 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(), handle_setcallerid(), pbx_load_config(), replace_cid(), rpt_exec(), setup_privacy_args(), ss_thread(), and write_metadata().

00930 {
00931    int x, y = 0;
00932    int bracketed = 0;
00933 
00934    for (x = 0; n[x]; x++) {
00935       switch (n[x]) {
00936       case '[':
00937          bracketed++;
00938          n[y++] = n[x];
00939          break;
00940       case ']':
00941          bracketed--;
00942          n[y++] = n[x];
00943          break;
00944       case '-':
00945          if (bracketed)
00946             n[y++] = n[x];
00947          break;
00948       case '.':
00949          if (!n[x+1])
00950             n[y++] = n[x];
00951          break;
00952       default:
00953          /* ignore parenthesis and whitespace */
00954          if (!strchr("( )", n[x]))
00955             n[y++] = n[x];
00956       }
00957    }
00958    n[y] = '\0';
00959 }

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

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

Referenced by __ast_callerid_generate().

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

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

00724 {
00725    struct timeval now = 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(&now, &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  type,
int  codec,
const char *  name,
const char *  number,
int  flags 
)

Generate message waiting indicator.

Parameters:
active The message indicator state -- either 0 no messages in mailbox or 1 messages in mailbox
type Format of message (any of CID_MWI_TYPE_*)
See also:
callerid_generate() for more info as it use the same encoding
Version:
1.6.1 changed mdmf parameter to type, added name, number and flags for caller id message generation

Definition at line 794 of file callerid.c.

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

Referenced by mwi_send_thread().

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


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

Referenced by jingle_newcall(), and jingle_transmit_invite().

const char* name

Definition at line 1109 of file callerid.c.

Referenced by __ast_channel_alloc_ap(), __iax2_show_peers(), _sip_show_peers(), action_atxfer(), action_getvar(), action_hangup(), action_originate(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), adsi_load(), aji_test(), ast_change_name(), ast_channel_free(), ast_do_masquerade(), ast_dsp_set_call_progress_zone(), ast_event_str_to_event_type(), ast_event_str_to_ie_type(), ast_getformatname_multiple(), ast_jb_read_conf(), 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(), callerid_read(), callerid_write(), change_monitor_action(), channel_spy(), cli_tps_ping(), cli_tps_report(), config_ldap(), do_pause_or_unpause(), dump_ies(), dump_prov_ies(), entry_cmp_fn(), fac2str(), get_dahdi_channel_locked(), group_cmp_fn(), handle_showchan(), handle_tcptls_connection(), 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(), manager_rpt_local_nodes(), manager_rpt_status(), 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(), process_echocancel(), process_opcode(), process_returncode(), register_verify(), rpt_call(), rpt_do_cmd(), rpt_do_dump(), rpt_do_fun(), rpt_do_fun1(), rpt_do_local_nodes(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_manager_do_stats(), rpt_master(), show_config_description(), sip_prepare_socket(), sip_prune_realtime(), softhangup_exec(), ss_thread(), start_monitor_action(), stop_monitor_action(), tps_taskprocessor_tab_complete(), unistim_new(), unload_module(), and update_call_counter().

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


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