Fri Jul 15 2011 11:57:21

Asterisk developer's documentation


callerid.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief CallerID Generation support 
00022  *
00023  * \author Mark Spencer <markster@digium.com> 
00024  */
00025 
00026 #include "asterisk.h"
00027 
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 310635 $")
00029 
00030 #include <time.h>
00031 #include <math.h>
00032 #include <ctype.h>
00033 
00034 #include "asterisk/ulaw.h"
00035 #include "asterisk/alaw.h"
00036 #include "asterisk/frame.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/callerid.h"
00039 #include "asterisk/fskmodem.h"
00040 #include "asterisk/utils.h"
00041 
00042 struct callerid_state {
00043    fsk_data fskd;
00044    char rawdata[256];
00045    short oldstuff[160];
00046    int oldlen;
00047    int pos;
00048    int type;
00049    int cksum;
00050    char name[64];
00051    char number[64];
00052    int flags;
00053    int sawflag;
00054    int len;
00055 
00056    int skipflag; 
00057    unsigned short crc;
00058 };
00059 
00060 
00061 float cid_dr[4], cid_di[4];
00062 float clidsb = 8000.0 / 1200.0;
00063 float sasdr, sasdi;
00064 float casdr1, casdi1, casdr2, casdi2;
00065 
00066 #define CALLERID_SPACE  2200.0      /*!< 2200 hz for "0" */
00067 #define CALLERID_MARK   1200.0      /*!< 1200 hz for "1" */
00068 #define SAS_FREQ      440.0
00069 #define CAS_FREQ1    2130.0
00070 #define CAS_FREQ2    2750.0
00071 
00072 #define AST_CALLERID_UNKNOWN  "<unknown>"
00073 
00074 static inline 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)
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 }
00095 
00096 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
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 }
00110 
00111 /*! \brief Initialize stuff for inverse FFT */
00112 void callerid_init(void)
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 }
00125 
00126 struct callerid_state *callerid_new(int cid_signalling)
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 }
00184 
00185 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
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 }
00197 
00198 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
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 }
00257 
00258 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
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 }
00279 
00280 static unsigned short calc_crc(unsigned short crc, unsigned char data)
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 }
00302 
00303 int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
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 }
00540 
00541 
00542 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
00543 {
00544    int mylen = len;
00545    int olen;
00546    int b = 'X';
00547    int res;
00548    int x;
00549    short *buf;
00550 
00551    buf = alloca(2 * len + cid->oldlen);
00552 
00553    memcpy(buf, cid->oldstuff, cid->oldlen);
00554    mylen += cid->oldlen/2;
00555 
00556    for (x = 0; x < len; x++) 
00557       buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
00558    while (mylen >= 160) {
00559       olen = mylen;
00560       res = fsk_serial(&cid->fskd, buf, &mylen, &b);
00561       if (mylen < 0) {
00562          ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
00563          return -1;
00564       }
00565       buf += (olen - mylen);
00566       if (res < 0) {
00567          ast_log(LOG_NOTICE, "fsk_serial failed\n");
00568          return -1;
00569       }
00570       if (res == 1) {
00571          if (b > 0xff) {
00572             if (cid->sawflag != 5) {
00573                /* Ignore invalid bytes */
00574                continue;
00575             }
00576             /*
00577              * We can tollerate an error on the checksum character since the
00578              * checksum character is the last character in the message and
00579              * it validates the message.
00580              *
00581              * Remove character error flags.
00582              * Bit 8 : Parity error
00583              * Bit 9 : Framing error
00584              */
00585             b &= 0xff;
00586          }
00587          switch (cid->sawflag) {
00588          case 0: /* Look for flag */
00589             if (b == 'U')
00590                cid->sawflag = 2;
00591             break;
00592          case 2: /* Get lead-in */
00593             if ((b == 0x04) || (b == 0x80) || (b == 0x06) || (b == 0x82)) {
00594                cid->type = b;
00595                cid->sawflag = 3;
00596                cid->cksum = b;
00597             }
00598             break;
00599          case 3:  /* Get length */
00600             /* Not a lead in.  We're ready  */
00601             cid->sawflag = 4;
00602             cid->len = b;
00603             cid->pos = 0;
00604             cid->cksum += b;
00605             break;
00606          case 4: /* Retrieve message */
00607             if (cid->pos >= 128) {
00608                ast_log(LOG_WARNING, "Caller ID too long???\n");
00609                return -1;
00610             }
00611             cid->rawdata[cid->pos++] = b;
00612             cid->len--;
00613             cid->cksum += b;
00614             if (!cid->len) {
00615                cid->rawdata[cid->pos] = '\0';
00616                cid->sawflag = 5;
00617             }
00618             break;
00619          case 5: /* Check checksum */
00620             if (b != (256 - (cid->cksum & 0xff))) {
00621                ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
00622                /* Try again */
00623                cid->sawflag = 0;
00624                break;
00625             }
00626       
00627             cid->number[0] = '\0';
00628             cid->name[0] = '\0';
00629             /* Update flags */
00630             cid->flags = 0;
00631             /* If we get this far we're fine.  */
00632             if ((cid->type == 0x80) || (cid->type == 0x82)) {
00633                /* MDMF */
00634                /* Go through each element and process */
00635                for (x = 0; x < cid->pos;) {
00636                   switch (cid->rawdata[x++]) {
00637                   case 1:
00638                      /* Date */
00639                      break;
00640                   case 2: /* Number */
00641                   case 3: /* Number (for Zebble) */
00642                   case 4: /* Number */
00643                      res = cid->rawdata[x];
00644                      if (res > 32) {
00645                         ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
00646                         res = 32; 
00647                      }
00648                      if (ast_strlen_zero(cid->number)) {
00649                         memcpy(cid->number, cid->rawdata + x + 1, res);
00650                         /* Null terminate */
00651                         cid->number[res] = '\0';
00652                      }
00653                      break;
00654                   case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
00655                      break;
00656                   case 7: /* Name */
00657                   case 8: /* Name */
00658                      res = cid->rawdata[x];
00659                      if (res > 32) {
00660                         ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
00661                         res = 32; 
00662                      }
00663                      memcpy(cid->name, cid->rawdata + x + 1, res);
00664                      cid->name[res] = '\0';
00665                      break;
00666                   case 11: /* Message Waiting */
00667                      res = cid->rawdata[x + 1];
00668                      if (res)
00669                         cid->flags |= CID_MSGWAITING;
00670                      else
00671                         cid->flags |= CID_NOMSGWAITING;
00672                      break;
00673                   case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
00674                   case 19: /* UK: Network message system status (Number of messages waiting) */
00675                   case 22: /* Something French */
00676                      break;
00677                   default:
00678                      ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]);
00679                   }
00680                   res = cid->rawdata[x];
00681                   if (0 > res){  /* Negative offset in the CID Spill */
00682                      ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
00683                      /* Try again */
00684                      cid->sawflag = 0;
00685                      break;   /* Exit the loop */
00686                   }
00687                   x += cid->rawdata[x];
00688                   x++;
00689                }
00690             } else if (cid->type == 0x6) {
00691                /* VMWI SDMF */
00692                if (cid->rawdata[2] == 0x42) {
00693                   cid->flags |= CID_MSGWAITING;
00694                } else if (cid->rawdata[2] == 0x6f) {
00695                   cid->flags |= CID_NOMSGWAITING;
00696                }
00697             } else {
00698                /* SDMF */
00699                ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
00700             }
00701             if (!strcmp(cid->number, "P")) {
00702                strcpy(cid->number, "");
00703                cid->flags |= CID_PRIVATE_NUMBER;
00704             } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
00705                strcpy(cid->number, "");
00706                cid->flags |= CID_UNKNOWN_NUMBER;
00707             }
00708             if (!strcmp(cid->name, "P")) {
00709                strcpy(cid->name, "");
00710                cid->flags |= CID_PRIVATE_NAME;
00711             } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
00712                strcpy(cid->name, "");
00713                cid->flags |= CID_UNKNOWN_NAME;
00714             }
00715             return 1;
00716             break;
00717          default:
00718             ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
00719          }
00720       }
00721    }
00722    if (mylen) {
00723       memcpy(cid->oldstuff, buf, mylen * 2);
00724       cid->oldlen = mylen * 2;
00725    } else
00726       cid->oldlen = 0;
00727 
00728    return 0;
00729 }
00730 
00731 void callerid_free(struct callerid_state *cid)
00732 {
00733    ast_free(cid);
00734 }
00735 
00736 static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
00737 {
00738    struct timeval now = ast_tvnow();
00739    struct ast_tm tm;
00740    char *ptr;
00741    int res;
00742    int i, x;
00743 
00744    /* Get the time */
00745    ast_localtime(&now, &tm, NULL);
00746    
00747    ptr = msg;
00748    
00749    /* Format time and message header */
00750    res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
00751             tm.tm_mday, tm.tm_hour, tm.tm_min);
00752    size -= res;
00753    ptr += res;
00754    if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
00755       /* Indicate number not known */
00756       res = snprintf(ptr, size, "\004\001O");
00757       size -= res;
00758       ptr += res;
00759    } else if (flags & CID_PRIVATE_NUMBER) {
00760       /* Indicate number is private */
00761       res = snprintf(ptr, size, "\004\001P");
00762       size -= res;
00763       ptr += res;
00764    } else {
00765       /* Send up to 16 digits of number MAX */
00766       i = strlen(number);
00767       if (i > 16)
00768          i = 16;
00769       res = snprintf(ptr, size, "\002%c", i);
00770       size -= res;
00771       ptr += res;
00772       for (x = 0; x < i; x++)
00773          ptr[x] = number[x];
00774       ptr[i] = '\0';
00775       ptr += i;
00776       size -= i;
00777    }
00778 
00779    if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
00780       /* Indicate name not known */
00781       res = snprintf(ptr, size, "\010\001O");
00782       size -= res;
00783       ptr += res;
00784    } else if (flags & CID_PRIVATE_NAME) {
00785       /* Indicate name is private */
00786       res = snprintf(ptr, size, "\010\001P");
00787       size -= res;
00788       ptr += res;
00789    } else {
00790       /* Send up to 16 digits of name MAX */
00791       i = strlen(name);
00792       if (i > 16)
00793          i = 16;
00794       res = snprintf(ptr, size, "\007%c", i);
00795       size -= res;
00796       ptr += res;
00797       for (x = 0; x < i; x++)
00798          ptr[x] = name[x];
00799       ptr[i] = '\0';
00800       ptr += i;
00801       size -= i;
00802    }
00803    return (ptr - msg);
00804    
00805 }
00806 
00807 int vmwi_generate(unsigned char *buf, int active, int type, int codec,
00808               const char* name, const char* number, int flags)
00809 {
00810    char msg[256];
00811    int len = 0;
00812    int sum;
00813    int x;
00814    int bytes = 0;
00815    float cr = 1.0;
00816    float ci = 0.0;
00817    float scont = 0.0;
00818    
00819    if (type == CID_MWI_TYPE_MDMF_FULL) {
00820       /* MDMF Message waiting with date, number, name and MWI parameter */
00821       msg[0] = 0x82;
00822 
00823       /* put date, number info at the right place */
00824       len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags); 
00825       
00826       /* length of MDMF CLI plus Message Waiting Structure */
00827       msg[1] = len+3;
00828       
00829       /* Go to the position to write to */
00830       len = len+2;
00831       
00832       /* "Message Waiting Parameter" */
00833       msg[len++] = 0x0b;
00834       /* Length of IE is one */
00835       msg[len++] = 1;
00836       /* Active or not */
00837       if (active)
00838          msg[len++] = 0xff;
00839       else
00840          msg[len++] = 0x00;
00841       
00842    } else if (type == CID_MWI_TYPE_MDMF) {
00843       /* MDMF Message waiting only */
00844       /* same as above except that the we only put MWI parameter */
00845       msg[len++] = 0x82;
00846       /* Length is 3 */
00847       msg[len++] = 3;
00848       /* IE is "Message Waiting Parameter" */
00849       msg[len++] = 0x0b;
00850       /* Length of IE is one */
00851       msg[len++] = 1;
00852       /* Active or not */
00853       if (active)
00854          msg[len++] = 0xff;
00855       else
00856          msg[len++] = 0x00;
00857    } else {
00858       /* SDMF Message waiting */
00859       msg[len++] = 0x6;
00860       /* Length is 3 */
00861       msg[len++] = 3;
00862       if (active) {
00863          msg[len++] = 0x42;
00864          msg[len++] = 0x42;
00865          msg[len++] = 0x42;
00866       } else {
00867          msg[len++] = 0x6f;
00868          msg[len++] = 0x6f;
00869          msg[len++] = 0x6f;
00870       }
00871    }
00872    sum = 0;
00873    for (x = 0; x < len; x++)
00874       sum += msg[x];
00875    sum = (256 - (sum & 255));
00876    msg[len++] = sum;
00877    /* Wait a half a second */
00878    for (x = 0; x < 4000; x++)
00879       PUT_BYTE(0x7f);
00880    /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00881    for (x = 0; x < 30; x++)
00882       PUT_CLID(0x55);
00883    /* Send 170ms of callerid marks */
00884    for (x = 0; x < 170; x++)
00885       PUT_CLID_MARKMS;
00886    for (x = 0; x < len; x++) {
00887       PUT_CLID(msg[x]);
00888    }
00889    /* Send 50 more ms of marks */
00890    for (x = 0; x < 50; x++)
00891       PUT_CLID_MARKMS;
00892    return bytes;
00893 }
00894 
00895 int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec)
00896 {
00897    int bytes = 0;
00898    int x, sum;
00899    int len;
00900 
00901    /* Initial carriers (real/imaginary) */
00902    float cr = 1.0;
00903    float ci = 0.0;
00904    float scont = 0.0;
00905    char msg[256];
00906    len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
00907    if (!callwaiting) {
00908       /* Wait a half a second */
00909       for (x = 0; x < 4000; x++)
00910          PUT_BYTE(0x7f);
00911       /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
00912       for (x = 0; x < 30; x++)
00913          PUT_CLID(0x55);
00914    }
00915    /* Send 150ms of callerid marks */
00916    for (x = 0; x < 150; x++)
00917       PUT_CLID_MARKMS;
00918    /* Send 0x80 indicating MDMF format */
00919    PUT_CLID(0x80);
00920    /* Put length of whole message */
00921    PUT_CLID(len);
00922    sum = 0x80 + strlen(msg);
00923    /* Put each character of message and update checksum */
00924    for (x = 0; x < len; x++) {
00925       PUT_CLID(msg[x]);
00926       sum += msg[x];
00927    }
00928    /* Send 2's compliment of sum */
00929    PUT_CLID(256 - (sum & 255));
00930 
00931    /* Send 50 more ms of marks */
00932    for (x = 0; x < 50; x++)
00933       PUT_CLID_MARKMS;
00934    
00935    return bytes;
00936 }
00937 
00938 /*! \brief Clean up phone string
00939  * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
00940  * Basically, remove anything that could be invalid in a pattern.
00941  */
00942 void ast_shrink_phone_number(char *n)
00943 {
00944    int x, y = 0;
00945    int bracketed = 0;
00946 
00947    for (x = 0; n[x]; x++) {
00948       switch (n[x]) {
00949       case '[':
00950          bracketed++;
00951          n[y++] = n[x];
00952          break;
00953       case ']':
00954          bracketed--;
00955          n[y++] = n[x];
00956          break;
00957       case '-':
00958          if (bracketed)
00959             n[y++] = n[x];
00960          break;
00961       case '.':
00962          if (!n[x+1])
00963             n[y++] = n[x];
00964          break;
00965       default:
00966          /* ignore parenthesis and whitespace */
00967          if (!strchr("( )", n[x]))
00968             n[y++] = n[x];
00969       }
00970    }
00971    n[y] = '\0';
00972 }
00973 
00974 /*! \brief Checks if phone number consists of valid characters 
00975    \param exten   String that needs to be checked
00976    \param valid   Valid characters in string
00977    \return 1 if valid string, 0 if string contains invalid characters
00978 */
00979 static int ast_is_valid_string(const char *exten, const char *valid)
00980 {
00981    int x;
00982 
00983    if (ast_strlen_zero(exten))
00984       return 0;
00985    for (x = 0; exten[x]; x++)
00986       if (!strchr(valid, exten[x]))
00987          return 0;
00988    return 1;
00989 }
00990 
00991 /*! \brief checks if string consists only of digits and * \# and + 
00992    \return 1 if string is valid AST phone number
00993    \return 0 if not
00994 */
00995 int ast_isphonenumber(const char *n)
00996 {
00997    return ast_is_valid_string(n, "0123456789*#+");
00998 }
00999 
01000 /*! \brief checks if string consists only of digits and ( ) - * \# and + 
01001    Pre-qualifies the string for ast_shrink_phone_number()
01002    \return 1 if string is valid AST shrinkable phone number
01003    \return 0 if not
01004 */
01005 int ast_is_shrinkable_phonenumber(const char *exten)
01006 {
01007    return ast_is_valid_string(exten, "0123456789*#+()-.");
01008 }
01009 
01010 /*!
01011  * \brief Destructively parse instr for caller id information 
01012  * \return always returns 0, as the code always returns something.
01013  * \note XXX 'name' is not parsed consistently e.g. we have
01014  * input                   location        name
01015  * " foo bar " <123>       123             ' foo bar ' (with spaces around)
01016  * " foo bar "             NULL            'foo bar' (without spaces around)
01017  * The parsing of leading and trailing space/quotes should be more consistent.
01018  */
01019 int ast_callerid_parse(char *instr, char **name, char **location)
01020 {
01021    char *ns, *ne, *ls, *le;
01022 
01023    /* Try "name" <location> format or name <location> format */
01024    if ((ls = strrchr(instr, '<')) && (le = strrchr(ls, '>'))) {
01025       *ls = *le = '\0'; /* location found, trim off the brackets */
01026       *location = ls + 1;  /* and this is the result */
01027       if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
01028          *ns = *ne = '\0'; /* trim off the quotes */
01029          *name = ns + 1;      /* and this is the name */
01030       } else if (ns) {
01031          /* An opening quote was found but no closing quote was. The closing
01032           * quote may actually be after the end of the bracketed number
01033           */
01034          if (strchr(le + 1, '\"')) {
01035             *ns = '\0';
01036             *name = ns + 1;
01037             ast_trim_blanks(*name);
01038          } else {
01039             *name = NULL;
01040          }
01041       } else { /* no quotes, trim off leading and trailing spaces */
01042          *name = ast_skip_blanks(instr);
01043          ast_trim_blanks(*name);
01044       }
01045    } else { /* no valid brackets */
01046       char tmp[256];
01047 
01048       ast_copy_string(tmp, instr, sizeof(tmp));
01049       ast_shrink_phone_number(tmp);
01050       if (ast_isphonenumber(tmp)) { /* Assume it's just a location */
01051          *name = NULL;
01052          strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
01053          *location = instr;
01054       } else { /* Assume it's just a name. */
01055          *location = NULL;
01056          if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
01057             *ns = *ne = '\0'; /* trim off the quotes */
01058             *name = ns + 1;      /* and this is the name */
01059          } else { /* no quotes, trim off leading and trailing spaces */
01060             *name = ast_skip_blanks(instr);
01061             ast_trim_blanks(*name);
01062          }
01063       }
01064    }
01065    return 0;
01066 }
01067 
01068 static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, int codec)
01069 {
01070    if (ast_strlen_zero(name))
01071       name = NULL;
01072    if (ast_strlen_zero(number))
01073       number = NULL;
01074    return callerid_generate(buf, number, name, 0, callwaiting, codec);
01075 }
01076 
01077 int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec)
01078 {
01079    return __ast_callerid_generate(buf, name, number, 0, codec);
01080 }
01081 
01082 int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec)
01083 {
01084    return __ast_callerid_generate(buf, name, number, 1, codec);
01085 }
01086 
01087 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
01088 {
01089    if (!unknown)
01090       unknown = "<unknown>";
01091    if (name && num)
01092       snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
01093    else if (name) 
01094       ast_copy_string(buf, name, bufsiz);
01095    else if (num)
01096       ast_copy_string(buf, num, bufsiz);
01097    else
01098       ast_copy_string(buf, unknown, bufsiz);
01099    return buf;
01100 }
01101 
01102 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
01103 {
01104    char *tmp;
01105    char *l = NULL, *n = NULL;
01106 
01107    tmp = ast_strdupa(buf);
01108    ast_callerid_parse(tmp, &n, &l);
01109    if (n)
01110       ast_copy_string(name, n, namelen);
01111    else
01112       name[0] = '\0';
01113    if (l) {
01114       ast_shrink_phone_number(l);
01115       ast_copy_string(num, l, numlen);
01116    } else
01117       num[0] = '\0';
01118    return 0;
01119 }
01120 
01121 /*! \brief Translation table for Caller ID Presentation settings */
01122 static struct {
01123    int val;
01124    const char *name;
01125    const char *description;
01126 } pres_types[] = {
01127    {  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
01128    {  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
01129    {  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
01130    {  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
01131    {  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
01132    {  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
01133    {  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
01134    {  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
01135    {  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
01136 };
01137 
01138 /*! \brief Convert caller ID text code to value 
01139    used in config file parsing
01140    \param data text string
01141    \return value AST_PRES_ from callerid.h 
01142 */
01143 int ast_parse_caller_presentation(const char *data)
01144 {
01145    int i;
01146    if (!data) {
01147       return -1;
01148    }
01149 
01150    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01151       if (!strcasecmp(pres_types[i].name, data))
01152          return pres_types[i].val;
01153    }
01154 
01155    return -1;
01156 }
01157 
01158 /*! \brief Convert caller ID pres value to explanatory string 
01159    \param data value (see callerid.h AST_PRES_ ) 
01160    \return string for human presentation
01161 */
01162 const char *ast_describe_caller_presentation(int data)
01163 {
01164    int i;
01165 
01166    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01167       if (pres_types[i].val == data)
01168          return pres_types[i].description;
01169    }
01170 
01171    return "unknown";
01172 }
01173 
01174 /*! \brief Convert caller ID pres value to text code
01175    \param data text string
01176    \return string for config file
01177 */
01178 const char *ast_named_caller_presentation(int data)
01179 {
01180    int i;
01181 
01182    for (i = 0; i < ARRAY_LEN(pres_types); i++) {
01183       if (pres_types[i].val == data)
01184          return pres_types[i].name;
01185    }
01186 
01187    return "unknown";
01188 }