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