Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


func_callerid.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999-2010, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16 
17 /*! \file
18  *
19  * \brief Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)
20  *
21  * \ingroup functions
22  *
23  * See Also:
24  * \arg \ref AstCREDITS
25  */
26 
27 /*** MODULEINFO
28  <support_level>core</support_level>
29  ***/
30 
31 #include "asterisk.h"
32 
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 411313 $")
34 
35 #include "asterisk/module.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/app.h"
40 #include "asterisk/callerid.h"
41 
42 /*
43  * Do not document the CALLERID(pres) datatype.
44  * The name and number now have their own presentation value. The pres
45  * option will simply live on as a historical relic with as best
46  * as can be managed backward compatible meaning.
47  *
48  * Do not document the CALLERID(ton) datatype.
49  * It is an alias for num-plan.
50  *
51  * Do not document the CALLERID(ANI-subaddr-...) datatype.
52  * This is not used.
53  *
54  * Do not document the CONNECTEDLINE(source) datatype.
55  * It has turned out to not be needed. The source value is really
56  * only useful as a possible tracing aid.
57  *
58  * Do not document the CONNECTEDLINE(pres) datatype.
59  * The name and number now have their own presentation value. The pres
60  * option will simply live on as a historical relic with as best
61  * as can be managed backward compatible meaning.
62  *
63  * Do not document the CONNECTEDLINE(ton) datatype.
64  * It is an alias for num-plan.
65  *
66  * Do not document the REDIRECTING(pres) datatype.
67  * It has turned out that the from-pres and to-pres values must be kept
68  * separate. They represent two different parties and there is a case when
69  * they are active at the same time. The plain pres option will simply
70  * live on as a historical relic.
71  *
72  * Do not document the REDIRECTING(from-pres) or REDIRECTING(to-pres) datatypes.
73  * The name and number now have their own presentation value. The from-pres
74  * and to-pres options will simply live on as a historical relic with as best
75  * as can be managed backward compatible meaning.
76  *
77  * Do not document the REDIRECTING(from-ton) or REDIRECTING(to-ton) datatypes.
78  * They are aliases for from-num-plan and to-num-plan respectively.
79  */
80 /*** DOCUMENTATION
81  <function name="CALLERID" language="en_US">
82  <synopsis>
83  Gets or sets Caller*ID data on the channel.
84  </synopsis>
85  <syntax>
86  <parameter name="datatype" required="true">
87  <para>The allowable datatypes are:</para>
88  <enumlist>
89  <enum name = "all" />
90  <enum name = "name" />
91  <enum name = "name-valid" />
92  <enum name = "name-charset" />
93  <enum name = "name-pres" />
94  <enum name = "num" />
95  <enum name = "num-valid" />
96  <enum name = "num-plan" />
97  <enum name = "num-pres" />
98  <enum name = "subaddr" />
99  <enum name = "subaddr-valid" />
100  <enum name = "subaddr-type" />
101  <enum name = "subaddr-odd" />
102  <enum name = "tag" />
103  <enum name = "ANI-all" />
104  <enum name = "ANI-name" />
105  <enum name = "ANI-name-valid" />
106  <enum name = "ANI-name-charset" />
107  <enum name = "ANI-name-pres" />
108  <enum name = "ANI-num" />
109  <enum name = "ANI-num-valid" />
110  <enum name = "ANI-num-plan" />
111  <enum name = "ANI-num-pres" />
112  <enum name = "ANI-tag" />
113  <enum name = "RDNIS" />
114  <enum name = "DNID" />
115  <enum name = "dnid-num-plan" />
116  <enum name = "dnid-subaddr" />
117  <enum name = "dnid-subaddr-valid" />
118  <enum name = "dnid-subaddr-type" />
119  <enum name = "dnid-subaddr-odd" />
120  </enumlist>
121  </parameter>
122  <parameter name="CID">
123  <para>Optional Caller*ID to parse instead of using the Caller*ID from the
124  channel. This parameter is only optional when reading the Caller*ID.</para>
125  </parameter>
126  </syntax>
127  <description>
128  <para>Gets or sets Caller*ID data on the channel. Uses channel callerid by
129  default or optional callerid, if specified.</para>
130  <para>The allowable values for the <replaceable>name-charset</replaceable>
131  field are the following:</para>
132  <enumlist>
133  <enum name = "unknown"><para>Unknown</para></enum>
134  <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
135  <enum name = "withdrawn"><para>Withdrawn</para></enum>
136  <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
137  <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
138  <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
139  <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
140  <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
141  <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
142  <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
143  </enumlist>
144  </description>
145  </function>
146  <function name="CALLERPRES" language="en_US">
147  <synopsis>
148  Gets or sets Caller*ID presentation on the channel.
149  </synopsis>
150  <syntax />
151  <description>
152  <para>Gets or sets Caller*ID presentation on the channel.
153  This function is deprecated in favor of CALLERID(num-pres)
154  and CALLERID(name-pres).
155  The following values are valid:</para>
156  <enumlist>
157  <enum name="allowed_not_screened">
158  <para>Presentation Allowed, Not Screened.</para>
159  </enum>
160  <enum name="allowed_passed_screen">
161  <para>Presentation Allowed, Passed Screen.</para>
162  </enum>
163  <enum name="allowed_failed_screen">
164  <para>Presentation Allowed, Failed Screen.</para>
165  </enum>
166  <enum name="allowed">
167  <para>Presentation Allowed, Network Number.</para>
168  </enum>
169  <enum name="prohib_not_screened">
170  <para>Presentation Prohibited, Not Screened.</para>
171  </enum>
172  <enum name="prohib_passed_screen">
173  <para>Presentation Prohibited, Passed Screen.</para>
174  </enum>
175  <enum name="prohib_failed_screen">
176  <para>Presentation Prohibited, Failed Screen.</para>
177  </enum>
178  <enum name="prohib">
179  <para>Presentation Prohibited, Network Number.</para>
180  </enum>
181  <enum name="unavailable">
182  <para>Number Unavailable.</para>
183  </enum>
184  </enumlist>
185  </description>
186  </function>
187  <function name="CONNECTEDLINE" language="en_US">
188  <synopsis>
189  Gets or sets Connected Line data on the channel.
190  </synopsis>
191  <syntax>
192  <parameter name="datatype" required="true">
193  <para>The allowable datatypes are:</para>
194  <enumlist>
195  <enum name = "all" />
196  <enum name = "name" />
197  <enum name = "name-valid" />
198  <enum name = "name-charset" />
199  <enum name = "name-pres" />
200  <enum name = "num" />
201  <enum name = "num-valid" />
202  <enum name = "num-plan" />
203  <enum name = "num-pres" />
204  <enum name = "subaddr" />
205  <enum name = "subaddr-valid" />
206  <enum name = "subaddr-type" />
207  <enum name = "subaddr-odd" />
208  <enum name = "tag" />
209  </enumlist>
210  </parameter>
211  <parameter name="i">
212  <para>If set, this will prevent the channel from sending out protocol
213  messages because of the value being set</para>
214  </parameter>
215  </syntax>
216  <description>
217  <para>Gets or sets Connected Line data on the channel.</para>
218  <para>The allowable values for the <replaceable>name-charset</replaceable>
219  field are the following:</para>
220  <enumlist>
221  <enum name = "unknown"><para>Unknown</para></enum>
222  <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
223  <enum name = "withdrawn"><para>Withdrawn</para></enum>
224  <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
225  <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
226  <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
227  <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
228  <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
229  <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
230  <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
231  </enumlist>
232  </description>
233  </function>
234  <function name="REDIRECTING" language="en_US">
235  <synopsis>
236  Gets or sets Redirecting data on the channel.
237  </synopsis>
238  <syntax>
239  <parameter name="datatype" required="true">
240  <para>The allowable datatypes are:</para>
241  <enumlist>
242  <enum name = "from-all" />
243  <enum name = "from-name" />
244  <enum name = "from-name-valid" />
245  <enum name = "from-name-charset" />
246  <enum name = "from-name-pres" />
247  <enum name = "from-num" />
248  <enum name = "from-num-valid" />
249  <enum name = "from-num-plan" />
250  <enum name = "from-num-pres" />
251  <enum name = "from-subaddr" />
252  <enum name = "from-subaddr-valid" />
253  <enum name = "from-subaddr-type" />
254  <enum name = "from-subaddr-odd" />
255  <enum name = "from-tag" />
256  <enum name = "to-all" />
257  <enum name = "to-name" />
258  <enum name = "to-name-valid" />
259  <enum name = "to-name-charset" />
260  <enum name = "to-name-pres" />
261  <enum name = "to-num" />
262  <enum name = "to-num-valid" />
263  <enum name = "to-num-plan" />
264  <enum name = "to-num-pres" />
265  <enum name = "to-subaddr" />
266  <enum name = "to-subaddr-valid" />
267  <enum name = "to-subaddr-type" />
268  <enum name = "to-subaddr-odd" />
269  <enum name = "to-tag" />
270  <enum name = "reason" />
271  <enum name = "count" />
272  </enumlist>
273  </parameter>
274  <parameter name="i">
275  <para>If set, this will prevent the channel from sending out protocol
276  messages because of the value being set</para>
277  </parameter>
278  </syntax>
279  <description>
280  <para>Gets or sets Redirecting data on the channel.</para>
281  <para>The allowable values for the <replaceable>reason</replaceable>
282  field are the following:</para>
283  <enumlist>
284  <enum name = "unknown"><para>Unknown</para></enum>
285  <enum name = "cfb"><para>Call Forwarding Busy</para></enum>
286  <enum name = "cfnr"><para>Call Forwarding No Reply</para></enum>
287  <enum name = "unavailable"><para>Callee is Unavailable</para></enum>
288  <enum name = "time_of_day"><para>Time of Day</para></enum>
289  <enum name = "dnd"><para>Do Not Disturb</para></enum>
290  <enum name = "deflection"><para>Call Deflection</para></enum>
291  <enum name = "follow_me"><para>Follow Me</para></enum>
292  <enum name = "out_of_order"><para>Called DTE Out-Of-Order</para></enum>
293  <enum name = "away"><para>Callee is Away</para></enum>
294  <enum name = "cf_dte"><para>Call Forwarding By The Called DTE</para></enum>
295  <enum name = "cfu"><para>Call Forwarding Unconditional</para></enum>
296  </enumlist>
297  <para>The allowable values for the <replaceable>xxx-name-charset</replaceable>
298  field are the following:</para>
299  <enumlist>
300  <enum name = "unknown"><para>Unknown</para></enum>
301  <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
302  <enum name = "withdrawn"><para>Withdrawn</para></enum>
303  <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
304  <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
305  <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
306  <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
307  <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
308  <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
309  <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
310  </enumlist>
311  </description>
312  </function>
313  ***/
314 
319 };
320 
322  AST_APP_ARG(member); /*!< Member name */
323  AST_APP_ARG(opts); /*!< Options token */
324  AST_APP_ARG(other); /*!< Any remining unused arguments */
325  );
326 
328  AST_APP_ARG(subnames[10]); /*!< Option member subnames */
329  );
330 
333 };
335  CONNECTED_LINE_OPT_DUMMY, /*!< Delete this if CONNECTED_LINE ever gets an option with parameters. */
336 
337  /*! \note This entry _MUST_ be the last one in the enum */
339 };
340 
344 
347 };
349  REDIRECTING_OPT_DUMMY, /*!< Delete this if REDIRECTING ever gets an option with parameters. */
350 
351  /*! \note This entry _MUST_ be the last one in the enum */
353 };
354 
358 
359 /*!
360  * \internal
361  * \brief Read values from the party name struct.
362  * \since 1.8
363  *
364  * \param buf Buffer to fill with read value.
365  * \param len Length of the buffer.
366  * \param argc Number of party member subnames.
367  * \param argv Party member subnames given.
368  * \param name Party name to get values from.
369  *
370  * \retval ID_FIELD_VALID on success.
371  * \retval ID_FIELD_UNKNOWN on unknown field name.
372  */
373 static enum ID_FIELD_STATUS party_name_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
374 {
375  enum ID_FIELD_STATUS status;
376 
377  status = ID_FIELD_VALID;
378 
379  if (argc == 0) {
380  /* We want the name string */
381  if (name->valid && name->str) {
382  ast_copy_string(buf, name->str, len);
383  }
384  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
385  snprintf(buf, len, "%d", name->valid);
386  } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
388  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
389  /* Accept pres[entation] */
391  } else {
392  status = ID_FIELD_UNKNOWN;
393  }
394 
395  return status;
396 }
397 
398 /*!
399  * \internal
400  * \brief Read values from the party number struct.
401  * \since 1.8
402  *
403  * \param buf Buffer to fill with read value.
404  * \param len Length of the buffer.
405  * \param argc Number of party member subnames.
406  * \param argv Party member subnames given.
407  * \param number Party number to get values from.
408  *
409  * \retval ID_FIELD_VALID on success.
410  * \retval ID_FIELD_UNKNOWN on unknown field name.
411  */
412 static enum ID_FIELD_STATUS party_number_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
413 {
414  enum ID_FIELD_STATUS status;
415 
416  status = ID_FIELD_VALID;
417 
418  if (argc == 0) {
419  /* We want the number string */
420  if (number->valid && number->str) {
421  ast_copy_string(buf, number->str, len);
422  }
423  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
424  snprintf(buf, len, "%d", number->valid);
425  } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
426  snprintf(buf, len, "%d", number->plan);
427  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
428  /* Accept pres[entation] */
430  } else {
431  status = ID_FIELD_UNKNOWN;
432  }
433 
434  return status;
435 }
436 
437 /*!
438  * \internal
439  * \brief Read values from the party subaddress struct.
440  * \since 1.8
441  *
442  * \param buf Buffer to fill with read value.
443  * \param len Length of the buffer.
444  * \param argc Number of party member subnames.
445  * \param argv Party member subnames given.
446  * \param subaddress Party subaddress to get values from.
447  *
448  * \retval ID_FIELD_VALID on success.
449  * \retval ID_FIELD_UNKNOWN on unknown field name.
450  */
451 static enum ID_FIELD_STATUS party_subaddress_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
452 {
453  enum ID_FIELD_STATUS status;
454 
455  status = ID_FIELD_VALID;
456 
457  if (argc == 0) {
458  /* We want the subaddress string */
459  if (subaddress->str) {
460  ast_copy_string(buf, subaddress->str, len);
461  }
462  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
463  snprintf(buf, len, "%d", subaddress->valid);
464  } else if (argc == 1 && !strcasecmp("type", argv[0])) {
465  snprintf(buf, len, "%d", subaddress->type);
466  } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
467  snprintf(buf, len, "%d", subaddress->odd_even_indicator);
468  } else {
469  status = ID_FIELD_UNKNOWN;
470  }
471 
472  return status;
473 }
474 
475 /*!
476  * \internal
477  * \brief Read values from the party id struct.
478  * \since 1.8
479  *
480  * \param buf Buffer to fill with read value.
481  * \param len Length of the buffer.
482  * \param argc Number of party member subnames.
483  * \param argv Party member subnames given.
484  * \param id Party id to get values from.
485  *
486  * \retval ID_FIELD_VALID on success.
487  * \retval ID_FIELD_UNKNOWN on unknown field name.
488  */
489 static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
490 {
491  enum ID_FIELD_STATUS status;
492 
493  if (argc == 0) {
494  /* Must have at least one subname. */
495  return ID_FIELD_UNKNOWN;
496  }
497 
498  status = ID_FIELD_VALID;
499 
500  if (argc == 1 && !strcasecmp("all", argv[0])) {
501  snprintf(buf, len, "\"%s\" <%s>",
502  S_COR(id->name.valid, id->name.str, ""),
503  S_COR(id->number.valid, id->number.str, ""));
504  } else if (!strcasecmp("name", argv[0])) {
505  status = party_name_read(buf, len, argc - 1, argv + 1, &id->name);
506  } else if (!strncasecmp("num", argv[0], 3)) {
507  /* Accept num[ber] */
508  status = party_number_read(buf, len, argc - 1, argv + 1, &id->number);
509  } else if (!strncasecmp("subaddr", argv[0], 7)) {
510  /* Accept subaddr[ess] */
511  status = party_subaddress_read(buf, len, argc - 1, argv + 1, &id->subaddress);
512  } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
513  if (id->tag) {
514  ast_copy_string(buf, id->tag, len);
515  }
516  } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
517  /* ton is an alias for num-plan */
518  snprintf(buf, len, "%d", id->number.plan);
519  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
520  /*
521  * Accept pres[entation]
522  * This is the combined name/number presentation.
523  */
524  ast_copy_string(buf,
526  } else {
527  status = ID_FIELD_UNKNOWN;
528  }
529 
530  return status;
531 }
532 
533 /*!
534  * \internal
535  * \brief Write new values to the party name struct
536  * \since 1.8
537  *
538  * \param name Party name struct to write values
539  * \param argc Number of party member subnames.
540  * \param argv Party member subnames given.
541  * \param value Value to assign to the party name.
542  *
543  * \retval ID_FIELD_VALID on success.
544  * \retval ID_FIELD_INVALID on error with field value.
545  * \retval ID_FIELD_UNKNOWN on unknown field name.
546  */
547 static enum ID_FIELD_STATUS party_name_write(struct ast_party_name *name, int argc, char *argv[], const char *value)
548 {
549  char *val;
550  enum ID_FIELD_STATUS status;
551 
552  status = ID_FIELD_VALID;
553 
554  if (argc == 0) {
555  /* We are setting the name string */
556  name->valid = 1;
557  name->str = ast_strdup(value);
558  ast_trim_blanks(name->str);
559  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
560  name->valid = atoi(value) ? 1 : 0;
561  } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
562  int char_set;
563 
564  val = ast_strdupa(value);
565  ast_trim_blanks(val);
566 
567  if (('0' <= val[0]) && (val[0] <= '9')) {
568  char_set = atoi(val);
569  } else {
570  char_set = ast_party_name_charset_parse(val);
571  }
572 
573  if (char_set < 0) {
575  "Unknown name char-set '%s', value unchanged\n", val);
576  status = ID_FIELD_INVALID;
577  } else {
578  name->char_set = char_set;
579  }
580  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
581  int pres;
582 
583  /* Accept pres[entation] */
584  val = ast_strdupa(value);
585  ast_trim_blanks(val);
586 
587  if (('0' <= val[0]) && (val[0] <= '9')) {
588  pres = atoi(val);
589  } else {
590  pres = ast_parse_caller_presentation(val);
591  }
592 
593  if (pres < 0) {
595  "Unknown name presentation '%s', value unchanged\n", val);
596  status = ID_FIELD_INVALID;
597  } else {
598  name->presentation = pres;
599  }
600  } else {
601  status = ID_FIELD_UNKNOWN;
602  }
603 
604  return status;
605 }
606 
607 /*!
608  * \internal
609  * \brief Write new values to the party number struct
610  * \since 1.8
611  *
612  * \param number Party number struct to write values
613  * \param argc Number of party member subnames.
614  * \param argv Party member subnames given.
615  * \param value Value to assign to the party number.
616  *
617  * \retval ID_FIELD_VALID on success.
618  * \retval ID_FIELD_INVALID on error with field value.
619  * \retval ID_FIELD_UNKNOWN on unknown field name.
620  */
621 static enum ID_FIELD_STATUS party_number_write(struct ast_party_number *number, int argc, char *argv[], const char *value)
622 {
623  char *val;
624  enum ID_FIELD_STATUS status;
625 
626  status = ID_FIELD_VALID;
627 
628  if (argc == 0) {
629  /* We are setting the number string */
630  number->valid = 1;
631  number->str = ast_strdup(value);
632  ast_trim_blanks(number->str);
633  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
634  number->valid = atoi(value) ? 1 : 0;
635  } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
636  val = ast_strdupa(value);
637  ast_trim_blanks(val);
638 
639  if (('0' <= val[0]) && (val[0] <= '9')) {
640  number->plan = atoi(val);
641  } else {
643  "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
644  status = ID_FIELD_INVALID;
645  }
646  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
647  int pres;
648 
649  /* Accept pres[entation] */
650  val = ast_strdupa(value);
651  ast_trim_blanks(val);
652 
653  if (('0' <= val[0]) && (val[0] <= '9')) {
654  pres = atoi(val);
655  } else {
656  pres = ast_parse_caller_presentation(val);
657  }
658 
659  if (pres < 0) {
661  "Unknown number presentation '%s', value unchanged\n", val);
662  status = ID_FIELD_INVALID;
663  } else {
664  number->presentation = pres;
665  }
666  } else {
667  status = ID_FIELD_UNKNOWN;
668  }
669 
670  return status;
671 }
672 
673 /*!
674  * \internal
675  * \brief Write new values to the party subaddress struct
676  * \since 1.8
677  *
678  * \param subaddress Party subaddress struct to write values
679  * \param argc Number of party member subnames.
680  * \param argv Party member subnames given.
681  * \param value Value to assign to the party subaddress.
682  *
683  * \retval ID_FIELD_VALID on success.
684  * \retval ID_FIELD_INVALID on error with field value.
685  * \retval ID_FIELD_UNKNOWN on unknown field name.
686  */
687 static enum ID_FIELD_STATUS party_subaddress_write(struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
688 {
689  enum ID_FIELD_STATUS status;
690 
691  status = ID_FIELD_VALID;
692 
693  if (argc == 0) {
694  /* We are setting the subaddress string */
695  subaddress->str = ast_strdup(value);
696  ast_trim_blanks(subaddress->str);
697  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
698  subaddress->valid = atoi(value) ? 1 : 0;
699  } else if (argc == 1 && !strcasecmp("type", argv[0])) {
700  subaddress->type = atoi(value) ? 2 : 0;
701  } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
702  subaddress->odd_even_indicator = atoi(value) ? 1 : 0;
703  } else {
704  status = ID_FIELD_UNKNOWN;
705  }
706 
707  return status;
708 }
709 
710 /*!
711  * \internal
712  * \brief Write new values to the party id struct
713  * \since 1.8
714  *
715  * \param id Party ID struct to write values
716  * \param argc Number of party member subnames.
717  * \param argv Party member subnames given.
718  * \param value Value to assign to the party id.
719  *
720  * \retval ID_FIELD_VALID on success.
721  * \retval ID_FIELD_INVALID on error with field value.
722  * \retval ID_FIELD_UNKNOWN on unknown field name.
723  */
724 static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
725 {
726  char *val;
727  enum ID_FIELD_STATUS status;
728 
729  if (argc == 0) {
730  /* Must have at least one subname. */
731  return ID_FIELD_UNKNOWN;
732  }
733 
734  status = ID_FIELD_VALID;
735 
736  if (argc == 1 && !strcasecmp("all", argv[0])) {
737  char name[256];
738  char num[256];
739 
740  ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
741  id->name.valid = 1;
742  id->name.str = ast_strdup(name);
743  if (!id->name.str) {
744  return ID_FIELD_INVALID;
745  }
746  id->number.valid = 1;
747  id->number.str = ast_strdup(num);
748  if (!id->number.str) {
749  return ID_FIELD_INVALID;
750  }
751  } else if (!strcasecmp("name", argv[0])) {
752  status = party_name_write(&id->name, argc - 1, argv + 1, value);
753  } else if (!strncasecmp("num", argv[0], 3)) {
754  /* Accept num[ber] */
755  status = party_number_write(&id->number, argc - 1, argv + 1, value);
756  } else if (!strncasecmp("subaddr", argv[0], 7)) {
757  /* Accept subaddr[ess] */
758  status = party_subaddress_write(&id->subaddress, argc - 1, argv + 1, value);
759  } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
760  id->tag = ast_strdup(value);
761  ast_trim_blanks(id->tag);
762  } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
763  /* ton is an alias for num-plan */
764  argv[0] = "plan";
765  status = party_number_write(&id->number, argc, argv, value);
766  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
767  int pres;
768 
769  /*
770  * Accept pres[entation]
771  * This is the combined name/number presentation.
772  */
773  val = ast_strdupa(value);
774  ast_trim_blanks(val);
775 
776  if (('0' <= val[0]) && (val[0] <= '9')) {
777  pres = atoi(val);
778  } else {
779  pres = ast_parse_caller_presentation(val);
780  }
781 
782  if (pres < 0) {
784  "Unknown combined presentation '%s', value unchanged\n", val);
785  status = ID_FIELD_INVALID;
786  } else {
787  id->name.presentation = pres;
788  id->number.presentation = pres;
789  }
790  } else {
791  status = ID_FIELD_UNKNOWN;
792  }
793 
794  return status;
795 }
796 
797 /*! TRUE if we have already notified about CALLERPRES being deprecated. */
799 
800 /*!
801  * \internal
802  * \brief Read values from the caller-id presentation information struct.
803  *
804  * \param chan Asterisk channel to read
805  * \param cmd Not used
806  * \param data Caller-id presentation function datatype string
807  * \param buf Buffer to fill with read value.
808  * \param len Length of the buffer
809  *
810  * \retval 0 on success.
811  * \retval -1 on error.
812  */
813 static int callerpres_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
814 {
815  if (!chan) {
816  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
817  return -1;
818  }
819 
820  if (!callerpres_deprecate_notify) {
821  callerpres_deprecate_notify = 1;
822  ast_log(LOG_WARNING, "CALLERPRES is deprecated."
823  " Use CALLERID(name-pres) or CALLERID(num-pres) instead.\n");
824  }
825  ast_copy_string(buf,
827  return 0;
828 }
829 
830 /*!
831  * \internal
832  * \brief Write new values to the caller-id presentation information struct.
833  *
834  * \param chan Asterisk channel to update
835  * \param cmd Not used
836  * \param data Caller-id presentation function datatype string
837  * \param value Value to assign to the caller-id presentation information struct.
838  *
839  * \retval 0 on success.
840  * \retval -1 on error.
841  */
842 static int callerpres_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
843 {
844  int pres;
845 
846  if (!chan) {
847  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
848  return -1;
849  }
850 
851  if (!callerpres_deprecate_notify) {
852  callerpres_deprecate_notify = 1;
853  ast_log(LOG_WARNING, "CALLERPRES is deprecated."
854  " Use CALLERID(name-pres) or CALLERID(num-pres) instead.\n");
855  }
856 
857  pres = ast_parse_caller_presentation(value);
858  if (pres < 0) {
859  ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show function CALLERPRES')\n", value);
860  } else {
861  chan->caller.id.name.presentation = pres;
862  chan->caller.id.number.presentation = pres;
863  }
864  return 0;
865 }
866 
867 /*!
868  * \internal
869  * \brief Read values from the caller-id information struct.
870  *
871  * \param chan Asterisk channel to read
872  * \param cmd Not used
873  * \param data Caller-id function datatype string
874  * \param buf Buffer to fill with read value.
875  * \param len Length of the buffer
876  *
877  * \retval 0 on success.
878  * \retval -1 on error.
879  */
880 static int callerid_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
881 {
882  enum ID_FIELD_STATUS status;
883  char *parms;
884  struct ast_party_members member;
886  AST_APP_ARG(member); /*!< Member name */
887  AST_APP_ARG(cid); /*!< Optional caller id to parse instead of from the channel. */
888  );
889 
890  /* Ensure that the buffer is empty */
891  *buf = 0;
892 
893  if (!chan) {
894  return -1;
895  }
896 
897  parms = ast_strdupa(data);
898  AST_STANDARD_APP_ARGS(args, parms);
899  if (args.argc == 0) {
900  /* Must have at least one argument. */
901  return -1;
902  }
903 
904  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
905  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
906  /* Too few or too many subnames */
907  return -1;
908  }
909 
910  if (args.argc == 2) {
911  char name[80];
912  char num[80];
913 
914  ast_callerid_split(args.cid, name, sizeof(name), num, sizeof(num));
915 
916  if (member.argc == 1 && !strcasecmp("all", member.argv[0])) {
917  snprintf(buf, len, "\"%s\" <%s>", name, num);
918  } else if (member.argc == 1 && !strcasecmp("name", member.argv[0])) {
919  ast_copy_string(buf, name, len);
920  } else if (member.argc == 1 && !strncasecmp("num", member.argv[0], 3)) {
921  /* Accept num[ber] */
922  ast_copy_string(buf, num, len);
923  } else {
924  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
925  }
926  } else {
927  ast_channel_lock(chan);
928 
929  if (member.argc == 1 && !strcasecmp("rdnis", member.argv[0])) {
930  if (chan->redirecting.from.number.valid
931  && chan->redirecting.from.number.str) {
932  ast_copy_string(buf, chan->redirecting.from.number.str, len);
933  }
934  } else if (!strcasecmp("dnid", member.argv[0])) {
935  if (member.argc == 1) {
936  /* Setup as if user had given dnid-num instead. */
937  member.argc = 2;
938  member.argv[1] = "num";
939  }
940  if (!strncasecmp("num", member.argv[1], 3)) {
941  /*
942  * Accept num[ber]
943  * dnid-num...
944  */
945  if (member.argc == 2) {
946  /* dnid-num */
947  if (chan->dialed.number.str) {
948  ast_copy_string(buf, chan->dialed.number.str, len);
949  }
950  } else if (member.argc == 3 && !strcasecmp("plan", member.argv[2])) {
951  /* dnid-num-plan */
952  snprintf(buf, len, "%d", chan->dialed.number.plan);
953  } else {
954  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
955  }
956  } else if (!strncasecmp("subaddr", member.argv[1], 7)) {
957  /*
958  * Accept subaddr[ess]
959  * dnid-subaddr...
960  */
961  status = party_subaddress_read(buf, len, member.argc - 2, member.argv + 2,
962  &chan->dialed.subaddress);
963  switch (status) {
964  case ID_FIELD_VALID:
965  case ID_FIELD_INVALID:
966  break;
967  default:
968  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
969  break;
970  }
971  } else {
972  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
973  }
974  } else if (member.argc == 1 && !strcasecmp("ani2", member.argv[0])) {
975  snprintf(buf, len, "%d", chan->caller.ani2);
976  } else if (!strcasecmp("ani", member.argv[0])) {
977  if (member.argc == 1) {
978  /* Setup as if user had given ani-num instead. */
979  member.argc = 2;
980  member.argv[1] = "num";
981  }
982  status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
983  &chan->caller.ani);
984  switch (status) {
985  case ID_FIELD_VALID:
986  case ID_FIELD_INVALID:
987  break;
988  default:
989  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
990  break;
991  }
992  } else {
993  status = party_id_read(buf, len, member.argc, member.argv, &chan->caller.id);
994  switch (status) {
995  case ID_FIELD_VALID:
996  case ID_FIELD_INVALID:
997  break;
998  default:
999  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1000  break;
1001  }
1002  }
1003 
1004  ast_channel_unlock(chan);
1005  }
1006 
1007  return 0;
1008 }
1009 
1010 /*!
1011  * \internal
1012  * \brief Write new values to the caller-id information struct.
1013  *
1014  * \param chan Asterisk channel to update
1015  * \param cmd Not used
1016  * \param data Caller-id function datatype string
1017  * \param value Value to assign to the caller-id information struct.
1018  *
1019  * \retval 0 on success.
1020  * \retval -1 on error.
1021  */
1022 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1023 {
1024  struct ast_party_caller caller;
1025  struct ast_party_dialed dialed;
1026  enum ID_FIELD_STATUS status;
1027  char *val;
1028  char *parms;
1029  struct ast_party_func_args args;
1030  struct ast_party_members member;
1031 
1032  if (!value || !chan) {
1033  return -1;
1034  }
1035 
1036  parms = ast_strdupa(data);
1037  AST_STANDARD_APP_ARGS(args, parms);
1038  if (args.argc == 0) {
1039  /* Must have at least one argument. */
1040  return -1;
1041  }
1042 
1043  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1044  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1045  /* Too few or too many subnames */
1046  return -1;
1047  }
1048 
1049  value = ast_skip_blanks(value);
1050 
1051  ast_channel_lock(chan);
1052  if (member.argc == 1 && !strcasecmp("rdnis", member.argv[0])) {
1053  chan->redirecting.from.number.valid = 1;
1055  chan->redirecting.from.number.str = ast_strdup(value);
1056  if (chan->cdr) {
1057  ast_cdr_setcid(chan->cdr, chan);
1058  }
1059  } else if (!strcasecmp("dnid", member.argv[0])) {
1060  ast_party_dialed_set_init(&dialed, &chan->dialed);
1061  if (member.argc == 1) {
1062  /* Setup as if user had given dnid-num instead. */
1063  member.argc = 2;
1064  member.argv[1] = "num";
1065  }
1066  if (!strncasecmp("num", member.argv[1], 3)) {
1067  /*
1068  * Accept num[ber]
1069  * dnid-num...
1070  */
1071  if (member.argc == 2) {
1072  /* dnid-num */
1073  dialed.number.str = ast_strdup(value);
1074  ast_trim_blanks(dialed.number.str);
1075  ast_party_dialed_set(&chan->dialed, &dialed);
1076  if (chan->cdr) {
1077  ast_cdr_setcid(chan->cdr, chan);
1078  }
1079  } else if (member.argc == 3 && !strcasecmp("plan", member.argv[2])) {
1080  /* dnid-num-plan */
1081  val = ast_strdupa(value);
1082  ast_trim_blanks(val);
1083 
1084  if (('0' <= val[0]) && (val[0] <= '9')) {
1085  chan->dialed.number.plan = atoi(val);
1086  if (chan->cdr) {
1087  ast_cdr_setcid(chan->cdr, chan);
1088  }
1089  } else {
1091  "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
1092  }
1093  } else {
1094  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1095  }
1096  } else if (!strncasecmp("subaddr", member.argv[1], 7)) {
1097  /*
1098  * Accept subaddr[ess]
1099  * dnid-subaddr...
1100  */
1101  status = party_subaddress_write(&dialed.subaddress, member.argc - 2,
1102  member.argv + 2, value);
1103  switch (status) {
1104  case ID_FIELD_VALID:
1105  ast_party_dialed_set(&chan->dialed, &dialed);
1106  if (chan->cdr) {
1107  ast_cdr_setcid(chan->cdr, chan);
1108  }
1109  break;
1110  case ID_FIELD_INVALID:
1111  break;
1112  default:
1113  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1114  break;
1115  }
1116  } else {
1117  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1118  }
1119  ast_party_dialed_free(&dialed);
1120  } else if (member.argc == 1 && !strcasecmp("ani2", member.argv[0])) {
1121  val = ast_strdupa(value);
1122  ast_trim_blanks(val);
1123 
1124  if (('0' <= val[0]) && (val[0] <= '9')) {
1125  chan->caller.ani2 = atoi(val);
1126  if (chan->cdr) {
1127  ast_cdr_setcid(chan->cdr, chan);
1128  }
1129  } else {
1130  ast_log(LOG_ERROR, "Unknown callerid ani2 '%s', value unchanged\n", val);
1131  }
1132  } else if (!strcasecmp("ani", member.argv[0])) {
1133  ast_party_caller_set_init(&caller, &chan->caller);
1134  if (member.argc == 1) {
1135  /* Setup as if user had given ani-num instead. */
1136  member.argc = 2;
1137  member.argv[1] = "num";
1138  }
1139  status = party_id_write(&caller.ani, member.argc - 1, member.argv + 1, value);
1140  switch (status) {
1141  case ID_FIELD_VALID:
1142  ast_party_caller_set(&chan->caller, &caller, NULL);
1143  if (chan->cdr) {
1144  ast_cdr_setcid(chan->cdr, chan);
1145  }
1146  break;
1147  case ID_FIELD_INVALID:
1148  break;
1149  default:
1150  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1151  break;
1152  }
1153  ast_party_caller_free(&caller);
1154  } else {
1155  ast_party_caller_set_init(&caller, &chan->caller);
1156  status = party_id_write(&caller.id, member.argc, member.argv, value);
1157  switch (status) {
1158  case ID_FIELD_VALID:
1159  ast_channel_set_caller_event(chan, &caller, NULL);
1160  if (chan->cdr) {
1161  ast_cdr_setcid(chan->cdr, chan);
1162  }
1163  break;
1164  case ID_FIELD_INVALID:
1165  break;
1166  default:
1167  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1168  break;
1169  }
1170  ast_party_caller_free(&caller);
1171  }
1172  ast_channel_unlock(chan);
1173 
1174  return 0;
1175 }
1176 
1177 /*!
1178  * \internal
1179  * \brief Read values from the connected line information struct.
1180  *
1181  * \param chan Asterisk channel to read
1182  * \param cmd Not used
1183  * \param data Connected line function datatype string
1184  * \param buf Buffer to fill with read value.
1185  * \param len Length of the buffer
1186  *
1187  * \retval 0 on success.
1188  * \retval -1 on error.
1189  */
1190 static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1191 {
1192  struct ast_party_members member;
1193  char *read_what;
1194  enum ID_FIELD_STATUS status;
1195 
1196  /* Ensure that the buffer is empty */
1197  *buf = 0;
1198 
1199  if (!chan) {
1200  return -1;
1201  }
1202 
1203  read_what = ast_strdupa(data);
1204  AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
1205  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1206  /* Too few or too many subnames */
1207  return -1;
1208  }
1209 
1210  ast_channel_lock(chan);
1211 
1212  if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
1214  } else {
1215  status = party_id_read(buf, len, member.argc, member.argv, &chan->connected.id);
1216  switch (status) {
1217  case ID_FIELD_VALID:
1218  case ID_FIELD_INVALID:
1219  break;
1220  default:
1221  ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1222  break;
1223  }
1224  }
1225 
1226  ast_channel_unlock(chan);
1227 
1228  return 0;
1229 }
1230 
1231 /*!
1232  * \internal
1233  * \brief Write new values to the connected line information struct.
1234  *
1235  * \param chan Asterisk channel to update
1236  * \param cmd Not used
1237  * \param data Connected line function datatype string
1238  * \param value Value to assign to the connected line information struct.
1239  *
1240  * \retval 0 on success.
1241  * \retval -1 on error.
1242  */
1243 static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1244 {
1245  struct ast_party_connected_line connected;
1246  enum ID_FIELD_STATUS status;
1247  char *val;
1248  char *parms;
1249  void (*set_it)(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
1250  struct ast_party_func_args args;
1251  struct ast_party_members member;
1252  struct ast_flags opts;
1253  char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
1254 
1255  if (!value || !chan) {
1256  return -1;
1257  }
1258 
1259  parms = ast_strdupa(data);
1260  AST_STANDARD_APP_ARGS(args, parms);
1261  if (args.argc == 0) {
1262  /* Must have at least one argument. */
1263  return -1;
1264  }
1265 
1266  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1267  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1268  /* Too few or too many subnames */
1269  return -1;
1270  }
1271 
1272  if (ast_app_parse_options(connectedline_opts, &opts, opt_args, args.opts)) {
1273  /* General invalid option syntax. */
1274  return -1;
1275  }
1276 
1277  /* Determine if the update indication inhibit option is present */
1280  } else {
1282  }
1283 
1284  ast_channel_lock(chan);
1285  ast_party_connected_line_set_init(&connected, &chan->connected);
1286  ast_channel_unlock(chan);
1287 
1288  value = ast_skip_blanks(value);
1289 
1290  if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
1291  int source;
1292 
1293  val = ast_strdupa(value);
1294  ast_trim_blanks(val);
1295 
1296  if (('0' <= val[0]) && (val[0] <= '9')) {
1297  source = atoi(val);
1298  } else {
1299  source = ast_connected_line_source_parse(val);
1300  }
1301 
1302  if (source < 0) {
1303  ast_log(LOG_ERROR, "Unknown connectedline source '%s', value unchanged\n", val);
1304  } else {
1305  connected.source = source;
1306  set_it(chan, &connected, NULL);
1307  }
1308  } else {
1309  status = party_id_write(&connected.id, member.argc, member.argv, value);
1310  switch (status) {
1311  case ID_FIELD_VALID:
1312  set_it(chan, &connected, NULL);
1313  break;
1314  case ID_FIELD_INVALID:
1315  break;
1316  default:
1317  ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1318  break;
1319  }
1320  ast_party_connected_line_free(&connected);
1321  }
1322 
1323  return 0;
1324 }
1325 
1326 /*!
1327  * \internal
1328  * \brief Read values from the redirecting information struct.
1329  *
1330  * \param chan Asterisk channel to read
1331  * \param cmd Not used
1332  * \param data Redirecting function datatype string
1333  * \param buf Buffer to fill with read value.
1334  * \param len Length of the buffer
1335  *
1336  * \retval 0 on success.
1337  * \retval -1 on error.
1338  */
1339 static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1340 {
1341  struct ast_party_members member;
1342  char *read_what;
1343  enum ID_FIELD_STATUS status;
1344 
1345  /* Ensure that the buffer is empty */
1346  *buf = 0;
1347 
1348  if (!chan) {
1349  return -1;
1350  }
1351 
1352  read_what = ast_strdupa(data);
1353  AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
1354  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1355  /* Too few or too many subnames */
1356  return -1;
1357  }
1358 
1359  ast_channel_lock(chan);
1360 
1361  if (!strcasecmp("from", member.argv[0])) {
1362  status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
1363  &chan->redirecting.from);
1364  switch (status) {
1365  case ID_FIELD_VALID:
1366  case ID_FIELD_INVALID:
1367  break;
1368  default:
1369  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1370  break;
1371  }
1372  } else if (!strcasecmp("to", member.argv[0])) {
1373  status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
1374  &chan->redirecting.to);
1375  switch (status) {
1376  case ID_FIELD_VALID:
1377  case ID_FIELD_INVALID:
1378  break;
1379  default:
1380  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1381  break;
1382  }
1383  } else if (member.argc == 1 && !strncasecmp("pres", member.argv[0], 4)) {
1384  /*
1385  * Accept pres[entation]
1386  * This is the combined from name/number presentation.
1387  */
1388  ast_copy_string(buf,
1391  } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) {
1393  } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
1394  snprintf(buf, len, "%d", chan->redirecting.count);
1395  } else {
1396  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1397  }
1398 
1399  ast_channel_unlock(chan);
1400 
1401  return 0;
1402 }
1403 
1404 /*!
1405  * \internal
1406  * \brief Write new values to the redirecting information struct.
1407  *
1408  * \param chan Asterisk channel to update
1409  * \param cmd Not used
1410  * \param data Redirecting function datatype string
1411  * \param value Value to assign to the redirecting information struct.
1412  *
1413  * \retval 0 on success.
1414  * \retval -1 on error.
1415  */
1416 static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1417 {
1418  struct ast_party_redirecting redirecting;
1419  enum ID_FIELD_STATUS status;
1420  char *val;
1421  char *parms;
1422  void (*set_it)(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
1423  struct ast_party_func_args args;
1424  struct ast_party_members member;
1425  struct ast_flags opts;
1426  char *opt_args[REDIRECTING_OPT_ARG_ARRAY_SIZE];
1427 
1428  if (!value || !chan) {
1429  return -1;
1430  }
1431 
1432  parms = ast_strdupa(data);
1433  AST_STANDARD_APP_ARGS(args, parms);
1434  if (args.argc == 0) {
1435  /* Must have at least one argument. */
1436  return -1;
1437  }
1438 
1439  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1440  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1441  /* Too few or too many subnames */
1442  return -1;
1443  }
1444 
1445  if (ast_app_parse_options(redirecting_opts, &opts, opt_args, args.opts)) {
1446  /* General invalid option syntax. */
1447  return -1;
1448  }
1449 
1450  /* Determine if the update indication inhibit option is present */
1451  if (ast_test_flag(&opts, REDIRECTING_OPT_INHIBIT)) {
1452  set_it = ast_channel_set_redirecting;
1453  } else {
1455  }
1456 
1457  ast_channel_lock(chan);
1458  ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
1459  ast_channel_unlock(chan);
1460 
1461  value = ast_skip_blanks(value);
1462 
1463  if (!strcasecmp("from", member.argv[0])) {
1464  status = party_id_write(&redirecting.from, member.argc - 1, member.argv + 1,
1465  value);
1466  switch (status) {
1467  case ID_FIELD_VALID:
1468  set_it(chan, &redirecting, NULL);
1469  break;
1470  case ID_FIELD_INVALID:
1471  break;
1472  default:
1473  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1474  break;
1475  }
1476  ast_party_redirecting_free(&redirecting);
1477  } else if (!strcasecmp("to", member.argv[0])) {
1478  status = party_id_write(&redirecting.to, member.argc - 1, member.argv + 1, value);
1479  switch (status) {
1480  case ID_FIELD_VALID:
1481  set_it(chan, &redirecting, NULL);
1482  break;
1483  case ID_FIELD_INVALID:
1484  break;
1485  default:
1486  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1487  break;
1488  }
1489  ast_party_redirecting_free(&redirecting);
1490  } else if (member.argc == 1 && !strncasecmp("pres", member.argv[0], 4)) {
1491  int pres;
1492 
1493  val = ast_strdupa(value);
1494  ast_trim_blanks(val);
1495 
1496  if (('0' <= val[0]) && (val[0] <= '9')) {
1497  pres = atoi(val);
1498  } else {
1499  pres = ast_parse_caller_presentation(val);
1500  }
1501 
1502  if (pres < 0) {
1504  "Unknown redirecting combined presentation '%s', value unchanged\n", val);
1505  } else {
1506  redirecting.from.name.presentation = pres;
1507  redirecting.from.number.presentation = pres;
1508  redirecting.to.name.presentation = pres;
1509  redirecting.to.number.presentation = pres;
1510  set_it(chan, &redirecting, NULL);
1511  }
1512  } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) {
1513  int reason;
1514 
1515  val = ast_strdupa(value);
1516  ast_trim_blanks(val);
1517 
1518  if (('0' <= val[0]) && (val[0] <= '9')) {
1519  reason = atoi(val);
1520  } else {
1521  reason = ast_redirecting_reason_parse(val);
1522  }
1523 
1524  if (reason < 0) {
1525  ast_log(LOG_ERROR, "Unknown redirecting reason '%s', value unchanged\n", val);
1526  } else {
1527  redirecting.reason = reason;
1528  set_it(chan, &redirecting, NULL);
1529  }
1530  } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
1531  val = ast_strdupa(value);
1532  ast_trim_blanks(val);
1533 
1534  if (('0' <= val[0]) && (val[0] <= '9')) {
1535  redirecting.count = atoi(val);
1536  set_it(chan, &redirecting, NULL);
1537  } else {
1538  ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
1539  }
1540  } else {
1541  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1542  }
1543 
1544  return 0;
1545 }
1546 
1548  .name = "CALLERID",
1549  .read = callerid_read,
1550  .read_max = 256,
1551  .write = callerid_write,
1552 };
1553 
1555  .name = "CALLERPRES",
1556  .read = callerpres_read,
1557  .read_max = 50,
1558  .write = callerpres_write,
1559 };
1560 
1562  .name = "CONNECTEDLINE",
1563  .read = connectedline_read,
1564  .write = connectedline_write,
1565 };
1566 
1568  .name = "REDIRECTING",
1569  .read = redirecting_read,
1570  .write = redirecting_write,
1571 };
1572 
1573 /*!
1574  * \internal
1575  * \brief Unload the function module
1576  *
1577  * \retval 0 on success.
1578  * \retval -1 on error.
1579  */
1580 static int unload_module(void)
1581 {
1582  int res;
1583 
1584  res = ast_custom_function_unregister(&callerpres_function);
1585  res |= ast_custom_function_unregister(&callerid_function);
1586  res |= ast_custom_function_unregister(&connectedline_function);
1587  res |= ast_custom_function_unregister(&redirecting_function);
1588  return res;
1589 }
1590 
1591 /*!
1592  * \internal
1593  * \brief Load and initialize the function module.
1594  *
1595  * \retval AST_MODULE_LOAD_SUCCESS on success.
1596  * \retval AST_MODULE_LOAD_DECLINE on error.
1597  */
1598 static int load_module(void)
1599 {
1600  int res;
1601 
1602  res = ast_custom_function_register(&callerpres_function);
1603  res |= ast_custom_function_register(&callerid_function);
1604  res |= ast_custom_function_register(&connectedline_function);
1605  res |= ast_custom_function_register(&redirecting_function);
1607 }
1608 
1609 /* Do not wrap the following line. */
1610 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)");
static enum ID_FIELD_STATUS party_subaddress_write(struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
Information needed to identify an endpoint in a call.
Definition: channel.h:288
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:227
#define ast_channel_lock(chan)
Definition: channel.h:2466
static int unload_module(void)
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_DEFINE_APP_ARGS_TYPE(type, arglist)
Define a structure type to hold an application&#39;s arguments.
Definition: app.h:588
static struct ast_app_option connectedline_opts[128]
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:338
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
const char * ast_named_caller_presentation(int data)
Convert caller ID pres value to text code.
Definition: callerid.c:1183
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
Asterisk main include file. File version handling, generic pbx functions.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
Definition: app.h:712
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7091
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
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1093
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
#define ast_strdup(a)
Definition: astmm.h:109
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
Definition: ast_expr2.c:325
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
REDIRECTING_OPT_FLAGS
static struct ast_custom_function redirecting_function
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Definition: channel.c:2329
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
const char * ast_connected_line_source_name(int data)
Convert connected line update source value to text code.
Definition: callerid.c:1291
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
Definition: channel.c:9592
#define LOG_WARNING
Definition: logger.h:144
static enum ID_FIELD_STATUS party_name_write(struct ast_party_name *name, int argc, char *argv[], const char *value)
static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:2151
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
Definition: channel.c:9085
void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
Set the caller information based on another caller source.
Definition: channel.c:2295
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
int ast_redirecting_reason_parse(const char *data)
Convert redirecting reason text code to value (used in config file parsing)
Definition: callerid.c:1214
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
int char_set
Character set the name is using.
Definition: channel.h:222
char * str
Subscriber name (Malloced)
Definition: channel.h:214
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2302
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
struct ast_cdr * cdr
Definition: channel.h:766
static int callerpres_deprecate_notify
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2353
#define END_OPTIONS
Definition: app.h:663
static int callerid_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
char * str
Malloced subaddress string.
Definition: channel.h:263
int value
Definition: syslog.c:39
static struct ast_custom_function callerid_function
static enum ID_FIELD_STATUS party_number_write(struct ast_party_number *number, int argc, char *argv[], const char *value)
static enum ID_FIELD_STATUS party_number_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
unsigned char odd_even_indicator
TRUE if odd number of address signals.
Definition: channel.h:276
const char * ast_redirecting_reason_name(int data)
Convert redirecting reason value to text code.
Definition: callerid.c:1240
static const char *const subnames[]
Definition: chan_dahdi.c:635
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
char * subnames[10]
Utility functions.
void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
Set the dialed information based on another dialed source.
Definition: channel.c:2249
Number structure.
Definition: app_followme.c:109
static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *chan)
Initialize based on a channel.
Definition: cdr.c:883
static int callerid_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static struct ast_custom_function callerpres_function
static enum ID_FIELD_STATUS party_name_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
General Asterisk PBX channel definitions.
static enum ID_FIELD_STATUS party_subaddress_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
struct ast_party_dialed::@155 number
Dialed/Called number.
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
Caller Party information.
Definition: channel.h:368
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
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
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9111
CONNECTED_LINE_OPT_ARGS
Core PBX routines and definitions.
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1144
static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
static struct ast_app_option redirecting_opts[128]
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
Dialed/Called Party information.
Definition: channel.h:328
#define LOG_ERROR
Definition: logger.h:155
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:2288
static struct @350 args
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:380
Connected Line/Party information.
Definition: channel.h:401
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:97
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
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:447
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:122
static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
#define ast_channel_unlock(chan)
Definition: channel.h:2467
unsigned int argc
static const char name[]
static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
int source
Information about the source of an update.
Definition: channel.h:424
#define ast_free(a)
Definition: astmm.h:97
ID_FIELD_STATUS
struct ast_party_subaddress subaddress
Dialed/Called subaddress.
Definition: channel.h:341
Structure used to handle boolean flags.
Definition: utils.h:200
static int callerpres_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:431
const char * ast_party_name_charset_str(int data)
Convert ast_party_name.char_set value to text code.
Definition: callerid.c:1346
char * tag
User-set &quot;tag&quot;.
Definition: channel.h:304
CONNECTED_LINE_OPT_FLAGS
int type
Q.931 subaddress type.
Definition: channel.h:270
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2396
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:465
int count
Number of times the call was redirected.
Definition: channel.h:455
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
Information needed to specify a number in a call.
Definition: channel.h:239
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
Definition: channel.c:2380
static int connected
Definition: cdr_pgsql.c:57
const char * name
Definition: pbx.h:96
void ast_party_dialed_free(struct ast_party_dialed *doomed)
Destroy the dialed party contents.
Definition: channel.c:2262
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
Information needed to specify a subaddress in a call.
Definition: channel.h:257
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
int reason
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:458
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
REDIRECTING_OPT_ARGS
Information needed to specify a name in a call.
Definition: channel.h:212
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
static int callerpres_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
Definition: channel.c:8458
#define BEGIN_OPTIONS
Definition: app.h:662
jack_status_t status
Definition: app_jack.c:143
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
Definition: app.h:721
void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
Initialize the given dialed structure using the given guide for a set update operation.
Definition: channel.c:2241
static int load_module(void)
static struct ast_custom_function connectedline_function
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292