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