Asterisk - The Open Source Telephony Project  18.5.0
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 #include "asterisk/module.h"
34 #include "asterisk/channel.h"
35 #include "asterisk/pbx.h"
36 #include "asterisk/utils.h"
37 #include "asterisk/app.h"
38 #include "asterisk/callerid.h"
39 
40 /*
41  * The CALLERID(pres) datatype is shorthand for getting/setting the
42  * combined value of name-pres and num-pres. Some channel drivers
43  * don't make a distinction, so it makes sense to only use one property
44  * to get/set it. The same applies to CONNECTEDLINE(pres),
45  * REDIRECTING(orig-pres), REDIRECTING(from-pres) and REDIRECTING(to-pres).
46  *
47  * Do not document the CALLERID(ton) datatype.
48  * It is an alias for num-plan.
49  *
50  * Do not document the CALLERID(ANI-subaddr-...) datatype.
51  * This is not used.
52  *
53  * Do not document the CONNECTEDLINE(source) datatype.
54  * It has turned out to not be needed. The source value is really
55  * only useful as a possible tracing aid.
56  *
57  * Do not document the CONNECTEDLINE(ton) datatype.
58  * It is an alias for num-plan.
59  *
60  * Do not document the REDIRECTING(pres) datatype.
61  * It has turned out that the from-pres and to-pres values must be kept
62  * separate. They represent two different parties and there is a case when
63  * they are active at the same time. The plain pres option will simply
64  * live on as a historical relic.
65  *
66  * Do not document the REDIRECTING(orig-ton), REDIRECTING(from-ton),
67  * or REDIRECTING(to-ton) datatypes.
68  * They are aliases for orig-num-plan, from-num-plan, and to-num-plan
69  * respectively.
70  */
71 /*** DOCUMENTATION
72  <function name="CALLERID" language="en_US">
73  <synopsis>
74  Gets or sets Caller*ID data on the channel.
75  </synopsis>
76  <syntax>
77  <parameter name="datatype" required="true">
78  <para>The allowable datatypes are:</para>
79  <enumlist>
80  <enum name = "all" />
81  <enum name = "name" />
82  <enum name = "name-valid" />
83  <enum name = "name-charset" />
84  <enum name = "name-pres" />
85  <enum name = "num" />
86  <enum name = "num-valid" />
87  <enum name = "num-plan" />
88  <enum name = "num-pres" />
89  <enum name = "pres" />
90  <enum name = "subaddr" />
91  <enum name = "subaddr-valid" />
92  <enum name = "subaddr-type" />
93  <enum name = "subaddr-odd" />
94  <enum name = "tag" />
95  <enum name = "priv-all" />
96  <enum name = "priv-name" />
97  <enum name = "priv-name-valid" />
98  <enum name = "priv-name-charset" />
99  <enum name = "priv-name-pres" />
100  <enum name = "priv-num" />
101  <enum name = "priv-num-valid" />
102  <enum name = "priv-num-plan" />
103  <enum name = "priv-num-pres" />
104  <enum name = "priv-subaddr" />
105  <enum name = "priv-subaddr-valid" />
106  <enum name = "priv-subaddr-type" />
107  <enum name = "priv-subaddr-odd" />
108  <enum name = "priv-tag" />
109  <enum name = "ANI-all" />
110  <enum name = "ANI-name" />
111  <enum name = "ANI-name-valid" />
112  <enum name = "ANI-name-charset" />
113  <enum name = "ANI-name-pres" />
114  <enum name = "ANI-num" />
115  <enum name = "ANI-num-valid" />
116  <enum name = "ANI-num-plan" />
117  <enum name = "ANI-num-pres" />
118  <enum name = "ANI-tag" />
119  <enum name = "RDNIS" />
120  <enum name = "DNID" />
121  <enum name = "dnid-num-plan" />
122  <enum name = "dnid-subaddr" />
123  <enum name = "dnid-subaddr-valid" />
124  <enum name = "dnid-subaddr-type" />
125  <enum name = "dnid-subaddr-odd" />
126  </enumlist>
127  </parameter>
128  <parameter name="CID">
129  <para>Optional Caller*ID to parse instead of using the Caller*ID from the
130  channel. This parameter is only optional when reading the Caller*ID.</para>
131  </parameter>
132  </syntax>
133  <description>
134  <para>Gets or sets Caller*ID data on the channel. Uses channel callerid by
135  default or optional callerid, if specified.</para>
136  <para>The <replaceable>pres</replaceable> field gets/sets a combined value
137  for <replaceable>name-pres</replaceable> and
138  <replaceable>num-pres</replaceable>.</para>
139  <para>The allowable values for the <replaceable>name-charset</replaceable>
140  field are the following:</para>
141  <enumlist>
142  <enum name = "unknown"><para>Unknown</para></enum>
143  <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
144  <enum name = "withdrawn"><para>Withdrawn</para></enum>
145  <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
146  <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
147  <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
148  <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
149  <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
150  <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
151  <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
152  </enumlist>
153  <para>The allowable values for the <replaceable>num-pres</replaceable>,
154  <replaceable>name-pres</replaceable>, and <replaceable>pres</replaceable>
155  fields are the following:</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 = "pres" />
205  <enum name = "subaddr" />
206  <enum name = "subaddr-valid" />
207  <enum name = "subaddr-type" />
208  <enum name = "subaddr-odd" />
209  <enum name = "tag" />
210  <enum name = "priv-all" />
211  <enum name = "priv-name" />
212  <enum name = "priv-name-valid" />
213  <enum name = "priv-name-charset" />
214  <enum name = "priv-name-pres" />
215  <enum name = "priv-num" />
216  <enum name = "priv-num-valid" />
217  <enum name = "priv-num-plan" />
218  <enum name = "priv-num-pres" />
219  <enum name = "priv-subaddr" />
220  <enum name = "priv-subaddr-valid" />
221  <enum name = "priv-subaddr-type" />
222  <enum name = "priv-subaddr-odd" />
223  <enum name = "priv-tag" />
224  </enumlist>
225  </parameter>
226  <parameter name="i">
227  <para>If set, this will prevent the channel from sending out protocol
228  messages because of the value being set</para>
229  </parameter>
230  </syntax>
231  <description>
232  <para>Gets or sets Connected Line data on the channel.</para>
233  <para>The <replaceable>pres</replaceable> field gets/sets a combined value
234  for <replaceable>name-pres</replaceable> and
235  <replaceable>num-pres</replaceable>.</para>
236  <para>The allowable values for the <replaceable>name-charset</replaceable>
237  field are the following:</para>
238  <enumlist>
239  <enum name = "unknown"><para>Unknown</para></enum>
240  <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
241  <enum name = "withdrawn"><para>Withdrawn</para></enum>
242  <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
243  <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
244  <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
245  <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
246  <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
247  <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
248  <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
249  </enumlist>
250  <para>The allowable values for the <replaceable>num-pres</replaceable>,
251  <replaceable>name-pres</replaceable>, and <replaceable>pres</replaceable>
252  fields are the following:</para>
253  <enumlist>
254  <enum name="allowed_not_screened">
255  <para>Presentation Allowed, Not Screened.</para>
256  </enum>
257  <enum name="allowed_passed_screen">
258  <para>Presentation Allowed, Passed Screen.</para>
259  </enum>
260  <enum name="allowed_failed_screen">
261  <para>Presentation Allowed, Failed Screen.</para>
262  </enum>
263  <enum name="allowed">
264  <para>Presentation Allowed, Network Number.</para>
265  </enum>
266  <enum name="prohib_not_screened">
267  <para>Presentation Prohibited, Not Screened.</para>
268  </enum>
269  <enum name="prohib_passed_screen">
270  <para>Presentation Prohibited, Passed Screen.</para>
271  </enum>
272  <enum name="prohib_failed_screen">
273  <para>Presentation Prohibited, Failed Screen.</para>
274  </enum>
275  <enum name="prohib">
276  <para>Presentation Prohibited, Network Number.</para>
277  </enum>
278  <enum name="unavailable">
279  <para>Number Unavailable.</para>
280  </enum>
281  </enumlist>
282  </description>
283  </function>
284  <function name="REDIRECTING" language="en_US">
285  <synopsis>
286  Gets or sets Redirecting data on the channel.
287  </synopsis>
288  <syntax>
289  <parameter name="datatype" required="true">
290  <para>The allowable datatypes are:</para>
291  <enumlist>
292  <enum name = "orig-all" />
293  <enum name = "orig-name" />
294  <enum name = "orig-name-valid" />
295  <enum name = "orig-name-charset" />
296  <enum name = "orig-name-pres" />
297  <enum name = "orig-num" />
298  <enum name = "orig-num-valid" />
299  <enum name = "orig-num-plan" />
300  <enum name = "orig-num-pres" />
301  <enum name = "orig-pres" />
302  <enum name = "orig-subaddr" />
303  <enum name = "orig-subaddr-valid" />
304  <enum name = "orig-subaddr-type" />
305  <enum name = "orig-subaddr-odd" />
306  <enum name = "orig-tag" />
307  <enum name = "orig-reason" />
308  <enum name = "from-all" />
309  <enum name = "from-name" />
310  <enum name = "from-name-valid" />
311  <enum name = "from-name-charset" />
312  <enum name = "from-name-pres" />
313  <enum name = "from-num" />
314  <enum name = "from-num-valid" />
315  <enum name = "from-num-plan" />
316  <enum name = "from-num-pres" />
317  <enum name = "from-pres" />
318  <enum name = "from-subaddr" />
319  <enum name = "from-subaddr-valid" />
320  <enum name = "from-subaddr-type" />
321  <enum name = "from-subaddr-odd" />
322  <enum name = "from-tag" />
323  <enum name = "to-all" />
324  <enum name = "to-name" />
325  <enum name = "to-name-valid" />
326  <enum name = "to-name-charset" />
327  <enum name = "to-name-pres" />
328  <enum name = "to-num" />
329  <enum name = "to-num-valid" />
330  <enum name = "to-num-plan" />
331  <enum name = "to-num-pres" />
332  <enum name = "to-pres" />
333  <enum name = "to-subaddr" />
334  <enum name = "to-subaddr-valid" />
335  <enum name = "to-subaddr-type" />
336  <enum name = "to-subaddr-odd" />
337  <enum name = "to-tag" />
338  <enum name = "priv-orig-all" />
339  <enum name = "priv-orig-name" />
340  <enum name = "priv-orig-name-valid" />
341  <enum name = "priv-orig-name-charset" />
342  <enum name = "priv-orig-name-pres" />
343  <enum name = "priv-orig-num" />
344  <enum name = "priv-orig-num-valid" />
345  <enum name = "priv-orig-num-plan" />
346  <enum name = "priv-orig-num-pres" />
347  <enum name = "priv-orig-subaddr" />
348  <enum name = "priv-orig-subaddr-valid" />
349  <enum name = "priv-orig-subaddr-type" />
350  <enum name = "priv-orig-subaddr-odd" />
351  <enum name = "priv-orig-tag" />
352  <enum name = "priv-from-all" />
353  <enum name = "priv-from-name" />
354  <enum name = "priv-from-name-valid" />
355  <enum name = "priv-from-name-charset" />
356  <enum name = "priv-from-name-pres" />
357  <enum name = "priv-from-num" />
358  <enum name = "priv-from-num-valid" />
359  <enum name = "priv-from-num-plan" />
360  <enum name = "priv-from-num-pres" />
361  <enum name = "priv-from-subaddr" />
362  <enum name = "priv-from-subaddr-valid" />
363  <enum name = "priv-from-subaddr-type" />
364  <enum name = "priv-from-subaddr-odd" />
365  <enum name = "priv-from-tag" />
366  <enum name = "priv-to-all" />
367  <enum name = "priv-to-name" />
368  <enum name = "priv-to-name-valid" />
369  <enum name = "priv-to-name-charset" />
370  <enum name = "priv-to-name-pres" />
371  <enum name = "priv-to-num" />
372  <enum name = "priv-to-num-valid" />
373  <enum name = "priv-to-num-plan" />
374  <enum name = "priv-to-num-pres" />
375  <enum name = "priv-to-subaddr" />
376  <enum name = "priv-to-subaddr-valid" />
377  <enum name = "priv-to-subaddr-type" />
378  <enum name = "priv-to-subaddr-odd" />
379  <enum name = "priv-to-tag" />
380  <enum name = "reason" />
381  <enum name = "count" />
382  </enumlist>
383  </parameter>
384  <parameter name="i">
385  <para>If set, this will prevent the channel from sending out protocol
386  messages because of the value being set</para>
387  </parameter>
388  </syntax>
389  <description>
390  <para>Gets or sets Redirecting data on the channel.</para>
391  <para>The <replaceable>orig-pres</replaceable>,
392  <replaceable>from-pres</replaceable> and <replaceable>to-pres</replaceable>
393  fields get/set a combined value for the corresponding
394  <replaceable>...-name-pres</replaceable> and <replaceable>...-num-pres</replaceable>
395  fields.</para>
396  <para>The recognized values for the <replaceable>reason</replaceable>
397  and <replaceable>orig-reason</replaceable> fields are the following:</para>
398  <enumlist>
399  <enum name = "away"><para>Callee is Away</para></enum>
400  <enum name = "cf_dte"><para>Call Forwarding By The Called DTE</para></enum>
401  <enum name = "cfb"><para>Call Forwarding Busy</para></enum>
402  <enum name = "cfnr"><para>Call Forwarding No Reply</para></enum>
403  <enum name = "cfu"><para>Call Forwarding Unconditional</para></enum>
404  <enum name = "deflection"><para>Call Deflection</para></enum>
405  <enum name = "dnd"><para>Do Not Disturb</para></enum>
406  <enum name = "follow_me"><para>Follow Me</para></enum>
407  <enum name = "out_of_order"><para>Called DTE Out-Of-Order</para></enum>
408  <enum name = "send_to_vm"><para>Send the call to voicemail</para></enum>
409  <enum name = "time_of_day"><para>Time of Day</para></enum>
410  <enum name = "unavailable"><para>Callee is Unavailable</para></enum>
411  <enum name = "unknown"><para>Unknown</para></enum>
412  </enumlist>
413  <note><para>You can set a user defined reason string that SIP can
414  send/receive instead. The user defined reason string my need to be
415  quoted depending upon SIP or the peer's requirements. These strings
416  are treated as unknown by the non-SIP channel drivers.</para></note>
417  <para>The allowable values for the <replaceable>xxx-name-charset</replaceable>
418  field are the following:</para>
419  <enumlist>
420  <enum name = "unknown"><para>Unknown</para></enum>
421  <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
422  <enum name = "withdrawn"><para>Withdrawn</para></enum>
423  <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
424  <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
425  <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
426  <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
427  <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
428  <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
429  <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
430  </enumlist>
431  </description>
432  </function>
433  ***/
434 
439 };
440 
442  AST_APP_ARG(member); /*!< Member name */
443  AST_APP_ARG(opts); /*!< Options token */
444  AST_APP_ARG(other); /*!< Any remining unused arguments */
445  );
446 
448  AST_APP_ARG(subnames[10]); /*!< Option member subnames */
449  );
450 
453 };
455  CONNECTED_LINE_OPT_DUMMY, /*!< Delete this if CONNECTED_LINE ever gets an option with parameters. */
456 
457  /*! \note This entry _MUST_ be the last one in the enum */
459 };
460 
464 
467 };
469  REDIRECTING_OPT_DUMMY, /*!< Delete this if REDIRECTING ever gets an option with parameters. */
470 
471  /*! \note This entry _MUST_ be the last one in the enum */
473 };
474 
478 
479 /*!
480  * \internal
481  * \brief Read values from the party name struct.
482  * \since 1.8
483  *
484  * \param buf Buffer to fill with read value.
485  * \param len Length of the buffer.
486  * \param argc Number of party member subnames.
487  * \param argv Party member subnames given.
488  * \param name Party name to get values from.
489  *
490  * \retval ID_FIELD_VALID on success.
491  * \retval ID_FIELD_UNKNOWN on unknown field name.
492  */
493 static enum ID_FIELD_STATUS party_name_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
494 {
495  enum ID_FIELD_STATUS status;
496 
497  status = ID_FIELD_VALID;
498 
499  if (argc == 0) {
500  /* We want the name string */
501  if (name->valid && name->str) {
502  ast_copy_string(buf, name->str, len);
503  }
504  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
505  snprintf(buf, len, "%d", name->valid);
506  } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
508  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
509  /* Accept pres[entation] */
511  } else {
512  status = ID_FIELD_UNKNOWN;
513  }
514 
515  return status;
516 }
517 
518 /*!
519  * \internal
520  * \brief Read values from the party number struct.
521  * \since 1.8
522  *
523  * \param buf Buffer to fill with read value.
524  * \param len Length of the buffer.
525  * \param argc Number of party member subnames.
526  * \param argv Party member subnames given.
527  * \param number Party number to get values from.
528  *
529  * \retval ID_FIELD_VALID on success.
530  * \retval ID_FIELD_UNKNOWN on unknown field name.
531  */
532 static enum ID_FIELD_STATUS party_number_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
533 {
534  enum ID_FIELD_STATUS status;
535 
536  status = ID_FIELD_VALID;
537 
538  if (argc == 0) {
539  /* We want the number string */
540  if (number->valid && number->str) {
541  ast_copy_string(buf, number->str, len);
542  }
543  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
544  snprintf(buf, len, "%d", number->valid);
545  } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
546  snprintf(buf, len, "%d", number->plan);
547  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
548  /* Accept pres[entation] */
550  } else {
551  status = ID_FIELD_UNKNOWN;
552  }
553 
554  return status;
555 }
556 
557 /*!
558  * \internal
559  * \brief Read values from the party subaddress struct.
560  * \since 1.8
561  *
562  * \param buf Buffer to fill with read value.
563  * \param len Length of the buffer.
564  * \param argc Number of party member subnames.
565  * \param argv Party member subnames given.
566  * \param subaddress Party subaddress to get values from.
567  *
568  * \retval ID_FIELD_VALID on success.
569  * \retval ID_FIELD_UNKNOWN on unknown field name.
570  */
571 static enum ID_FIELD_STATUS party_subaddress_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
572 {
573  enum ID_FIELD_STATUS status;
574 
575  status = ID_FIELD_VALID;
576 
577  if (argc == 0) {
578  /* We want the subaddress string */
579  if (subaddress->str) {
580  ast_copy_string(buf, subaddress->str, len);
581  }
582  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
583  snprintf(buf, len, "%d", subaddress->valid);
584  } else if (argc == 1 && !strcasecmp("type", argv[0])) {
585  snprintf(buf, len, "%d", subaddress->type);
586  } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
587  snprintf(buf, len, "%d", subaddress->odd_even_indicator);
588  } else {
589  status = ID_FIELD_UNKNOWN;
590  }
591 
592  return status;
593 }
594 
595 /*!
596  * \internal
597  * \brief Read values from the party id struct.
598  * \since 1.8
599  *
600  * \param buf Buffer to fill with read value.
601  * \param len Length of the buffer.
602  * \param argc Number of party member subnames.
603  * \param argv Party member subnames given.
604  * \param id Party id to get values from.
605  *
606  * \retval ID_FIELD_VALID on success.
607  * \retval ID_FIELD_UNKNOWN on unknown field name.
608  */
609 static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
610 {
611  enum ID_FIELD_STATUS status;
612 
613  if (argc == 0) {
614  /* Must have at least one subname. */
615  return ID_FIELD_UNKNOWN;
616  }
617 
618  status = ID_FIELD_VALID;
619 
620  if (argc == 1 && !strcasecmp("all", argv[0])) {
621  snprintf(buf, len, "\"%s\" <%s>",
622  S_COR(id->name.valid, id->name.str, ""),
623  S_COR(id->number.valid, id->number.str, ""));
624  } else if (!strcasecmp("name", argv[0])) {
625  status = party_name_read(buf, len, argc - 1, argv + 1, &id->name);
626  } else if (!strncasecmp("num", argv[0], 3)) {
627  /* Accept num[ber] */
628  status = party_number_read(buf, len, argc - 1, argv + 1, &id->number);
629  } else if (!strncasecmp("subaddr", argv[0], 7)) {
630  /* Accept subaddr[ess] */
631  status = party_subaddress_read(buf, len, argc - 1, argv + 1, &id->subaddress);
632  } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
633  if (id->tag) {
634  ast_copy_string(buf, id->tag, len);
635  }
636  } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
637  /* ton is an alias for num-plan */
638  snprintf(buf, len, "%d", id->number.plan);
639  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
640  /*
641  * Accept pres[entation]
642  * This is the combined name/number presentation.
643  */
644  ast_copy_string(buf,
646  } else {
647  status = ID_FIELD_UNKNOWN;
648  }
649 
650  return status;
651 }
652 
653 /*!
654  * \internal
655  * \brief Write new values to the party name struct
656  * \since 1.8
657  *
658  * \param name Party name struct to write values
659  * \param argc Number of party member subnames.
660  * \param argv Party member subnames given.
661  * \param value Value to assign to the party name.
662  *
663  * \retval ID_FIELD_VALID on success.
664  * \retval ID_FIELD_INVALID on error with field value.
665  * \retval ID_FIELD_UNKNOWN on unknown field name.
666  */
667 static enum ID_FIELD_STATUS party_name_write(struct ast_party_name *name, int argc, char *argv[], const char *value)
668 {
669  char *val;
670  enum ID_FIELD_STATUS status;
671 
672  status = ID_FIELD_VALID;
673 
674  if (argc == 0) {
675  /* We are setting the name string */
676  name->valid = 1;
677  name->str = ast_strdup(value);
678  ast_trim_blanks(name->str);
679  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
680  name->valid = atoi(value) ? 1 : 0;
681  } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
682  int char_set;
683 
684  val = ast_strdupa(value);
685  ast_trim_blanks(val);
686 
687  if (('0' <= val[0]) && (val[0] <= '9')) {
688  char_set = atoi(val);
689  } else {
690  char_set = ast_party_name_charset_parse(val);
691  }
692 
693  if (char_set < 0) {
695  "Unknown name char-set '%s', value unchanged\n", val);
696  status = ID_FIELD_INVALID;
697  } else {
698  name->char_set = char_set;
699  }
700  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
701  int pres;
702 
703  /* Accept pres[entation] */
704  val = ast_strdupa(value);
705  ast_trim_blanks(val);
706 
707  if (('0' <= val[0]) && (val[0] <= '9')) {
708  pres = atoi(val);
709  } else {
710  pres = ast_parse_caller_presentation(val);
711  }
712 
713  if (pres < 0) {
715  "Unknown name presentation '%s', value unchanged\n", val);
716  status = ID_FIELD_INVALID;
717  } else {
718  name->presentation = pres;
719  }
720  } else {
721  status = ID_FIELD_UNKNOWN;
722  }
723 
724  return status;
725 }
726 
727 /*!
728  * \internal
729  * \brief Write new values to the party number struct
730  * \since 1.8
731  *
732  * \param number Party number struct to write values
733  * \param argc Number of party member subnames.
734  * \param argv Party member subnames given.
735  * \param value Value to assign to the party number.
736  *
737  * \retval ID_FIELD_VALID on success.
738  * \retval ID_FIELD_INVALID on error with field value.
739  * \retval ID_FIELD_UNKNOWN on unknown field name.
740  */
741 static enum ID_FIELD_STATUS party_number_write(struct ast_party_number *number, int argc, char *argv[], const char *value)
742 {
743  char *val;
744  enum ID_FIELD_STATUS status;
745 
746  status = ID_FIELD_VALID;
747 
748  if (argc == 0) {
749  /* We are setting the number string */
750  number->valid = 1;
751  number->str = ast_strdup(value);
752  ast_trim_blanks(number->str);
753  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
754  number->valid = atoi(value) ? 1 : 0;
755  } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
756  val = ast_strdupa(value);
757  ast_trim_blanks(val);
758 
759  if (('0' <= val[0]) && (val[0] <= '9')) {
760  number->plan = atoi(val);
761  } else {
763  "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
764  status = ID_FIELD_INVALID;
765  }
766  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
767  int pres;
768 
769  /* Accept pres[entation] */
770  val = ast_strdupa(value);
771  ast_trim_blanks(val);
772 
773  if (('0' <= val[0]) && (val[0] <= '9')) {
774  pres = atoi(val);
775  } else {
776  pres = ast_parse_caller_presentation(val);
777  }
778 
779  if (pres < 0) {
781  "Unknown number presentation '%s', value unchanged\n", val);
782  status = ID_FIELD_INVALID;
783  } else {
784  number->presentation = pres;
785  }
786  } else {
787  status = ID_FIELD_UNKNOWN;
788  }
789 
790  return status;
791 }
792 
793 /*!
794  * \internal
795  * \brief Write new values to the party subaddress struct
796  * \since 1.8
797  *
798  * \param subaddress Party subaddress struct to write values
799  * \param argc Number of party member subnames.
800  * \param argv Party member subnames given.
801  * \param value Value to assign to the party subaddress.
802  *
803  * \retval ID_FIELD_VALID on success.
804  * \retval ID_FIELD_INVALID on error with field value.
805  * \retval ID_FIELD_UNKNOWN on unknown field name.
806  */
807 static enum ID_FIELD_STATUS party_subaddress_write(struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
808 {
809  enum ID_FIELD_STATUS status;
810 
811  status = ID_FIELD_VALID;
812 
813  if (argc == 0) {
814  /* We are setting the subaddress string */
815  subaddress->str = ast_strdup(value);
816  ast_trim_blanks(subaddress->str);
817  } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
818  subaddress->valid = atoi(value) ? 1 : 0;
819  } else if (argc == 1 && !strcasecmp("type", argv[0])) {
820  subaddress->type = atoi(value) ? 2 : 0;
821  } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
822  subaddress->odd_even_indicator = atoi(value) ? 1 : 0;
823  } else {
824  status = ID_FIELD_UNKNOWN;
825  }
826 
827  return status;
828 }
829 
830 /*!
831  * \internal
832  * \brief Write new values to the party id struct
833  * \since 1.8
834  *
835  * \param id Party ID struct to write values
836  * \param argc Number of party member subnames.
837  * \param argv Party member subnames given.
838  * \param value Value to assign to the party id.
839  *
840  * \retval ID_FIELD_VALID on success.
841  * \retval ID_FIELD_INVALID on error with field value.
842  * \retval ID_FIELD_UNKNOWN on unknown field name.
843  */
844 static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
845 {
846  char *val;
847  enum ID_FIELD_STATUS status;
848 
849  if (argc == 0) {
850  /* Must have at least one subname. */
851  return ID_FIELD_UNKNOWN;
852  }
853 
854  status = ID_FIELD_VALID;
855 
856  if (argc == 1 && !strcasecmp("all", argv[0])) {
857  char name[256];
858  char num[256];
859 
860  ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
861  id->name.valid = 1;
862  id->name.str = ast_strdup(name);
863  if (!id->name.str) {
864  return ID_FIELD_INVALID;
865  }
866  id->number.valid = 1;
867  id->number.str = ast_strdup(num);
868  if (!id->number.str) {
869  return ID_FIELD_INVALID;
870  }
871  } else if (!strcasecmp("name", argv[0])) {
872  status = party_name_write(&id->name, argc - 1, argv + 1, value);
873  } else if (!strncasecmp("num", argv[0], 3)) {
874  /* Accept num[ber] */
875  status = party_number_write(&id->number, argc - 1, argv + 1, value);
876  } else if (!strncasecmp("subaddr", argv[0], 7)) {
877  /* Accept subaddr[ess] */
878  status = party_subaddress_write(&id->subaddress, argc - 1, argv + 1, value);
879  } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
880  id->tag = ast_strdup(value);
881  ast_trim_blanks(id->tag);
882  } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
883  /* ton is an alias for num-plan */
884  argv[0] = "plan";
885  status = party_number_write(&id->number, argc, argv, value);
886  } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
887  int pres;
888 
889  /*
890  * Accept pres[entation]
891  * This is the combined name/number presentation.
892  */
893  val = ast_strdupa(value);
894  ast_trim_blanks(val);
895 
896  if (('0' <= val[0]) && (val[0] <= '9')) {
897  pres = atoi(val);
898  } else {
899  pres = ast_parse_caller_presentation(val);
900  }
901 
902  if (pres < 0) {
904  "Unknown combined presentation '%s', value unchanged\n", val);
905  status = ID_FIELD_INVALID;
906  } else {
907  id->name.presentation = pres;
908  id->number.presentation = pres;
909  }
910  } else {
911  status = ID_FIELD_UNKNOWN;
912  }
913 
914  return status;
915 }
916 
917 /*!
918  * \internal
919  * \brief Read values from the caller-id information struct.
920  *
921  * \param chan Asterisk channel to read
922  * \param cmd Not used
923  * \param data Caller-id function datatype string
924  * \param buf Buffer to fill with read value.
925  * \param len Length of the buffer
926  *
927  * \retval 0 on success.
928  * \retval -1 on error.
929  */
930 static int callerid_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
931 {
932  char *parms;
933  struct ast_party_members member = { 0, };
935  AST_APP_ARG(member); /*!< Member name */
936  AST_APP_ARG(cid); /*!< Optional caller id to parse instead of from the channel. */
937  );
938 
939  /* Ensure that the buffer is empty */
940  *buf = 0;
941 
942  if (!chan) {
943  return -1;
944  }
945 
946  parms = ast_strdupa(data);
947  AST_STANDARD_APP_ARGS(args, parms);
948  if (args.argc == 0) {
949  /* Must have at least one argument. */
950  return -1;
951  }
952 
953  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
954  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
955  /* Too few or too many subnames */
956  return -1;
957  }
958 
959  if (args.argc == 2) {
960  char name[80];
961  char num[80];
962 
963  ast_callerid_split(args.cid, name, sizeof(name), num, sizeof(num));
964 
965  if (member.argc == 1 && !strcasecmp("all", member.subnames[0])) {
966  snprintf(buf, len, "\"%s\" <%s>", name, num);
967  } else if (member.argc == 1 && !strcasecmp("name", member.subnames[0])) {
968  ast_copy_string(buf, name, len);
969  } else if (member.argc == 1 && !strncasecmp("num", member.subnames[0], 3)) {
970  /* Accept num[ber] */
971  ast_copy_string(buf, num, len);
972  } else {
973  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
974  }
975  } else {
976  enum ID_FIELD_STATUS status;
977  ast_channel_lock(chan);
978 
979  if (member.argc == 1 && !strcasecmp("rdnis", member.subnames[0])) {
980  if (ast_channel_redirecting(chan)->from.number.valid
981  && ast_channel_redirecting(chan)->from.number.str) {
982  ast_copy_string(buf, ast_channel_redirecting(chan)->from.number.str, len);
983  }
984  } else if (!strcasecmp("dnid", member.subnames[0])) {
985  if (member.argc == 1) {
986  /* Setup as if user had given dnid-num instead. */
987  member.argc = 2;
988  member.subnames[1] = "num";
989  }
990  if (!strncasecmp("num", member.subnames[1], 3)) {
991  /*
992  * Accept num[ber]
993  * dnid-num...
994  */
995  if (member.argc == 2) {
996  /* dnid-num */
997  if (ast_channel_dialed(chan)->number.str) {
998  ast_copy_string(buf, ast_channel_dialed(chan)->number.str, len);
999  }
1000  } else if (member.argc == 3 && !strcasecmp("plan", member.subnames[2])) {
1001  /* dnid-num-plan */
1002  snprintf(buf, len, "%d", ast_channel_dialed(chan)->number.plan);
1003  } else {
1004  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1005  }
1006  } else if (!strncasecmp("subaddr", member.subnames[1], 7)) {
1007  /*
1008  * Accept subaddr[ess]
1009  * dnid-subaddr...
1010  */
1011  status = party_subaddress_read(buf, len, member.argc - 2, member.subnames + 2,
1012  &ast_channel_dialed(chan)->subaddress);
1013  switch (status) {
1014  case ID_FIELD_VALID:
1015  case ID_FIELD_INVALID:
1016  break;
1017  default:
1018  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1019  break;
1020  }
1021  } else {
1022  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1023  }
1024  } else if (member.argc == 1 && !strcasecmp("ani2", member.subnames[0])) {
1025  snprintf(buf, len, "%d", ast_channel_caller(chan)->ani2);
1026  } else if (!strcasecmp("ani", member.subnames[0])) {
1027  if (member.argc == 1) {
1028  /* Setup as if user had given ani-num instead. */
1029  member.argc = 2;
1030  member.subnames[1] = "num";
1031  }
1032  status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1033  &ast_channel_caller(chan)->ani);
1034  switch (status) {
1035  case ID_FIELD_VALID:
1036  case ID_FIELD_INVALID:
1037  break;
1038  default:
1039  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1040  break;
1041  }
1042  } else if (!strcasecmp("priv", member.subnames[0])) {
1043  status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1044  &ast_channel_caller(chan)->priv);
1045  switch (status) {
1046  case ID_FIELD_VALID:
1047  case ID_FIELD_INVALID:
1048  break;
1049  default:
1050  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1051  break;
1052  }
1053  } else {
1054  status = party_id_read(buf, len, member.argc, member.subnames, &ast_channel_caller(chan)->id);
1055  switch (status) {
1056  case ID_FIELD_VALID:
1057  case ID_FIELD_INVALID:
1058  break;
1059  default:
1060  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1061  break;
1062  }
1063  }
1064 
1065  ast_channel_unlock(chan);
1066  }
1067 
1068  return 0;
1069 }
1070 
1071 /*!
1072  * \internal
1073  * \brief Write new values to the caller-id information struct.
1074  *
1075  * \param chan Asterisk channel to update
1076  * \param cmd Not used
1077  * \param data Caller-id function datatype string
1078  * \param value Value to assign to the caller-id information struct.
1079  *
1080  * \retval 0 on success.
1081  * \retval -1 on error.
1082  */
1083 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1084 {
1085  struct ast_party_caller caller;
1086  struct ast_party_dialed dialed;
1087  enum ID_FIELD_STATUS status;
1088  char *val;
1089  char *parms;
1090  struct ast_party_func_args args = { 0, };
1091  struct ast_party_members member = { 0, };
1092 
1093  if (!value || !chan) {
1094  return -1;
1095  }
1096 
1097  parms = ast_strdupa(data);
1098  AST_STANDARD_APP_ARGS(args, parms);
1099  if (args.argc == 0) {
1100  /* Must have at least one argument. */
1101  return -1;
1102  }
1103 
1104  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1105  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1106  /* Too few or too many subnames */
1107  return -1;
1108  }
1109 
1110  value = ast_skip_blanks(value);
1111 
1112  ast_channel_lock(chan);
1113  if (member.argc == 1 && !strcasecmp("rdnis", member.subnames[0])) {
1115  ast_free(ast_channel_redirecting(chan)->from.number.str);
1117  } else if (!strcasecmp("dnid", member.subnames[0])) {
1119  if (member.argc == 1) {
1120  /* Setup as if user had given dnid-num instead. */
1121  member.argc = 2;
1122  member.subnames[1] = "num";
1123  }
1124  if (!strncasecmp("num", member.subnames[1], 3)) {
1125  /*
1126  * Accept num[ber]
1127  * dnid-num...
1128  */
1129  if (member.argc == 2) {
1130  /* dnid-num */
1131  dialed.number.str = ast_strdup(value);
1132  ast_trim_blanks(dialed.number.str);
1133  ast_party_dialed_set(ast_channel_dialed(chan), &dialed);
1134  } else if (member.argc == 3 && !strcasecmp("plan", member.subnames[2])) {
1135  /* dnid-num-plan */
1136  val = ast_strdupa(value);
1137  ast_trim_blanks(val);
1138 
1139  if (('0' <= val[0]) && (val[0] <= '9')) {
1140  ast_channel_dialed(chan)->number.plan = atoi(val);
1141  } else {
1143  "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
1144  }
1145  } else {
1146  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1147  }
1148  } else if (!strncasecmp("subaddr", member.subnames[1], 7)) {
1149  /*
1150  * Accept subaddr[ess]
1151  * dnid-subaddr...
1152  */
1153  status = party_subaddress_write(&dialed.subaddress, member.argc - 2,
1154  member.subnames + 2, value);
1155  switch (status) {
1156  case ID_FIELD_VALID:
1157  ast_party_dialed_set(ast_channel_dialed(chan), &dialed);
1158  break;
1159  case ID_FIELD_INVALID:
1160  break;
1161  default:
1162  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1163  break;
1164  }
1165  } else {
1166  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1167  }
1168  ast_party_dialed_free(&dialed);
1169  } else if (member.argc == 1 && !strcasecmp("ani2", member.subnames[0])) {
1170  val = ast_strdupa(value);
1171  ast_trim_blanks(val);
1172 
1173  if (('0' <= val[0]) && (val[0] <= '9')) {
1174  ast_channel_caller(chan)->ani2 = atoi(val);
1175  } else {
1176  ast_log(LOG_ERROR, "Unknown callerid ani2 '%s', value unchanged\n", val);
1177  }
1178  } else if (!strcasecmp("ani", member.subnames[0])) {
1180  if (member.argc == 1) {
1181  /* Setup as if user had given ani-num instead. */
1182  member.argc = 2;
1183  member.subnames[1] = "num";
1184  }
1185  status = party_id_write(&caller.ani, member.argc - 1, member.subnames + 1, value);
1186  switch (status) {
1187  case ID_FIELD_VALID:
1188  ast_party_caller_set(ast_channel_caller(chan), &caller, NULL);
1189  break;
1190  case ID_FIELD_INVALID:
1191  break;
1192  default:
1193  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1194  break;
1195  }
1196  ast_party_caller_free(&caller);
1197  } else if (!strcasecmp("priv", member.subnames[0])) {
1199  status = party_id_write(&caller.priv, member.argc - 1, member.subnames + 1, value);
1200  switch (status) {
1201  case ID_FIELD_VALID:
1202  ast_party_caller_set(ast_channel_caller(chan), &caller, NULL);
1203  break;
1204  case ID_FIELD_INVALID:
1205  break;
1206  default:
1207  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1208  break;
1209  }
1210  ast_party_caller_free(&caller);
1211  } else {
1213  status = party_id_write(&caller.id, member.argc, member.subnames, value);
1214  switch (status) {
1215  case ID_FIELD_VALID:
1216  ast_channel_set_caller_event(chan, &caller, NULL);
1217  break;
1218  case ID_FIELD_INVALID:
1219  break;
1220  default:
1221  ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1222  break;
1223  }
1224  ast_party_caller_free(&caller);
1225  }
1226  ast_channel_unlock(chan);
1227 
1228  return 0;
1229 }
1230 
1231 /*!
1232  * \internal
1233  * \brief Read values from the connected line information struct.
1234  *
1235  * \param chan Asterisk channel to read
1236  * \param cmd Not used
1237  * \param data Connected line function datatype string
1238  * \param buf Buffer to fill with read value.
1239  * \param len Length of the buffer
1240  *
1241  * \retval 0 on success.
1242  * \retval -1 on error.
1243  */
1244 static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1245 {
1246  struct ast_party_members member = { 0, };
1247  char *read_what;
1248  enum ID_FIELD_STATUS status;
1249 
1250  /* Ensure that the buffer is empty */
1251  *buf = 0;
1252 
1253  if (!chan) {
1254  return -1;
1255  }
1256 
1257  read_what = ast_strdupa(data);
1258  AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
1259  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1260  /* Too few or too many subnames */
1261  return -1;
1262  }
1263 
1264  ast_channel_lock(chan);
1265 
1266  if (member.argc == 1 && !strcasecmp("source", member.subnames[0])) {
1268  } else if (!strcasecmp("priv", member.subnames[0])) {
1269  status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1270  &ast_channel_connected(chan)->priv);
1271  switch (status) {
1272  case ID_FIELD_VALID:
1273  case ID_FIELD_INVALID:
1274  break;
1275  default:
1276  ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1277  break;
1278  }
1279  } else {
1280  status = party_id_read(buf, len, member.argc, member.subnames, &ast_channel_connected(chan)->id);
1281  switch (status) {
1282  case ID_FIELD_VALID:
1283  case ID_FIELD_INVALID:
1284  break;
1285  default:
1286  ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1287  break;
1288  }
1289  }
1290 
1291  ast_channel_unlock(chan);
1292 
1293  return 0;
1294 }
1295 
1296 /*!
1297  * \internal
1298  * \brief Write new values to the connected line information struct.
1299  *
1300  * \param chan Asterisk channel to update
1301  * \param cmd Not used
1302  * \param data Connected line function datatype string
1303  * \param value Value to assign to the connected line information struct.
1304  *
1305  * \retval 0 on success.
1306  * \retval -1 on error.
1307  */
1308 static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1309 {
1310  struct ast_party_connected_line connected;
1311  char *val;
1312  char *parms;
1313  void (*set_it)(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
1314  struct ast_party_func_args args = { 0, };
1315  struct ast_party_members member = { 0, };
1316  struct ast_flags opts;
1317  char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
1318  enum ID_FIELD_STATUS status;
1319 
1320  if (!value || !chan) {
1321  return -1;
1322  }
1323 
1324  parms = ast_strdupa(data);
1325  AST_STANDARD_APP_ARGS(args, parms);
1326  if (args.argc == 0) {
1327  /* Must have at least one argument. */
1328  return -1;
1329  }
1330 
1331  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1332  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1333  /* Too few or too many subnames */
1334  return -1;
1335  }
1336 
1337  if (ast_app_parse_options(connectedline_opts, &opts, opt_args, args.opts)) {
1338  /* General invalid option syntax. */
1339  return -1;
1340  }
1341 
1342  /* Determine if the update indication inhibit option is present */
1345  } else {
1347  }
1348 
1349  ast_channel_lock(chan);
1351  ast_channel_unlock(chan);
1352 
1353  value = ast_skip_blanks(value);
1354 
1355  if (member.argc == 1 && !strcasecmp("source", member.subnames[0])) {
1356  int source;
1357 
1358  val = ast_strdupa(value);
1359  ast_trim_blanks(val);
1360 
1361  if (('0' <= val[0]) && (val[0] <= '9')) {
1362  source = atoi(val);
1363  } else {
1364  source = ast_connected_line_source_parse(val);
1365  }
1366 
1367  if (source < 0) {
1368  ast_log(LOG_ERROR, "Unknown connectedline source '%s', value unchanged\n", val);
1369  } else {
1370  connected.source = source;
1371  set_it(chan, &connected, NULL);
1372  }
1373  } else if (!strcasecmp("priv", member.subnames[0])) {
1374  status = party_id_write(&connected.priv, member.argc - 1, member.subnames + 1, value);
1375  switch (status) {
1376  case ID_FIELD_VALID:
1377  set_it(chan, &connected, NULL);
1378  break;
1379  case ID_FIELD_INVALID:
1380  break;
1381  default:
1382  ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1383  break;
1384  }
1385  ast_party_connected_line_free(&connected);
1386  } else {
1387  status = party_id_write(&connected.id, member.argc, member.subnames, value);
1388  switch (status) {
1389  case ID_FIELD_VALID:
1390  set_it(chan, &connected, NULL);
1391  break;
1392  case ID_FIELD_INVALID:
1393  break;
1394  default:
1395  ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1396  break;
1397  }
1398  ast_party_connected_line_free(&connected);
1399  }
1400 
1401  return 0;
1402 }
1403 
1404 /*!
1405  * \internal
1406  * \brief Read values from the redirecting information struct.
1407  *
1408  * \param chan Asterisk channel to read
1409  * \param cmd Not used
1410  * \param data Redirecting function datatype string
1411  * \param buf Buffer to fill with read value.
1412  * \param len Length of the buffer
1413  *
1414  * \retval 0 on success.
1415  * \retval -1 on error.
1416  */
1417 static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1418 {
1419  struct ast_party_members member = { 0, };
1420  char *read_what;
1421  const struct ast_party_redirecting *ast_redirecting;
1422  enum ID_FIELD_STATUS status;
1423 
1424  /* Ensure that the buffer is empty */
1425  *buf = 0;
1426 
1427  if (!chan) {
1428  return -1;
1429  }
1430 
1431  read_what = ast_strdupa(data);
1432  AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
1433  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1434  /* Too few or too many subnames */
1435  return -1;
1436  }
1437 
1438  ast_channel_lock(chan);
1439 
1440  ast_redirecting = ast_channel_redirecting(chan);
1441  if (!strcasecmp("orig", member.subnames[0])) {
1442  if (member.argc == 2 && !strcasecmp("reason", member.subnames[1])) {
1443  ast_copy_string(buf,
1444  ast_redirecting_reason_name(&ast_redirecting->orig_reason), len);
1445  } else {
1446  status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1447  &ast_redirecting->orig);
1448  switch (status) {
1449  case ID_FIELD_VALID:
1450  case ID_FIELD_INVALID:
1451  break;
1452  default:
1453  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1454  break;
1455  }
1456  }
1457  } else if (!strcasecmp("from", member.subnames[0])) {
1458  status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1459  &ast_redirecting->from);
1460  switch (status) {
1461  case ID_FIELD_VALID:
1462  case ID_FIELD_INVALID:
1463  break;
1464  default:
1465  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1466  break;
1467  }
1468  } else if (!strcasecmp("to", member.subnames[0])) {
1469  status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1470  &ast_redirecting->to);
1471  switch (status) {
1472  case ID_FIELD_VALID:
1473  case ID_FIELD_INVALID:
1474  break;
1475  default:
1476  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1477  break;
1478  }
1479  } else if (member.argc == 1 && !strncasecmp("pres", member.subnames[0], 4)) {
1480  /*
1481  * Accept pres[entation]
1482  * This is the combined from name/number presentation.
1483  */
1484  ast_copy_string(buf,
1486  ast_party_id_presentation(&ast_redirecting->from)), len);
1487  } else if (member.argc == 1 && !strcasecmp("reason", member.subnames[0])) {
1488  ast_copy_string(buf, ast_redirecting_reason_name(&ast_redirecting->reason), len);
1489  } else if (member.argc == 1 && !strcasecmp("count", member.subnames[0])) {
1490  snprintf(buf, len, "%d", ast_redirecting->count);
1491  } else if (1 < member.argc && !strcasecmp("priv", member.subnames[0])) {
1492  if (!strcasecmp("orig", member.subnames[1])) {
1493  status = party_id_read(buf, len, member.argc - 2, member.subnames + 2,
1494  &ast_redirecting->priv_orig);
1495  switch (status) {
1496  case ID_FIELD_VALID:
1497  case ID_FIELD_INVALID:
1498  break;
1499  default:
1500  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1501  break;
1502  }
1503  } else if (!strcasecmp("from", member.subnames[1])) {
1504  status = party_id_read(buf, len, member.argc - 2, member.subnames + 2,
1505  &ast_redirecting->priv_from);
1506  switch (status) {
1507  case ID_FIELD_VALID:
1508  case ID_FIELD_INVALID:
1509  break;
1510  default:
1511  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1512  break;
1513  }
1514  } else if (!strcasecmp("to", member.subnames[1])) {
1515  status = party_id_read(buf, len, member.argc - 2, member.subnames + 2,
1516  &ast_redirecting->priv_to);
1517  switch (status) {
1518  case ID_FIELD_VALID:
1519  case ID_FIELD_INVALID:
1520  break;
1521  default:
1522  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1523  break;
1524  }
1525  } else {
1526  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1527  }
1528  } else {
1529  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1530  }
1531 
1532  ast_channel_unlock(chan);
1533 
1534  return 0;
1535 }
1536 
1537 /*!
1538  * \internal
1539  * \brief Write new values to the redirecting information struct.
1540  *
1541  * \param chan Asterisk channel to update
1542  * \param cmd Not used
1543  * \param data Redirecting function datatype string
1544  * \param value Value to assign to the redirecting information struct.
1545  *
1546  * \retval 0 on success.
1547  * \retval -1 on error.
1548  */
1549 static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1550 {
1551  struct ast_party_redirecting redirecting;
1552  enum ID_FIELD_STATUS status;
1553  char *val;
1554  char *parms;
1555  void (*set_it)(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
1556  struct ast_party_func_args args = { 0, };
1557  struct ast_party_members member = { 0, };
1558  struct ast_flags opts;
1559  char *opt_args[REDIRECTING_OPT_ARG_ARRAY_SIZE];
1560 
1561  if (!value || !chan) {
1562  return -1;
1563  }
1564 
1565  parms = ast_strdupa(data);
1566  AST_STANDARD_APP_ARGS(args, parms);
1567  if (args.argc == 0) {
1568  /* Must have at least one argument. */
1569  return -1;
1570  }
1571 
1572  AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1573  if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1574  /* Too few or too many subnames */
1575  return -1;
1576  }
1577 
1578  if (ast_app_parse_options(redirecting_opts, &opts, opt_args, args.opts)) {
1579  /* General invalid option syntax. */
1580  return -1;
1581  }
1582 
1583  /* Determine if the update indication inhibit option is present */
1584  if (ast_test_flag(&opts, REDIRECTING_OPT_INHIBIT)) {
1585  set_it = ast_channel_set_redirecting;
1586  } else {
1588  }
1589 
1590  ast_channel_lock(chan);
1592  ast_channel_unlock(chan);
1593 
1594  value = ast_skip_blanks(value);
1595 
1596  if (!strcasecmp("orig", member.subnames[0])) {
1597  if (member.argc == 2 && !strcasecmp("reason", member.subnames[1])) {
1598  int reason;
1599 
1600  val = ast_strdupa(value);
1601  ast_trim_blanks(val);
1602 
1603  if (('0' <= val[0]) && (val[0] <= '9')) {
1604  reason = atoi(val);
1605  } else {
1606  reason = ast_redirecting_reason_parse(val);
1607  }
1608 
1609  if (reason < 0) {
1610  /* The argument passed into the function does not correspond to a pre-defined
1611  * reason, so we can just set the reason string to what was given and set the
1612  * code to be unknown
1613  */
1615  redirecting.orig_reason.str = val;
1616  set_it(chan, &redirecting, NULL);
1617  } else {
1618  redirecting.orig_reason.code = reason;
1619  redirecting.orig_reason.str = "";
1620  set_it(chan, &redirecting, NULL);
1621  }
1622  } else {
1623  status = party_id_write(&redirecting.orig, member.argc - 1, member.subnames + 1,
1624  value);
1625  switch (status) {
1626  case ID_FIELD_VALID:
1627  set_it(chan, &redirecting, NULL);
1628  break;
1629  case ID_FIELD_INVALID:
1630  break;
1631  default:
1632  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1633  break;
1634  }
1635  ast_party_redirecting_free(&redirecting);
1636  }
1637  } else if (!strcasecmp("from", member.subnames[0])) {
1638  status = party_id_write(&redirecting.from, member.argc - 1, member.subnames + 1,
1639  value);
1640  switch (status) {
1641  case ID_FIELD_VALID:
1642  set_it(chan, &redirecting, NULL);
1643  break;
1644  case ID_FIELD_INVALID:
1645  break;
1646  default:
1647  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1648  break;
1649  }
1650  ast_party_redirecting_free(&redirecting);
1651  } else if (!strcasecmp("to", member.subnames[0])) {
1652  status = party_id_write(&redirecting.to, member.argc - 1, member.subnames + 1, value);
1653  switch (status) {
1654  case ID_FIELD_VALID:
1655  set_it(chan, &redirecting, NULL);
1656  break;
1657  case ID_FIELD_INVALID:
1658  break;
1659  default:
1660  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1661  break;
1662  }
1663  ast_party_redirecting_free(&redirecting);
1664  } else if (member.argc == 1 && !strncasecmp("pres", member.subnames[0], 4)) {
1665  int pres;
1666 
1667  val = ast_strdupa(value);
1668  ast_trim_blanks(val);
1669 
1670  if (('0' <= val[0]) && (val[0] <= '9')) {
1671  pres = atoi(val);
1672  } else {
1673  pres = ast_parse_caller_presentation(val);
1674  }
1675 
1676  if (pres < 0) {
1678  "Unknown redirecting combined presentation '%s', value unchanged\n", val);
1679  } else {
1680  redirecting.from.name.presentation = pres;
1681  redirecting.from.number.presentation = pres;
1682  redirecting.to.name.presentation = pres;
1683  redirecting.to.number.presentation = pres;
1684  set_it(chan, &redirecting, NULL);
1685  }
1686  } else if (member.argc == 1 && !strcasecmp("reason", member.subnames[0])) {
1687  int reason;
1688 
1689  val = ast_strdupa(value);
1690  ast_trim_blanks(val);
1691 
1692  if (('0' <= val[0]) && (val[0] <= '9')) {
1693  reason = atoi(val);
1694  } else {
1695  reason = ast_redirecting_reason_parse(val);
1696  }
1697 
1698  if (reason < 0) {
1699  /* The argument passed into the function does not correspond to a pre-defined
1700  * reason, so we can just set the reason string to what was given and set the
1701  * code to be unknown
1702  */
1704  redirecting.reason.str = val;
1705  set_it(chan, &redirecting, NULL);
1706  } else {
1707  redirecting.reason.code = reason;
1708  redirecting.reason.str = "";
1709  set_it(chan, &redirecting, NULL);
1710  }
1711  } else if (member.argc == 1 && !strcasecmp("count", member.subnames[0])) {
1712  val = ast_strdupa(value);
1713  ast_trim_blanks(val);
1714 
1715  if (('0' <= val[0]) && (val[0] <= '9')) {
1716  redirecting.count = atoi(val);
1717  set_it(chan, &redirecting, NULL);
1718  } else {
1719  ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
1720  }
1721  } else if (1 < member.argc && !strcasecmp("priv", member.subnames[0])) {
1722  if (!strcasecmp("orig", member.subnames[1])) {
1723  status = party_id_write(&redirecting.priv_orig, member.argc - 2, member.subnames + 2,
1724  value);
1725  switch (status) {
1726  case ID_FIELD_VALID:
1727  set_it(chan, &redirecting, NULL);
1728  break;
1729  case ID_FIELD_INVALID:
1730  break;
1731  default:
1732  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1733  break;
1734  }
1735  ast_party_redirecting_free(&redirecting);
1736  } else if (!strcasecmp("from", member.subnames[1])) {
1737  status = party_id_write(&redirecting.priv_from, member.argc - 2, member.subnames + 2,
1738  value);
1739  switch (status) {
1740  case ID_FIELD_VALID:
1741  set_it(chan, &redirecting, NULL);
1742  break;
1743  case ID_FIELD_INVALID:
1744  break;
1745  default:
1746  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1747  break;
1748  }
1749  ast_party_redirecting_free(&redirecting);
1750  } else if (!strcasecmp("to", member.subnames[1])) {
1751  status = party_id_write(&redirecting.priv_to, member.argc - 2, member.subnames + 2, value);
1752  switch (status) {
1753  case ID_FIELD_VALID:
1754  set_it(chan, &redirecting, NULL);
1755  break;
1756  case ID_FIELD_INVALID:
1757  break;
1758  default:
1759  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1760  break;
1761  }
1762  ast_party_redirecting_free(&redirecting);
1763  } else {
1764  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1765  }
1766  } else {
1767  ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1768  }
1769 
1770  return 0;
1771 }
1772 
1774  .name = "CALLERID",
1775  .read = callerid_read,
1776  .read_max = 256,
1777  .write = callerid_write,
1778 };
1779 
1781  .name = "CONNECTEDLINE",
1782  .read = connectedline_read,
1783  .write = connectedline_write,
1784 };
1785 
1787  .name = "REDIRECTING",
1788  .read = redirecting_read,
1789  .write = redirecting_write,
1790 };
1791 
1792 /*!
1793  * \internal
1794  * \brief Unload the function module
1795  *
1796  * \retval 0 on success.
1797  * \retval -1 on error.
1798  */
1799 static int unload_module(void)
1800 {
1801  ast_custom_function_unregister(&callerid_function);
1802  ast_custom_function_unregister(&connectedline_function);
1803  ast_custom_function_unregister(&redirecting_function);
1804  return 0;
1805 }
1806 
1807 /*!
1808  * \internal
1809  * \brief Load and initialize the function module.
1810  *
1811  * \retval AST_MODULE_LOAD_SUCCESS on success.
1812  * \retval AST_MODULE_LOAD_DECLINE on error.
1813  */
1814 static int load_module(void)
1815 {
1816  int res;
1817 
1818  res = ast_custom_function_register(&callerid_function);
1819  res |= ast_custom_function_register(&connectedline_function);
1820  res |= ast_custom_function_register(&redirecting_function);
1821 
1822  if (res) {
1823  unload_module();
1824  return AST_MODULE_LOAD_DECLINE;
1825  }
1826 
1827  return AST_MODULE_LOAD_SUCCESS;
1828 }
1829 
1830 /* Do not wrap the following line. */
1831 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)");
const char * name
Definition: pbx.h:119
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
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:339
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:278
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int unload_module(void)
Main Channel structure associated with a channel.
struct ast_party_dialed::@246 number
Dialed/Called number.
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:389
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
const char * ast_named_caller_presentation(int data)
Convert caller ID pres value to text code.
Definition: callerid.c:1182
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
struct ast_party_id priv_to
Call is redirecting to a new party (Sent to the caller) - private representation. ...
Definition: channel.h:540
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * str
Subscriber phone number (Malloced)
Definition: channel.h:387
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:7472
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:1279
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1092
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
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:459
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:2045
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_id priv_orig
Who originally redirected the call (Sent to the party the call is redirected toward) - private repres...
Definition: channel.h:534
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
#define BEGIN_OPTIONS
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:528
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const char * ast_connected_line_source_name(int data)
Convert connected line update source value to text code.
Definition: callerid.c:1305
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:10379
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
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:1821
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:9189
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:2007
int ast_redirecting_reason_parse(const char *data)
Convert redirecting reason text code to value (used in config file parsing)
Definition: callerid.c:1223
struct ast_party_id priv_from
Who is redirecting the call (Sent to the party the call is redirected toward) - private representatio...
Definition: channel.h:537
int char_set
Character set the name is using.
Definition: channel.h:273
char * str
Subscriber name (Malloced)
Definition: channel.h:265
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2015
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:329
#define AST_DEFINE_APP_ARGS_TYPE(type, arglist)
Define a structure type to hold an application&#39;s arguments.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
const char * args
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:314
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
static struct ast_custom_function callerid_function
const char * ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
Convert redirecting reason value to text code.
Definition: callerid.c:1249
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)
int code
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:511
unsigned char odd_even_indicator
TRUE if odd number of address signals.
Definition: channel.h:327
const char *const subnames[]
Definition: chan_dahdi.c:795
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
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:1958
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward) ...
Definition: channel.h:525
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
Number structure.
Definition: app_followme.c:154
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:421
static int callerid_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
#define ast_log
Definition: astobj2.c:42
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:428
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_redirecting_reason orig_reason
Reason for the redirection by the original party.
Definition: channel.h:546
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
Data structure associated with a custom dialplan function.
Definition: pbx.h:118
Caller Party information.
Definition: channel.h:419
#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:85
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:1334
struct ast_party_id priv
Private caller party ID.
Definition: channel.h:431
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:9215
CONNECTED_LINE_OPT_ARGS
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: main/app.c:2906
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:1143
static const struct ast_app_option connectedline_opts[128]
static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:345
Dialed/Called Party information.
Definition: channel.h:379
#define LOG_ERROR
Definition: logger.h:285
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:1999
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
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:434
Connected Line/Party information.
Definition: channel.h:457
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:182
static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
char * str
a string value for the redirecting reason
Definition: channel.h:508
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const struct ast_app_option redirecting_opts[128]
unsigned int argc
static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static const char name[]
Definition: cdr_mysql.c:74
int source
Information about the source of an update.
Definition: channel.h:483
#define ast_free(a)
Definition: astmm.h:182
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
ID_FIELD_STATUS
struct ast_party_redirecting_reason reason
Reason for the redirection.
Definition: channel.h:543
struct ast_party_subaddress subaddress
Dialed/Called subaddress.
Definition: channel.h:392
Structure used to handle boolean flags.
Definition: utils.h:199
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
const char * ast_party_name_charset_str(int data)
Convert ast_party_name.char_set value to text code.
Definition: callerid.c:1360
char * tag
User-set "tag".
Definition: channel.h:355
CONNECTED_LINE_OPT_FLAGS
int type
Q.931 subaddress type.
Definition: channel.h:321
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:556
int count
Number of times the call was redirected.
Definition: channel.h:549
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:531
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
#define END_OPTIONS
Information needed to specify a number in a call.
Definition: channel.h:290
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:2153
void ast_party_dialed_free(struct ast_party_dialed *doomed)
Destroy the dialed party contents.
Definition: channel.c:1971
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
Information needed to specify a subaddress in a call.
Definition: channel.h:308
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
REDIRECTING_OPT_ARGS
char connected
Definition: eagi_proxy.c:82
Asterisk module definitions.
Information needed to specify a name in a call.
Definition: channel.h:263
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ast_party_id priv
Private connected party ID.
Definition: channel.h:469
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
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:8404
jack_status_t status
Definition: app_jack.c:146
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:1950
#define AST_APP_ARG(name)
Define an application argument.
static int load_module(void)
static struct ast_custom_function connectedline_function
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343