Wed Jan 8 2020 09:49:42

Asterisk developer's documentation


callerid.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief CallerID Generation support
22  *
23  * \author Mark Spencer <markster@digium.com>
24  */
25 
26 /*** MODULEINFO
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 425152 $")
33 
34 #include <time.h>
35 #include <math.h>
36 #include <ctype.h>
37 
38 #include "asterisk/ulaw.h"
39 #include "asterisk/alaw.h"
40 #include "asterisk/frame.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/callerid.h"
43 #include "asterisk/fskmodem.h"
44 #include "asterisk/utils.h"
45 
48  char rawdata[256];
49  short oldstuff[160];
50  int oldlen;
51  int pos;
52  int type;
53  int cksum;
54  char name[64];
55  char number[64];
56  int flags;
57  int sawflag;
58  int len;
59 
60  int skipflag;
61  unsigned short crc;
62 };
63 
64 
65 float cid_dr[4], cid_di[4];
66 float clidsb = 8000.0 / 1200.0;
67 float sasdr, sasdi;
69 
70 #define CALLERID_SPACE 2200.0 /*!< 2200 hz for "0" */
71 #define CALLERID_MARK 1200.0 /*!< 1200 hz for "1" */
72 #define SAS_FREQ 440.0
73 #define CAS_FREQ1 2130.0
74 #define CAS_FREQ2 2750.0
75 
76 #define AST_CALLERID_UNKNOWN "<unknown>"
77 
78 static inline void gen_tones(unsigned char *buf, int len, format_t codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
79 {
80  int x;
81  float t;
82  for (x = 0; x < len; x++) {
83  t = *cr1 * ddr1 - *ci1 * ddi1;
84  *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
85  *cr1 = t;
86  t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
87  *cr1 *= t;
88  *ci1 *= t;
89 
90  t = *cr2 * ddr2 - *ci2 * ddi2;
91  *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
92  *cr2 = t;
93  t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
94  *cr2 *= t;
95  *ci2 *= t;
96  buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
97  }
98 }
99 
100 static inline void gen_tone(unsigned char *buf, int len, format_t codec, float ddr1, float ddi1, float *cr1, float *ci1)
101 {
102  int x;
103  float t;
104  for (x = 0; x < len; x++) {
105  t = *cr1 * ddr1 - *ci1 * ddi1;
106  *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
107  *cr1 = t;
108  t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
109  *cr1 *= t;
110  *ci1 *= t;
111  buf[x] = AST_LIN2X(*cr1 * 8192.0);
112  }
113 }
114 
115 /*! \brief Initialize stuff for inverse FFT */
116 void callerid_init(void)
117 {
118  cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
119  cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
120  cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
121  cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
122  sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
123  sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
124  casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
125  casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
126  casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
127  casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
128 }
129 
130 struct callerid_state *callerid_new(int cid_signalling)
131 {
132  struct callerid_state *cid;
133 
134  if ((cid = ast_calloc(1, sizeof(*cid)))) {
135 #ifdef INTEGER_CALLERID
136  cid->fskd.ispb = 7; /* 1200 baud */
137  /* Set up for 1200 / 8000 freq *32 to allow ints */
138  cid->fskd.pllispb = (int)(8000 * 32 / 1200);
139  cid->fskd.pllids = cid->fskd.pllispb/32;
140  cid->fskd.pllispb2 = cid->fskd.pllispb/2;
141 
142  cid->fskd.icont = 0; /* PLL REset */
143  /* cid->fskd.hdlc = 0; */ /* Async */
144  cid->fskd.nbit = 8; /* 8 bits */
145  cid->fskd.instop = 1; /* 1 stop bit */
146  /* cid->fskd.paridad = 0; */ /* No parity */
147  cid->fskd.bw = 1; /* Filter 800 Hz */
148  if (cid_signalling == 2) { /* v23 signalling */
149  cid->fskd.f_mark_idx = 4; /* 1300 Hz */
150  cid->fskd.f_space_idx = 5; /* 2100 Hz */
151  } else { /* Bell 202 signalling as default */
152  cid->fskd.f_mark_idx = 2; /* 1200 Hz */
153  cid->fskd.f_space_idx = 3; /* 2200 Hz */
154  }
155  /* cid->fskd.pcola = 0; */ /* No clue */
156  /* cid->fskd.cont = 0.0; */ /* Digital PLL reset */
157  /* cid->fskd.x0 = 0.0; */
158  /* cid->fskd.state = 0; */
160  /* cid->pos = 0; */
161 
162  fskmodem_init(&cid->fskd);
163 #else
164  cid->fskd.spb = 7.0; /* 1200 baud */
165  /* cid->fskd.hdlc = 0; */ /* Async */
166  cid->fskd.nbit = 8; /* 8 bits */
167  cid->fskd.nstop = 1.0; /* 1 stop bit */
168  /* cid->fskd.paridad = 0; */ /* No parity */
169  cid->fskd.bw = 1; /* Filter 800 Hz */
170  if (cid_signalling == 2) { /* v23 signalling */
171  cid->fskd.f_mark_idx = 4; /* 1300 Hz */
172  cid->fskd.f_space_idx = 5; /* 2100 Hz */
173  } else { /* Bell 202 signalling as default */
174  cid->fskd.f_mark_idx = 2; /* 1200 Hz */
175  cid->fskd.f_space_idx = 3; /* 2200 Hz */
176  }
177  /* cid->fskd.pcola = 0; */ /* No clue */
178  /* cid->fskd.cont = 0.0; */ /* Digital PLL reset */
179  /* cid->fskd.x0 = 0.0; */
180  /* cid->fskd.state = 0; */
182  /* cid->pos = 0; */
183 #endif
184  }
185 
186  return cid;
187 }
188 
189 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
190 {
191  *flags = cid->flags;
192  if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NAME))
193  *name = NULL;
194  else
195  *name = cid->name;
197  *number = NULL;
198  else
199  *number = cid->number;
200 }
201 
202 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
203 {
204  int i;
205  int code;
206 
207  /* "Clear" the number-buffer. */
208  number[0] = 0;
209 
210  if (strlen(cidstring) < 2) {
211  ast_debug(1, "No cid detected\n");
212  *flags = CID_UNKNOWN_NUMBER;
213  return;
214  }
215 
216  /* Detect protocol and special types */
217  if (cidstring[0] == 'B') {
218  /* Handle special codes */
219  code = atoi(&cidstring[1]);
220  if (code == 0)
221  *flags = CID_UNKNOWN_NUMBER;
222  else if (code == 10)
223  *flags = CID_PRIVATE_NUMBER;
224  else
225  ast_debug(1, "Unknown DTMF code %d\n", code);
226  } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
227  /* .DK special code */
228  if (cidstring[1] == '1')
229  *flags = CID_PRIVATE_NUMBER;
230  if (cidstring[1] == '2' || cidstring[1] == '3')
231  *flags = CID_UNKNOWN_NUMBER;
232  } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
233  /* "Standard" callerid */
234  for (i = 1; i < strlen(cidstring); i++) {
235  if (cidstring[i] == 'C' || cidstring[i] == '#')
236  break;
237  if (isdigit(cidstring[i]))
238  number[i-1] = cidstring[i];
239  else
240  ast_debug(1, "Unknown CID digit '%c'\n",
241  cidstring[i]);
242  }
243  number[i-1] = 0;
244  } else if (isdigit(cidstring[0])) {
245  /* It begins with a digit, so we parse it as a number and hope
246  * for the best */
247  ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
248  "parsing might be unreliable\n");
249  for (i = 0; i < strlen(cidstring); i++) {
250  if (isdigit(cidstring[i]))
251  number[i] = cidstring[i];
252  else
253  break;
254  }
255  number[i] = 0;
256  } else {
257  ast_debug(1, "Unknown CID protocol, start digit '%c'\n", cidstring[0]);
258  *flags = CID_UNKNOWN_NUMBER;
259  }
260 }
261 
262 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, format_t codec)
263 {
264  int pos = 0;
265  int saslen = 2400;
266  float cr1 = 1.0;
267  float ci1 = 0.0;
268  float cr2 = 1.0;
269  float ci2 = 0.0;
270 
271  if (sendsas) {
272  if (len < saslen)
273  return -1;
274  gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
275  len -= saslen;
276  pos += saslen;
277  cr2 = cr1;
278  ci2 = ci1;
279  }
280  gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
281  return 0;
282 }
283 
284 static unsigned short calc_crc(unsigned short crc, unsigned char data)
285 {
286  unsigned int i, j, org, dst;
287  org = data;
288  dst = 0;
289 
290  for (i = 0; i < CHAR_BIT; i++) {
291  org <<= 1;
292  dst >>= 1;
293  if (org & 0x100)
294  dst |= 0x80;
295  }
296  data = (unsigned char) dst;
297  crc ^= (unsigned int) data << (16 - CHAR_BIT);
298  for (j = 0; j < CHAR_BIT; j++) {
299  if (crc & 0x8000U)
300  crc = (crc << 1) ^ 0x1021U ;
301  else
302  crc <<= 1 ;
303  }
304  return crc;
305 }
306 
307 int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, format_t codec)
308 {
309  int mylen = len;
310  int olen;
311  int b = 'X';
312  int b2;
313  int res;
314  int x;
315  short *buf;
316 
317  buf = ast_alloca(2 * len + cid->oldlen);
318 
319  memcpy(buf, cid->oldstuff, cid->oldlen);
320  mylen += cid->oldlen / 2;
321 
322  for (x = 0; x < len; x++)
323  buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
324 
325  while (mylen >= 160) {
326  b = b2 = 0;
327  olen = mylen;
328  res = fsk_serial(&cid->fskd, buf, &mylen, &b);
329 
330  if (mylen < 0) {
331  ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
332  return -1;
333  }
334 
335  buf += (olen - mylen);
336 
337  if (res < 0) {
338  ast_log(LOG_NOTICE, "fsk_serial failed\n");
339  return -1;
340  }
341 
342  if (res == 1) {
343  b2 = b;
344  b &= 0x7f;
345 
346  /* crc checksum calculation */
347  if (cid->sawflag > 1)
348  cid->crc = calc_crc(cid->crc, (unsigned char) b2);
349 
350  /* Ignore invalid bytes */
351  if (b > 0xff)
352  continue;
353 
354  /* skip DLE if needed */
355  if (cid->sawflag > 0) {
356  if (cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10) {
357  cid->skipflag = 1 ;
358  continue ;
359  }
360  }
361  if (cid->skipflag == 1)
362  cid->skipflag = 0 ;
363 
364  /* caller id retrieval */
365  switch (cid->sawflag) {
366  case 0: /* DLE */
367  if (b == 0x10) {
368  cid->sawflag = 1;
369  cid->skipflag = 0;
370  cid->crc = 0;
371  }
372  break;
373  case 1: /* SOH */
374  if (b == 0x01)
375  cid->sawflag = 2;
376  break ;
377  case 2: /* HEADER */
378  if (b == 0x07)
379  cid->sawflag = 3;
380  break;
381  case 3: /* STX */
382  if (b == 0x02)
383  cid->sawflag = 4;
384  break;
385  case 4: /* SERVICE TYPE */
386  if (b == 0x40)
387  cid->sawflag = 5;
388  break;
389  case 5: /* Frame Length */
390  cid->sawflag = 6;
391  break;
392  case 6: /* NUMBER TYPE */
393  cid->sawflag = 7;
394  cid->pos = 0;
395  cid->rawdata[cid->pos++] = b;
396  break;
397  case 7: /* NUMBER LENGTH */
398  cid->sawflag = 8;
399  cid->len = b;
400  if ((cid->len+2) >= sizeof(cid->rawdata)) {
401  ast_log(LOG_WARNING, "too long caller id string\n") ;
402  return -1;
403  }
404  cid->rawdata[cid->pos++] = b;
405  break;
406  case 8: /* Retrieve message */
407  cid->rawdata[cid->pos++] = b;
408  cid->len--;
409  if (cid->len<=0) {
410  cid->rawdata[cid->pos] = '\0';
411  cid->sawflag = 9;
412  }
413  break;
414  case 9: /* ETX */
415  cid->sawflag = 10;
416  break;
417  case 10: /* CRC Checksum 1 */
418  cid->sawflag = 11;
419  break;
420  case 11: /* CRC Checksum 2 */
421  cid->sawflag = 12;
422  if (cid->crc != 0) {
423  ast_log(LOG_WARNING, "crc checksum error\n") ;
424  return -1;
425  }
426  /* extract caller id data */
427  for (x = 0; x < cid->pos;) {
428  switch (cid->rawdata[x++]) {
429  case 0x02: /* caller id number */
430  cid->number[0] = '\0';
431  cid->name[0] = '\0';
432  cid->flags = 0;
433  res = cid->rawdata[x++];
434  ast_copy_string(cid->number, &cid->rawdata[x], res+1);
435  x += res;
436  break;
437  case 0x21: /* additional information */
438  /* length */
439  x++;
440  /* number type */
441  switch (cid->rawdata[x]) {
442  case 0x00: /* unknown */
443  case 0x01: /* international number */
444  case 0x02: /* domestic number */
445  case 0x03: /* network */
446  case 0x04: /* local call */
447  case 0x06: /* short dial number */
448  case 0x07: /* reserved */
449  default: /* reserved */
450  ast_debug(2, "cid info:#1=%X\n", (unsigned)cid->rawdata[x]);
451  break ;
452  }
453  x++;
454  /* numbering plan octed 4 */
455  x++;
456  /* numbering plan octed 5 */
457  switch (cid->rawdata[x]) {
458  case 0x00: /* unknown */
459  case 0x01: /* recommendation E.164 ISDN */
460  case 0x03: /* recommendation X.121 */
461  case 0x04: /* telex dial plan */
462  case 0x08: /* domestic dial plan */
463  case 0x09: /* private dial plan */
464  case 0x05: /* reserved */
465  default: /* reserved */
466  ast_debug(2, "cid info:#2=%X\n", (unsigned)cid->rawdata[x]);
467  break ;
468  }
469  x++;
470  break ;
471  case 0x04: /* no callerid reason */
472  /* length */
473  x++;
474  /* no callerid reason code */
475  switch (cid->rawdata[x]) {
476  case 'P': /* caller id denied by user */
477  case 'O': /* service not available */
478  case 'C': /* pay phone */
479  case 'S': /* service congested */
480  cid->flags |= CID_UNKNOWN_NUMBER;
481  ast_debug(2, "no cid reason:%c\n", cid->rawdata[x]);
482  break ;
483  }
484  x++;
485  break ;
486  case 0x09: /* dialed number */
487  /* length */
488  res = cid->rawdata[x++];
489  /* dialed number */
490  x += res;
491  break ;
492  case 0x22: /* dialed number additional information */
493  /* length */
494  x++;
495  /* number type */
496  switch (cid->rawdata[x]) {
497  case 0x00: /* unknown */
498  case 0x01: /* international number */
499  case 0x02: /* domestic number */
500  case 0x03: /* network */
501  case 0x04: /* local call */
502  case 0x06: /* short dial number */
503  case 0x07: /* reserved */
504  default: /* reserved */
505  if (option_debug > 1)
506  ast_log(LOG_NOTICE, "did info:#1=%X\n", (unsigned)cid->rawdata[x]);
507  break ;
508  }
509  x++;
510  /* numbering plan octed 4 */
511  x++;
512  /* numbering plan octed 5 */
513  switch (cid->rawdata[x]) {
514  case 0x00: /* unknown */
515  case 0x01: /* recommendation E.164 ISDN */
516  case 0x03: /* recommendation X.121 */
517  case 0x04: /* telex dial plan */
518  case 0x08: /* domestic dial plan */
519  case 0x09: /* private dial plan */
520  case 0x05: /* reserved */
521  default: /* reserved */
522  ast_debug(2, "did info:#2=%X\n", (unsigned)cid->rawdata[x]);
523  break ;
524  }
525  x++;
526  break ;
527  }
528  }
529  return 1;
530  break;
531  default:
532  ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
533  }
534  }
535  }
536  if (mylen) {
537  memcpy(cid->oldstuff, buf, mylen * 2);
538  cid->oldlen = mylen * 2;
539  } else
540  cid->oldlen = 0;
541 
542  return 0;
543 }
544 
545 
546 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, format_t codec)
547 {
548  int mylen = len;
549  int olen;
550  int b = 'X';
551  int res;
552  int x;
553  short *buf;
554 
555  buf = ast_alloca(2 * len + cid->oldlen);
556 
557  memcpy(buf, cid->oldstuff, cid->oldlen);
558  mylen += cid->oldlen/2;
559 
560  for (x = 0; x < len; x++)
561  buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
562  while (mylen >= 160) {
563  olen = mylen;
564  res = fsk_serial(&cid->fskd, buf, &mylen, &b);
565  if (mylen < 0) {
566  ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
567  return -1;
568  }
569  buf += (olen - mylen);
570  if (res < 0) {
571  ast_log(LOG_NOTICE, "fsk_serial failed\n");
572  return -1;
573  }
574  if (res == 1) {
575  if (b > 0xff) {
576  if (cid->sawflag != 5) {
577  /* Ignore invalid bytes */
578  continue;
579  }
580  /*
581  * We can tollerate an error on the checksum character since the
582  * checksum character is the last character in the message and
583  * it validates the message.
584  *
585  * Remove character error flags.
586  * Bit 8 : Parity error
587  * Bit 9 : Framing error
588  */
589  b &= 0xff;
590  }
591  switch (cid->sawflag) {
592  case 0: /* Look for flag */
593  if (b == 'U')
594  cid->sawflag = 2;
595  break;
596  case 2: /* Get lead-in */
597  if ((b == 0x04) || (b == 0x80) || (b == 0x06) || (b == 0x82)) {
598  cid->type = b;
599  cid->sawflag = 3;
600  cid->cksum = b;
601  }
602  break;
603  case 3: /* Get length */
604  /* Not a lead in. We're ready */
605  cid->sawflag = 4;
606  cid->len = b;
607  cid->pos = 0;
608  cid->cksum += b;
609  break;
610  case 4: /* Retrieve message */
611  if (cid->pos >= 128) {
612  ast_log(LOG_WARNING, "Caller ID too long???\n");
613  return -1;
614  }
615  cid->rawdata[cid->pos++] = b;
616  cid->len--;
617  cid->cksum += b;
618  if (!cid->len) {
619  cid->rawdata[cid->pos] = '\0';
620  cid->sawflag = 5;
621  }
622  break;
623  case 5: /* Check checksum */
624  if ((b + cid->cksum) & 0xff) {
625  ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
626  /* Try again */
627  cid->sawflag = 0;
628  break;
629  }
630 
631  cid->number[0] = '\0';
632  cid->name[0] = '\0';
633  /* Update flags */
634  cid->flags = 0;
635  /* If we get this far we're fine. */
636  if ((cid->type == 0x80) || (cid->type == 0x82)) {
637  /* MDMF */
638  /* Go through each element and process */
639  for (x = 0; x < cid->pos;) {
640  switch (cid->rawdata[x++]) {
641  case 1:
642  /* Date */
643  break;
644  case 2: /* Number */
645  case 3: /* Number (for Zebble) */
646  case 4: /* Number */
647  res = cid->rawdata[x];
648  if (res > 32) {
649  ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
650  res = 32;
651  }
652  if (ast_strlen_zero(cid->number)) {
653  memcpy(cid->number, cid->rawdata + x + 1, res);
654  /* Null terminate */
655  cid->number[res] = '\0';
656  }
657  break;
658  case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
659  break;
660  case 7: /* Name */
661  case 8: /* Name */
662  res = cid->rawdata[x];
663  if (res > 32) {
664  ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
665  res = 32;
666  }
667  memcpy(cid->name, cid->rawdata + x + 1, res);
668  cid->name[res] = '\0';
669  break;
670  case 11: /* Message Waiting */
671  res = cid->rawdata[x + 1];
672  if (res)
673  cid->flags |= CID_MSGWAITING;
674  else
675  cid->flags |= CID_NOMSGWAITING;
676  break;
677  case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */
678  case 19: /* UK: Network message system status (Number of messages waiting) */
679  case 22: /* Something French */
680  break;
681  default:
682  ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]);
683  }
684  res = cid->rawdata[x];
685  if (0 > res){ /* Negative offset in the CID Spill */
686  ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
687  /* Try again */
688  cid->sawflag = 0;
689  break; /* Exit the loop */
690  }
691  x += cid->rawdata[x];
692  x++;
693  }
694  } else if (cid->type == 0x6) {
695  /* VMWI SDMF */
696  if (cid->rawdata[2] == 0x42) {
697  cid->flags |= CID_MSGWAITING;
698  } else if (cid->rawdata[2] == 0x6f) {
699  cid->flags |= CID_NOMSGWAITING;
700  }
701  } else {
702  /* SDMF */
703  ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
704  }
705  if (!strcmp(cid->number, "P")) {
706  strcpy(cid->number, "");
707  cid->flags |= CID_PRIVATE_NUMBER;
708  } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
709  strcpy(cid->number, "");
710  cid->flags |= CID_UNKNOWN_NUMBER;
711  }
712  if (!strcmp(cid->name, "P")) {
713  strcpy(cid->name, "");
714  cid->flags |= CID_PRIVATE_NAME;
715  } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
716  strcpy(cid->name, "");
717  cid->flags |= CID_UNKNOWN_NAME;
718  }
719  return 1;
720  break;
721  default:
722  ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
723  }
724  }
725  }
726  if (mylen) {
727  memcpy(cid->oldstuff, buf, mylen * 2);
728  cid->oldlen = mylen * 2;
729  } else
730  cid->oldlen = 0;
731 
732  return 0;
733 }
734 
735 void callerid_free(struct callerid_state *cid)
736 {
737  ast_free(cid);
738 }
739 
740 static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
741 {
742  struct timeval now = ast_tvnow();
743  struct ast_tm tm;
744  char *ptr;
745  int res;
746  int i, x;
747 
748  /* Get the time */
749  ast_localtime(&now, &tm, NULL);
750 
751  ptr = msg;
752 
753  /* Format time and message header */
754  res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
755  tm.tm_mday, tm.tm_hour, tm.tm_min);
756  size -= res;
757  ptr += res;
758  if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
759  /* Indicate number not known */
760  res = snprintf(ptr, size, "\004\001O");
761  size -= res;
762  ptr += res;
763  } else if (flags & CID_PRIVATE_NUMBER) {
764  /* Indicate number is private */
765  res = snprintf(ptr, size, "\004\001P");
766  size -= res;
767  ptr += res;
768  } else {
769  /* Send up to 16 digits of number MAX */
770  i = strlen(number);
771  if (i > 16)
772  i = 16;
773  res = snprintf(ptr, size, "\002%c", i);
774  size -= res;
775  ptr += res;
776  for (x = 0; x < i; x++)
777  ptr[x] = number[x];
778  ptr[i] = '\0';
779  ptr += i;
780  size -= i;
781  }
782 
783  if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
784  /* Indicate name not known */
785  res = snprintf(ptr, size, "\010\001O");
786  size -= res;
787  ptr += res;
788  } else if (flags & CID_PRIVATE_NAME) {
789  /* Indicate name is private */
790  res = snprintf(ptr, size, "\010\001P");
791  size -= res;
792  ptr += res;
793  } else {
794  /* Send up to 16 digits of name MAX */
795  i = strlen(name);
796  if (i > 16)
797  i = 16;
798  res = snprintf(ptr, size, "\007%c", i);
799  size -= res;
800  ptr += res;
801  for (x = 0; x < i; x++)
802  ptr[x] = name[x];
803  ptr[i] = '\0';
804  ptr += i;
805  size -= i;
806  }
807  return (ptr - msg);
808 
809 }
810 
811 int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, format_t codec,
812  const char* name, const char* number, int flags)
813 {
814  char msg[256];
815  int len = 0;
816  int sum;
817  int x;
818  int bytes = 0;
819  float cr = 1.0;
820  float ci = 0.0;
821  float scont = 0.0;
822 
823  if (type == CID_MWI_TYPE_MDMF_FULL) {
824  /* MDMF Message waiting with date, number, name and MWI parameter */
825  msg[0] = 0x82;
826 
827  /* put date, number info at the right place */
828  len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags);
829 
830  /* length of MDMF CLI plus Message Waiting Structure */
831  msg[1] = len+3;
832 
833  /* Go to the position to write to */
834  len = len+2;
835 
836  /* "Message Waiting Parameter" */
837  msg[len++] = 0x0b;
838  /* Length of IE is one */
839  msg[len++] = 1;
840  /* Active or not */
841  if (active)
842  msg[len++] = 0xff;
843  else
844  msg[len++] = 0x00;
845 
846  } else if (type == CID_MWI_TYPE_MDMF) {
847  /* MDMF Message waiting only */
848  /* same as above except that the we only put MWI parameter */
849  msg[len++] = 0x82;
850  /* Length is 3 */
851  msg[len++] = 3;
852  /* IE is "Message Waiting Parameter" */
853  msg[len++] = 0x0b;
854  /* Length of IE is one */
855  msg[len++] = 1;
856  /* Active or not */
857  if (active)
858  msg[len++] = 0xff;
859  else
860  msg[len++] = 0x00;
861  } else {
862  /* SDMF Message waiting */
863  msg[len++] = 0x6;
864  /* Length is 3 */
865  msg[len++] = 3;
866  if (active) {
867  msg[len++] = 0x42;
868  msg[len++] = 0x42;
869  msg[len++] = 0x42;
870  } else {
871  msg[len++] = 0x6f;
872  msg[len++] = 0x6f;
873  msg[len++] = 0x6f;
874  }
875  }
876  sum = 0;
877  for (x = 0; x < len; x++)
878  sum += msg[x];
879  sum = (256 - (sum & 255));
880  msg[len++] = sum;
881  /* Wait a half a second */
882  for (x = 0; x < 4000; x++)
883  PUT_BYTE(0x7f);
884  /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
885  for (x = 0; x < 30; x++)
886  PUT_CLID(0x55);
887  /* Send 170ms of callerid marks */
888  for (x = 0; x < 170; x++)
890  for (x = 0; x < len; x++) {
891  PUT_CLID(msg[x]);
892  }
893  /* Send 50 more ms of marks */
894  for (x = 0; x < 50; x++)
896  return bytes;
897 }
898 
899 int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, format_t codec)
900 {
901  int bytes = 0;
902  int x, sum;
903  int len;
904 
905  /* Initial carriers (real/imaginary) */
906  float cr = 1.0;
907  float ci = 0.0;
908  float scont = 0.0;
909  char msg[256];
910  len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
911  if (!callwaiting) {
912  /* Wait a half a second */
913  for (x = 0; x < 4000; x++)
914  PUT_BYTE(0x7f);
915  /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
916  for (x = 0; x < 30; x++)
917  PUT_CLID(0x55);
918  }
919  /* Send 150ms of callerid marks */
920  for (x = 0; x < 150; x++)
922  /* Send 0x80 indicating MDMF format */
923  PUT_CLID(0x80);
924  /* Put length of whole message */
925  PUT_CLID(len);
926  sum = 0x80 + strlen(msg);
927  /* Put each character of message and update checksum */
928  for (x = 0; x < len; x++) {
929  PUT_CLID(msg[x]);
930  sum += msg[x];
931  }
932  /* Send 2's compliment of sum */
933  PUT_CLID(256 - (sum & 255));
934 
935  /* Send 50 more ms of marks */
936  for (x = 0; x < 50; x++)
938 
939  return bytes;
940 }
941 
942 /*!
943  * \brief Clean up phone string
944  * \details
945  * Remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
946  * Basically, remove anything that could be invalid in a pattern.
947  */
949 {
950  int x, y = 0;
951  int bracketed = 0;
952 
953  for (x = 0; n[x]; x++) {
954  switch (n[x]) {
955  case '[':
956  bracketed++;
957  n[y++] = n[x];
958  break;
959  case ']':
960  bracketed--;
961  n[y++] = n[x];
962  break;
963  case '-':
964  if (bracketed)
965  n[y++] = n[x];
966  break;
967  case '.':
968  if (!n[x+1])
969  n[y++] = n[x];
970  break;
971  default:
972  /* ignore parenthesis and whitespace */
973  if (!strchr("( )", n[x]))
974  n[y++] = n[x];
975  }
976  }
977  n[y] = '\0';
978 }
979 
980 /*!
981  * \brief Checks if phone number consists of valid characters
982  * \param exten String that needs to be checked
983  * \param valid Valid characters in string
984  * \retval 1 if valid string
985  * \retval 0 if string contains invalid characters
986  */
987 static int ast_is_valid_string(const char *exten, const char *valid)
988 {
989  int x;
990 
991  if (ast_strlen_zero(exten))
992  return 0;
993  for (x = 0; exten[x]; x++)
994  if (!strchr(valid, exten[x]))
995  return 0;
996  return 1;
997 }
998 
999 int ast_isphonenumber(const char *n)
1000 {
1001  return ast_is_valid_string(n, "0123456789*#+");
1002 }
1003 
1005 {
1006  return ast_is_valid_string(exten, "0123456789*#+()-.");
1007 }
1008 
1009 int ast_callerid_parse(char *input_str, char **name, char **location)
1010 {
1011  char *ls;
1012  char *le;
1013  char *name_start;
1014  char *instr;
1015  int quotes_stripped = 0;
1016 
1017  /* Handle surrounding quotes */
1018  input_str = ast_strip(input_str);
1019  instr = ast_strip_quoted(input_str, "\"", "\"");
1020  if (instr != input_str) {
1021  quotes_stripped = 1;
1022  }
1023 
1024  /* Try "name" <location> format or name <location> format or with a missing > */
1025  if ((ls = strrchr(instr, '<'))) {
1026  if ((le = strrchr(ls, '>'))) {
1027  *le = '\0'; /* location found, trim off the brackets */
1028  }
1029  *ls = '\0';
1030  *location = ls + 1; /* and this is the result */
1031 
1032  name_start = ast_strip_quoted(instr, "\"", "\"");
1033  } else { /* no valid brackets */
1034  char tmp[256];
1035 
1036  ast_copy_string(tmp, instr, sizeof(tmp));
1038  if (!quotes_stripped && ast_isphonenumber(tmp)) { /* Assume it's just a location */
1039  name_start = NULL;
1040  strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
1041  *location = instr;
1042  } else { /* Assume it's just a name. */
1043  *location = NULL;
1044  name_start = ast_strip_quoted(instr, "\"", "\"");
1045  }
1046  }
1047 
1048  if (name_start) {
1049  ast_unescape_quoted(name_start);
1050  }
1051  *name = name_start;
1052  return 0;
1053 }
1054 
1055 static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, format_t codec)
1056 {
1057  if (ast_strlen_zero(name))
1058  name = NULL;
1059  if (ast_strlen_zero(number))
1060  number = NULL;
1061  return callerid_generate(buf, number, name, 0, callwaiting, codec);
1062 }
1063 
1064 int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, format_t codec)
1065 {
1066  return __ast_callerid_generate(buf, name, number, 0, codec);
1067 }
1068 
1069 int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, format_t codec)
1070 {
1071  return __ast_callerid_generate(buf, name, number, 1, codec);
1072 }
1073 
1074 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
1075 {
1076  if (!unknown)
1077  unknown = "<unknown>";
1078  if (name && num) {
1079  char name_buf[128];
1080 
1081  ast_escape_quoted(name, name_buf, sizeof(name_buf));
1082  snprintf(buf, bufsiz, "\"%s\" <%s>", name_buf, num);
1083  } else if (name) {
1084  ast_copy_string(buf, name, bufsiz);
1085  } else if (num) {
1086  ast_copy_string(buf, num, bufsiz);
1087  } else {
1088  ast_copy_string(buf, unknown, bufsiz);
1089  }
1090  return buf;
1091 }
1092 
1093 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
1094 {
1095  char *tmp;
1096  char *l = NULL, *n = NULL;
1097 
1098  tmp = ast_strdupa(buf);
1099  ast_callerid_parse(tmp, &n, &l);
1100  if (n)
1101  ast_copy_string(name, n, namelen);
1102  else
1103  name[0] = '\0';
1104  if (l) {
1106  ast_copy_string(num, l, numlen);
1107  } else
1108  num[0] = '\0';
1109  return 0;
1110 }
1111 
1113  int value;
1114  const char *name;
1115  const char *description;
1116 };
1117 
1118 /*! \brief Translation table for Caller ID Presentation settings */
1119 static const struct ast_value_translation pres_types[] = {
1120 /* *INDENT-OFF* */
1121  { AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened" },
1122  { AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen" },
1123  { AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen" },
1124  { AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number" },
1125 
1126  { AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened" },
1127  { AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen" },
1128  { AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen" },
1129  { AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number" },
1130 
1131  { AST_PRES_UNAVAILABLE | AST_PRES_NETWORK_NUMBER, "unavailable", "Number Unavailable" }, /* Default name to value conversion. */
1132  { AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_UNSCREENED, "unavailable", "Number Unavailable" },
1133  { AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_FAILED_SCREEN, "unavailable", "Number Unavailable" },
1134  { AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_PASSED_SCREEN, "unavailable", "Number Unavailable" },
1135 /* *INDENT-ON* */
1136 };
1137 
1138 /*!
1139  * \brief Convert caller ID text code to value (used in config file parsing)
1140  * \param data text string from config file
1141  * \retval value AST_PRES_ from callerid.h
1142  * \retval -1 if not in table
1143  */
1144 int ast_parse_caller_presentation(const char *data)
1145 {
1146  int index;
1147  if (!data) {
1148  return -1;
1149  }
1150 
1151  for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1152  if (!strcasecmp(pres_types[index].name, data)) {
1153  return pres_types[index].value;
1154  }
1155  }
1156 
1157  return -1;
1158 }
1159 
1160 /*!
1161  * \brief Convert caller ID pres value to explanatory string
1162  * \param data AST_PRES_ value from callerid.h
1163  * \return string for human presentation
1164  */
1166 {
1167  int index;
1168 
1169  for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1170  if (pres_types[index].value == data) {
1171  return pres_types[index].description;
1172  }
1173  }
1174 
1175  return "unknown";
1176 }
1177 
1178 /*!
1179  * \brief Convert caller ID pres value to text code
1180  * \param data AST_PRES_ value from callerid.h
1181  * \return string for config file
1182  */
1183 const char *ast_named_caller_presentation(int data)
1184 {
1185  int index;
1186 
1187  for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1188  if (pres_types[index].value == data) {
1189  return pres_types[index].name;
1190  }
1191  }
1192 
1193  return "unknown";
1194 }
1195 
1196 /*! \brief Translation table for redirecting reason settings */
1198 /* *INDENT-OFF* */
1199  { AST_REDIRECTING_REASON_UNKNOWN, "unknown", "Unknown" },
1200  { AST_REDIRECTING_REASON_USER_BUSY, "cfb", "Call Forwarding Busy" },
1201  { AST_REDIRECTING_REASON_NO_ANSWER, "cfnr", "Call Forwarding No Reply" },
1202  { AST_REDIRECTING_REASON_UNAVAILABLE, "unavailable", "Callee is Unavailable" },
1203  { AST_REDIRECTING_REASON_UNCONDITIONAL, "cfu", "Call Forwarding Unconditional" },
1204  { AST_REDIRECTING_REASON_TIME_OF_DAY, "time_of_day", "Time of Day" },
1205  { AST_REDIRECTING_REASON_DO_NOT_DISTURB, "dnd", "Do Not Disturb" },
1206  { AST_REDIRECTING_REASON_DEFLECTION, "deflection", "Call Deflection" },
1207  { AST_REDIRECTING_REASON_FOLLOW_ME, "follow_me", "Follow Me" },
1208  { AST_REDIRECTING_REASON_OUT_OF_ORDER, "out_of_order", "Called DTE Out-Of-Order" },
1209  { AST_REDIRECTING_REASON_AWAY, "away", "Callee is Away" },
1210  { AST_REDIRECTING_REASON_CALL_FWD_DTE, "cf_dte", "Call Forwarding By The Called DTE" },
1211 /* *INDENT-ON* */
1212 };
1213 
1214 int ast_redirecting_reason_parse(const char *data)
1215 {
1216  int index;
1217 
1218  for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1219  if (!strcasecmp(redirecting_reason_types[index].name, data)) {
1220  return redirecting_reason_types[index].value;
1221  }
1222  }
1223 
1224  return -1;
1225 }
1226 
1227 const char *ast_redirecting_reason_describe(int data)
1228 {
1229  int index;
1230 
1231  for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1232  if (redirecting_reason_types[index].value == data) {
1233  return redirecting_reason_types[index].description;
1234  }
1235  }
1236 
1237  return "not-known";
1238 }
1239 
1240 const char *ast_redirecting_reason_name(int data)
1241 {
1242  int index;
1243 
1244  for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1245  if (redirecting_reason_types[index].value == data) {
1246  return redirecting_reason_types[index].name;
1247  }
1248  }
1249 
1250  return "not-known";
1251 }
1252 
1253 /*! \brief Translation table for connected line update source settings */
1255 /* *INDENT-OFF* */
1256  { AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, "unknown", "Unknown" },
1257  { AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, "answer", "Normal Call Answering" },
1258  { AST_CONNECTED_LINE_UPDATE_SOURCE_DIVERSION, "diversion", "Call Diversion (Deprecated, use REDIRECTING)" },
1259  { AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, "transfer_active", "Call Transfer(Active)" },
1260  { AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, "transfer", "Call Transfer(Active)" },/* Old name must come after new name. */
1261  { AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, "transfer_alerting", "Call Transfer(Alerting)" }
1262 /* *INDENT-ON* */
1263 };
1264 
1265 int ast_connected_line_source_parse(const char *data)
1266 {
1267  int index;
1268 
1269  for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1270  if (!strcasecmp(connected_line_source_types[index].name, data)) {
1271  return connected_line_source_types[index].value;
1272  }
1273  }
1274 
1275  return -1;
1276 }
1277 
1279 {
1280  int index;
1281 
1282  for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1283  if (connected_line_source_types[index].value == data) {
1284  return connected_line_source_types[index].description;
1285  }
1286  }
1287 
1288  return "not-known";
1289 }
1290 
1291 const char *ast_connected_line_source_name(int data)
1292 {
1293  int index;
1294 
1295  for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1296  if (connected_line_source_types[index].value == data) {
1297  return connected_line_source_types[index].name;
1298  }
1299  }
1300 
1301  return "not-known";
1302 }
1303 
1304 /*! \brief Translation table for ast_party_name char-set settings */
1306 /* *INDENT-OFF* */
1307  { AST_PARTY_CHAR_SET_UNKNOWN, "unknown", "Unknown" },
1308  { AST_PARTY_CHAR_SET_ISO8859_1, "iso8859-1", "ISO8859-1" },
1309  { AST_PARTY_CHAR_SET_WITHDRAWN, "withdrawn", "Withdrawn" },
1310  { AST_PARTY_CHAR_SET_ISO8859_2, "iso8859-2", "ISO8859-2" },
1311  { AST_PARTY_CHAR_SET_ISO8859_3, "iso8859-3", "ISO8859-3" },
1312  { AST_PARTY_CHAR_SET_ISO8859_4, "iso8859-4", "ISO8859-4" },
1313  { AST_PARTY_CHAR_SET_ISO8859_5, "iso8859-5", "ISO8859-5" },
1314  { AST_PARTY_CHAR_SET_ISO8859_7, "iso8859-7", "ISO8859-7" },
1315  { AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, "bmp", "ISO10646 Bmp String" },
1316  { AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, "utf8", "ISO10646 UTF-8 String" },
1317 /* *INDENT-ON* */
1318 };
1319 
1320 int ast_party_name_charset_parse(const char *data)
1321 {
1322  int index;
1323 
1324  for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1325  if (!strcasecmp(party_name_charset_tbl[index].name, data)) {
1326  return party_name_charset_tbl[index].value;
1327  }
1328  }
1329 
1330  return -1;
1331 }
1332 
1333 const char *ast_party_name_charset_describe(int data)
1334 {
1335  int index;
1336 
1337  for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1338  if (party_name_charset_tbl[index].value == data) {
1339  return party_name_charset_tbl[index].description;
1340  }
1341  }
1342 
1343  return "not-known";
1344 }
1345 
1346 const char *ast_party_name_charset_str(int data)
1347 {
1348  int index;
1349 
1350  for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1351  if (party_name_charset_tbl[index].value == data) {
1352  return party_name_charset_tbl[index].name;
1353  }
1354  }
1355 
1356  return "not-known";
1357 }
#define CALLERID_MARK
Definition: callerid.c:71
A-Law to Signed linear conversion.
#define CID_UNKNOWN_NUMBER
Definition: callerid.h:55
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define CID_MSGWAITING
Definition: callerid.h:56
static int ast_is_valid_string(const char *exten, const char *valid)
Checks if phone number consists of valid characters.
Definition: callerid.c:987
const char * ast_named_caller_presentation(int data)
Convert caller ID pres value to text code.
Definition: callerid.c:1183
static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, format_t codec)
Definition: callerid.c:1055
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_connected_line_source_parse(const char *data)
Convert connected line update source text code to value (used in config file parsing) ...
Definition: callerid.c:1265
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1093
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
float clidsb
Definition: callerid.c:66
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define CAS_FREQ1
Definition: callerid.c:73
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1165
int option_debug
Definition: asterisk.c:182
static int callwaiting
Definition: chan_mgcp.c:178
#define AST_XLAW(a)
Definition: callerid.h:79
const char * ast_connected_line_source_name(int data)
Convert connected line update source value to text code.
Definition: callerid.c:1291
unsigned short crc
Definition: callerid.c:61
#define LOG_WARNING
Definition: logger.h:144
float cid_di[4]
Definition: callerid.c:65
int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, format_t codec, const char *name, const char *number, int flags)
Generate message waiting indicator.
Definition: callerid.c:811
int ast_redirecting_reason_parse(const char *data)
Convert redirecting reason text code to value (used in config file parsing)
Definition: callerid.c:1214
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define CAS_FREQ2
Definition: callerid.c:74
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define CID_MWI_TYPE_MDMF_FULL
Definition: callerid.h:76
int pllids
Definition: fskmodem_int.h:60
int fskmodem_init(fsk_data *fskd)
Definition: fskmodem_int.c:197
float casdr1
Definition: callerid.c:68
int value
Definition: syslog.c:39
float sasdi
Definition: callerid.c:67
int ast_is_shrinkable_phonenumber(const char *exten)
Check if a string consists only of digits and and + # ( ) - . (meaning it can be cleaned with ast_shr...
Definition: callerid.c:1004
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
const char * ast_redirecting_reason_name(int data)
Convert redirecting reason value to text code.
Definition: callerid.c:1240
#define PUT_BYTE(a)
Definition: callerid.h:278
void callerid_get(struct callerid_state *cid, char **number, char **name, int *flags)
Extract info out of callerID state machine. Flags are listed above.
Definition: callerid.c:189
int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, format_t codec)
Generate Caller-ID spill from the &quot;callerid&quot; field of asterisk (in e-mail address like format) ...
Definition: callerid.c:1064
Utility functions.
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define M_PI
Number structure.
Definition: app_followme.c:109
float nstop
const char * description
Definition: callerid.c:1115
#define SAS_FREQ
Definition: callerid.c:72
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1431
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
u-Law to Signed linear conversion
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1074
void callerid_init(void)
CallerID Initialization.
Definition: callerid.c:116
General Asterisk PBX channel definitions.
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define CID_NOMSGWAITING
Definition: callerid.h:57
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define CID_PRIVATE_NAME
Definition: callerid.h:52
static struct ast_value_translation pres_types[]
Translation table for Caller ID Presentation settings.
Definition: callerid.c:1119
Asterisk internal frame definitions.
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
Definition: utils.c:461
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
int tm_mon
Definition: localtime.h:40
int ast_party_name_charset_parse(const char *data)
Convert ast_party_name.char_set text code to value (used in config file parsing)
Definition: callerid.c:1320
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, format_t codec)
Read samples into the state machine.
Definition: callerid.c:546
int tm_mday
Definition: localtime.h:39
int instop
Definition: fskmodem_int.h:46
int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, format_t codec)
Read samples into the state machine.
Definition: callerid.c:307
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1144
#define CID_PRIVATE_NUMBER
Definition: callerid.h:53
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, format_t codec)
Generates a CallerID FSK stream in ulaw format suitable for transmission.
Definition: callerid.c:899
#define LOG_ERROR
Definition: logger.h:155
int pllispb
Definition: fskmodem_int.h:59
char name[64]
Definition: callerid.c:54
int64_t format_t
Definition: frame_defs.h:32
int pllispb2
Definition: fskmodem_int.h:61
#define CALLERID_SPACE
Definition: callerid.c:70
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
Definition: callerid.c:740
#define AST_LIN2X(a)
Definition: callerid.h:78
#define LOG_NOTICE
Definition: logger.h:133
static void gen_tones(unsigned char *buf, int len, format_t codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
Definition: callerid.c:78
const char * ast_redirecting_reason_describe(int data)
Convert redirecting reason value to explanatory string.
Definition: callerid.c:1227
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
int ast_gen_cas(unsigned char *outbuf, int sas, int len, format_t codec)
Generate a CAS (CPE Alert Signal) tone for &#39;n&#39; samples.
Definition: callerid.c:262
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: utils.c:431
int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, format_t codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)&#39;s Caller*ID(tm) ...
Definition: callerid.c:1069
int f_space_idx
int ast_isphonenumber(const char *n)
Check if a string consists only of digits and + #.
Definition: callerid.c:999
static struct ast_value_translation redirecting_reason_types[]
Translation table for redirecting reason settings.
Definition: callerid.c:1197
float sasdr
Definition: callerid.c:67
int tm_hour
Definition: localtime.h:38
static const char type[]
Definition: chan_nbs.c:57
const char * ast_party_name_charset_str(int data)
Convert ast_party_name.char_set value to text code.
Definition: callerid.c:1346
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
Definition: callerid.c:735
#define PUT_CLID(byte)
Definition: callerid.h:304
short oldstuff[160]
Definition: callerid.c:49
static struct ast_value_translation connected_line_source_types[]
Translation table for connected line update source settings.
Definition: callerid.c:1254
#define PUT_CLID_MARKMS
Definition: callerid.h:289
continue
Definition: ast_expr2.c:1263
float casdr2
Definition: callerid.c:68
#define CID_UNKNOWN_NAME
Definition: callerid.h:54
#define ast_calloc(a, b)
Definition: astmm.h:82
float casdi2
Definition: callerid.c:68
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static void gen_tone(unsigned char *buf, int len, format_t codec, float ddr1, float ddi1, float *cr1, float *ci1)
Definition: callerid.c:100
static char org[80]
Definition: pbx_dundi.c:193
#define AST_PRES_ALLOWED
Definition: callerid.h:324
int f_mark_idx
#define CID_MWI_TYPE_MDMF
Definition: callerid.h:74
const char * ast_connected_line_source_describe(int data)
Convert connected line update source value to explanatory string.
Definition: callerid.c:1278
float casdi1
Definition: callerid.c:68
FSK Modem Support.
static struct ast_value_translation party_name_charset_tbl[]
Translation table for ast_party_name char-set settings.
Definition: callerid.c:1305
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:326
static unsigned short calc_crc(unsigned short crc, unsigned char data)
Definition: callerid.c:284
static unsigned int cos
Definition: chan_h323.c:147
void callerid_get_dtmf(char *cidstring, char *number, int *flags)
Get and parse DTMF-based callerid.
Definition: callerid.c:202
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:948
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
Definition: callerid.c:130
int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte)
char rawdata[256]
Definition: callerid.c:48
char number[64]
Definition: callerid.c:55
fsk_data fskd
Definition: callerid.c:47
const char * ast_party_name_charset_describe(int data)
Convert ast_party_name.char_set value to explanatory string.
Definition: callerid.c:1333
int tm_min
Definition: localtime.h:37
const char * name
Definition: callerid.c:1114
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
float cid_dr[4]
Definition: callerid.c:65
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009