Asterisk - The Open Source Telephony Project  18.5.0
pjsip/dialplan_functions.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, 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 /*!
18  * \file
19  *
20  * \author \verbatim Joshua Colp <[email protected]> \endverbatim
21  * \author \verbatim Matt Jordan <[email protected]> \endverbatim
22  *
23  * \ingroup functions
24  *
25  * \brief PJSIP channel dialplan functions
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 /*** DOCUMENTATION
33 <function name="PJSIP_DIAL_CONTACTS" language="en_US">
34  <synopsis>
35  Return a dial string for dialing all contacts on an AOR.
36  </synopsis>
37  <syntax>
38  <parameter name="endpoint" required="true">
39  <para>Name of the endpoint</para>
40  </parameter>
41  <parameter name="aor" required="false">
42  <para>Name of an AOR to use, if not specified the configured AORs on the endpoint are used</para>
43  </parameter>
44  <parameter name="request_user" required="false">
45  <para>Optional request user to use in the request URI</para>
46  </parameter>
47  </syntax>
48  <description>
49  <para>Returns a properly formatted dial string for dialing all contacts on an AOR.</para>
50  </description>
51 </function>
52 <function name="PJSIP_MEDIA_OFFER" language="en_US">
53  <synopsis>
54  Media and codec offerings to be set on an outbound SIP channel prior to dialing.
55  </synopsis>
56  <syntax>
57  <parameter name="media" required="true">
58  <para>types of media offered</para>
59  </parameter>
60  </syntax>
61  <description>
62  <para>When read, returns the codecs offered based upon the media choice.</para>
63  <para>When written, sets the codecs to offer when an outbound dial attempt is made,
64  or when a session refresh is sent using <replaceable>PJSIP_SEND_SESSION_REFRESH</replaceable>.
65  </para>
66  </description>
67  <see-also>
68  <ref type="function">PJSIP_SEND_SESSION_REFRESH</ref>
69  </see-also>
70 </function>
71 <function name="PJSIP_DTMF_MODE" language="en_US">
72  <synopsis>
73  Get or change the DTMF mode for a SIP call.
74  </synopsis>
75  <syntax>
76  </syntax>
77  <description>
78  <para>When read, returns the current DTMF mode</para>
79  <para>When written, sets the current DTMF mode</para>
80  <para>This function uses the same DTMF mode naming as the dtmf_mode configuration option</para>
81  </description>
82 </function>
83 <function name="PJSIP_MOH_PASSTHROUGH" language="en_US">
84  <synopsis>
85  Get or change the on-hold behavior for a SIP call.
86  </synopsis>
87  <syntax>
88  </syntax>
89  <description>
90  <para>When read, returns the current moh passthrough mode</para>
91  <para>When written, sets the current moh passthrough mode</para>
92  <para>If <replaceable>yes</replaceable>, on-hold re-INVITEs are sent. If <replaceable>no</replaceable>, music on hold is generated.</para>
93  <para>This function can be used to override the moh_passthrough configuration option</para>
94  </description>
95 </function>
96 <function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
97  <synopsis>
98  W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session
99  </synopsis>
100  <syntax>
101  <parameter name="update_type" required="false">
102  <para>The type of update to send. Default is <literal>invite</literal>.</para>
103  <enumlist>
104  <enum name="invite">
105  <para>Send the session refresh as a re-INVITE.</para>
106  </enum>
107  <enum name="update">
108  <para>Send the session refresh as an UPDATE.</para>
109  </enum>
110  </enumlist>
111  </parameter>
112  </syntax>
113  <description>
114  <para>This function will cause the PJSIP stack to immediately refresh
115  the media session for the channel. This will be done using either a
116  re-INVITE (default) or an UPDATE request.
117  </para>
118  <para>This is most useful when combined with the <replaceable>PJSIP_MEDIA_OFFER</replaceable>
119  dialplan function, as it allows the formats in use on a channel to be
120  re-negotiated after call setup.</para>
121  <warning>
122  <para>The formats the endpoint supports are <emphasis>not</emphasis>
123  checked or enforced by this function. Using this function to offer
124  formats not supported by the endpoint <emphasis>may</emphasis> result
125  in a loss of media.</para>
126  </warning>
127  <example title="Re-negotiate format to g722">
128  ; Within some existing extension on an answered channel
129  same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,g722)
130  same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite)
131  </example>
132  </description>
133  <see-also>
134  <ref type="function">PJSIP_MEDIA_OFFER</ref>
135  </see-also>
136 </function>
137 <function name="PJSIP_PARSE_URI" language="en_US">
138  <synopsis>
139  Parse an uri and return a type part of the URI.
140  </synopsis>
141  <syntax>
142  <parameter name="uri" required="true">
143  <para>URI to parse</para>
144  </parameter>
145  <parameter name="type" required="true">
146  <para>The <literal>type</literal> parameter specifies which URI part to read</para>
147  <enumlist>
148  <enum name="display">
149  <para>Display name.</para>
150  </enum>
151  <enum name="scheme">
152  <para>URI scheme.</para>
153  </enum>
154  <enum name="user">
155  <para>User part.</para>
156  </enum>
157  <enum name="passwd">
158  <para>Password part.</para>
159  </enum>
160  <enum name="host">
161  <para>Host part.</para>
162  </enum>
163  <enum name="port">
164  <para>Port number, or zero.</para>
165  </enum>
166  <enum name="user_param">
167  <para>User parameter.</para>
168  </enum>
169  <enum name="method_param">
170  <para>Method parameter.</para>
171  </enum>
172  <enum name="transport_param">
173  <para>Transport parameter.</para>
174  </enum>
175  <enum name="ttl_param">
176  <para>TTL param, or -1.</para>
177  </enum>
178  <enum name="lr_param">
179  <para>Loose routing param, or zero.</para>
180  </enum>
181  <enum name="maddr_param">
182  <para>Maddr param.</para>
183  </enum>
184  </enumlist>
185  </parameter>
186  </syntax>
187  <description>
188  <para>Parse an URI and return a specified part of the URI.</para>
189  </description>
190 </function>
191 <info name="CHANNEL" language="en_US" tech="PJSIP">
192  <enumlist>
193  <enum name="rtp">
194  <para>R/O Retrieve media related information.</para>
195  <parameter name="type" required="true">
196  <para>When <replaceable>rtp</replaceable> is specified, the
197  <literal>type</literal> parameter must be provided. It specifies
198  which RTP parameter to read.</para>
199  <enumlist>
200  <enum name="src">
201  <para>Retrieve the local address for RTP.</para>
202  </enum>
203  <enum name="dest">
204  <para>Retrieve the remote address for RTP.</para>
205  </enum>
206  <enum name="direct">
207  <para>If direct media is enabled, this address is the remote address
208  used for RTP.</para>
209  </enum>
210  <enum name="secure">
211  <para>Whether or not the media stream is encrypted.</para>
212  <enumlist>
213  <enum name="0">
214  <para>The media stream is not encrypted.</para>
215  </enum>
216  <enum name="1">
217  <para>The media stream is encrypted.</para>
218  </enum>
219  </enumlist>
220  </enum>
221  <enum name="hold">
222  <para>Whether or not the media stream is currently restricted
223  due to a call hold.</para>
224  <enumlist>
225  <enum name="0">
226  <para>The media stream is not held.</para>
227  </enum>
228  <enum name="1">
229  <para>The media stream is held.</para>
230  </enum>
231  </enumlist>
232  </enum>
233  </enumlist>
234  </parameter>
235  <parameter name="media_type" required="false">
236  <para>When <replaceable>rtp</replaceable> is specified, the
237  <literal>media_type</literal> parameter may be provided. It specifies
238  which media stream the chosen RTP parameter should be retrieved
239  from.</para>
240  <enumlist>
241  <enum name="audio">
242  <para>Retrieve information from the audio media stream.</para>
243  <note><para>If not specified, <literal>audio</literal> is used
244  by default.</para></note>
245  </enum>
246  <enum name="video">
247  <para>Retrieve information from the video media stream.</para>
248  </enum>
249  </enumlist>
250  </parameter>
251  </enum>
252  <enum name="rtcp">
253  <para>R/O Retrieve RTCP statistics.</para>
254  <parameter name="statistic" required="true">
255  <para>When <replaceable>rtcp</replaceable> is specified, the
256  <literal>statistic</literal> parameter must be provided. It specifies
257  which RTCP statistic parameter to read.</para>
258  <enumlist>
259  <enum name="all">
260  <para>Retrieve a summary of all RTCP statistics.</para>
261  <para>The following data items are returned in a semi-colon
262  delineated list:</para>
263  <enumlist>
264  <enum name="ssrc">
265  <para>Our Synchronization Source identifier</para>
266  </enum>
267  <enum name="themssrc">
268  <para>Their Synchronization Source identifier</para>
269  </enum>
270  <enum name="lp">
271  <para>Our lost packet count</para>
272  </enum>
273  <enum name="rxjitter">
274  <para>Received packet jitter</para>
275  </enum>
276  <enum name="rxcount">
277  <para>Received packet count</para>
278  </enum>
279  <enum name="txjitter">
280  <para>Transmitted packet jitter</para>
281  </enum>
282  <enum name="txcount">
283  <para>Transmitted packet count</para>
284  </enum>
285  <enum name="rlp">
286  <para>Remote lost packet count</para>
287  </enum>
288  <enum name="rtt">
289  <para>Round trip time</para>
290  </enum>
291  </enumlist>
292  </enum>
293  <enum name="all_jitter">
294  <para>Retrieve a summary of all RTCP Jitter statistics.</para>
295  <para>The following data items are returned in a semi-colon
296  delineated list:</para>
297  <enumlist>
298  <enum name="minrxjitter">
299  <para>Our minimum jitter</para>
300  </enum>
301  <enum name="maxrxjitter">
302  <para>Our max jitter</para>
303  </enum>
304  <enum name="avgrxjitter">
305  <para>Our average jitter</para>
306  </enum>
307  <enum name="stdevrxjitter">
308  <para>Our jitter standard deviation</para>
309  </enum>
310  <enum name="reported_minjitter">
311  <para>Their minimum jitter</para>
312  </enum>
313  <enum name="reported_maxjitter">
314  <para>Their max jitter</para>
315  </enum>
316  <enum name="reported_avgjitter">
317  <para>Their average jitter</para>
318  </enum>
319  <enum name="reported_stdevjitter">
320  <para>Their jitter standard deviation</para>
321  </enum>
322  </enumlist>
323  </enum>
324  <enum name="all_loss">
325  <para>Retrieve a summary of all RTCP packet loss statistics.</para>
326  <para>The following data items are returned in a semi-colon
327  delineated list:</para>
328  <enumlist>
329  <enum name="minrxlost">
330  <para>Our minimum lost packets</para>
331  </enum>
332  <enum name="maxrxlost">
333  <para>Our max lost packets</para>
334  </enum>
335  <enum name="avgrxlost">
336  <para>Our average lost packets</para>
337  </enum>
338  <enum name="stdevrxlost">
339  <para>Our lost packets standard deviation</para>
340  </enum>
341  <enum name="reported_minlost">
342  <para>Their minimum lost packets</para>
343  </enum>
344  <enum name="reported_maxlost">
345  <para>Their max lost packets</para>
346  </enum>
347  <enum name="reported_avglost">
348  <para>Their average lost packets</para>
349  </enum>
350  <enum name="reported_stdevlost">
351  <para>Their lost packets standard deviation</para>
352  </enum>
353  </enumlist>
354  </enum>
355  <enum name="all_rtt">
356  <para>Retrieve a summary of all RTCP round trip time information.</para>
357  <para>The following data items are returned in a semi-colon
358  delineated list:</para>
359  <enumlist>
360  <enum name="minrtt">
361  <para>Minimum round trip time</para>
362  </enum>
363  <enum name="maxrtt">
364  <para>Maximum round trip time</para>
365  </enum>
366  <enum name="avgrtt">
367  <para>Average round trip time</para>
368  </enum>
369  <enum name="stdevrtt">
370  <para>Standard deviation round trip time</para>
371  </enum>
372  </enumlist>
373  </enum>
374  <enum name="txcount"><para>Transmitted packet count</para></enum>
375  <enum name="rxcount"><para>Received packet count</para></enum>
376  <enum name="txjitter"><para>Transmitted packet jitter</para></enum>
377  <enum name="rxjitter"><para>Received packet jitter</para></enum>
378  <enum name="remote_maxjitter"><para>Their max jitter</para></enum>
379  <enum name="remote_minjitter"><para>Their minimum jitter</para></enum>
380  <enum name="remote_normdevjitter"><para>Their average jitter</para></enum>
381  <enum name="remote_stdevjitter"><para>Their jitter standard deviation</para></enum>
382  <enum name="local_maxjitter"><para>Our max jitter</para></enum>
383  <enum name="local_minjitter"><para>Our minimum jitter</para></enum>
384  <enum name="local_normdevjitter"><para>Our average jitter</para></enum>
385  <enum name="local_stdevjitter"><para>Our jitter standard deviation</para></enum>
386  <enum name="txploss"><para>Transmitted packet loss</para></enum>
387  <enum name="rxploss"><para>Received packet loss</para></enum>
388  <enum name="remote_maxrxploss"><para>Their max lost packets</para></enum>
389  <enum name="remote_minrxploss"><para>Their minimum lost packets</para></enum>
390  <enum name="remote_normdevrxploss"><para>Their average lost packets</para></enum>
391  <enum name="remote_stdevrxploss"><para>Their lost packets standard deviation</para></enum>
392  <enum name="local_maxrxploss"><para>Our max lost packets</para></enum>
393  <enum name="local_minrxploss"><para>Our minimum lost packets</para></enum>
394  <enum name="local_normdevrxploss"><para>Our average lost packets</para></enum>
395  <enum name="local_stdevrxploss"><para>Our lost packets standard deviation</para></enum>
396  <enum name="rtt"><para>Round trip time</para></enum>
397  <enum name="maxrtt"><para>Maximum round trip time</para></enum>
398  <enum name="minrtt"><para>Minimum round trip time</para></enum>
399  <enum name="normdevrtt"><para>Average round trip time</para></enum>
400  <enum name="stdevrtt"><para>Standard deviation round trip time</para></enum>
401  <enum name="local_ssrc"><para>Our Synchronization Source identifier</para></enum>
402  <enum name="remote_ssrc"><para>Their Synchronization Source identifier</para></enum>
403  </enumlist>
404  </parameter>
405  <parameter name="media_type" required="false">
406  <para>When <replaceable>rtcp</replaceable> is specified, the
407  <literal>media_type</literal> parameter may be provided. It specifies
408  which media stream the chosen RTCP parameter should be retrieved
409  from.</para>
410  <enumlist>
411  <enum name="audio">
412  <para>Retrieve information from the audio media stream.</para>
413  <note><para>If not specified, <literal>audio</literal> is used
414  by default.</para></note>
415  </enum>
416  <enum name="video">
417  <para>Retrieve information from the video media stream.</para>
418  </enum>
419  </enumlist>
420  </parameter>
421  </enum>
422  <enum name="endpoint">
423  <para>R/O The name of the endpoint associated with this channel.
424  Use the <replaceable>PJSIP_ENDPOINT</replaceable> function to obtain
425  further endpoint related information.</para>
426  </enum>
427  <enum name="contact">
428  <para>R/O The name of the contact associated with this channel.
429  Use the <replaceable>PJSIP_CONTACT</replaceable> function to obtain
430  further contact related information. Note this may not be present and if so
431  is only available on outgoing legs.</para>
432  </enum>
433  <enum name="aor">
434  <para>R/O The name of the AOR associated with this channel.
435  Use the <replaceable>PJSIP_AOR</replaceable> function to obtain
436  further AOR related information. Note this may not be present and if so
437  is only available on outgoing legs.</para>
438  </enum>
439  <enum name="pjsip">
440  <para>R/O Obtain information about the current PJSIP channel and its
441  session.</para>
442  <parameter name="type" required="true">
443  <para>When <replaceable>pjsip</replaceable> is specified, the
444  <literal>type</literal> parameter must be provided. It specifies
445  which signalling parameter to read.</para>
446  <enumlist>
447  <enum name="call-id">
448  <para>The SIP call-id.</para>
449  </enum>
450  <enum name="secure">
451  <para>Whether or not the signalling uses a secure transport.</para>
452  <enumlist>
453  <enum name="0"><para>The signalling uses a non-secure transport.</para></enum>
454  <enum name="1"><para>The signalling uses a secure transport.</para></enum>
455  </enumlist>
456  </enum>
457  <enum name="target_uri">
458  <para>The contact URI where requests are sent.</para>
459  </enum>
460  <enum name="local_uri">
461  <para>The local URI.</para>
462  </enum>
463  <enum name="local_tag">
464  <para>Tag in From header</para>
465  </enum>
466  <enum name="remote_uri">
467  <para>The remote URI.</para>
468  </enum>
469  <enum name="remote_tag">
470  <para>Tag in To header</para>
471  </enum>
472  <enum name="request_uri">
473  <para>The request URI of the incoming <literal>INVITE</literal>
474  associated with the creation of this channel.</para>
475  </enum>
476  <enum name="t38state">
477  <para>The current state of any T.38 fax on this channel.</para>
478  <enumlist>
479  <enum name="DISABLED"><para>T.38 faxing is disabled on this channel.</para></enum>
480  <enum name="LOCAL_REINVITE"><para>Asterisk has sent a <literal>re-INVITE</literal> to the remote end to initiate a T.38 fax.</para></enum>
481  <enum name="REMOTE_REINVITE"><para>The remote end has sent a <literal>re-INVITE</literal> to Asterisk to initiate a T.38 fax.</para></enum>
482  <enum name="ENABLED"><para>A T.38 fax session has been enabled.</para></enum>
483  <enum name="REJECTED"><para>A T.38 fax session was attempted but was rejected.</para></enum>
484  </enumlist>
485  </enum>
486  <enum name="local_addr">
487  <para>On inbound calls, the full IP address and port number that
488  the <literal>INVITE</literal> request was received on. On outbound
489  calls, the full IP address and port number that the <literal>INVITE</literal>
490  request was transmitted from.</para>
491  </enum>
492  <enum name="remote_addr">
493  <para>On inbound calls, the full IP address and port number that
494  the <literal>INVITE</literal> request was received from. On outbound
495  calls, the full IP address and port number that the <literal>INVITE</literal>
496  request was transmitted to.</para>
497  </enum>
498  </enumlist>
499  </parameter>
500  </enum>
501  </enumlist>
502 </info>
503 <info name="CHANNEL_EXAMPLES" language="en_US" tech="PJSIP">
504  <example title="PJSIP specific CHANNEL examples">
505  ; Log the current Call-ID
506  same => n,Log(NOTICE, ${CHANNEL(pjsip,call-id)})
507 
508  ; Log the destination address of the audio stream
509  same => n,Log(NOTICE, ${CHANNEL(rtp,dest)})
510 
511  ; Store the round-trip time associated with a
512  ; video stream in the CDR field video-rtt
513  same => n,Set(CDR(video-rtt)=${CHANNEL(rtcp,rtt,video)})
514  </example>
515 </info>
516 ***/
517 
518 #include "asterisk.h"
519 
520 #include <pjsip.h>
521 #include <pjlib.h>
522 #include <pjsip_ua.h>
523 
524 #include "asterisk/astobj2.h"
525 #include "asterisk/module.h"
526 #include "asterisk/acl.h"
527 #include "asterisk/app.h"
528 #include "asterisk/channel.h"
529 #include "asterisk/stream.h"
530 #include "asterisk/format.h"
531 #include "asterisk/dsp.h"
532 #include "asterisk/pbx.h"
533 #include "asterisk/res_pjsip.h"
535 #include "include/chan_pjsip.h"
536 #include "include/dialplan_functions.h"
537 
538 /*!
539  * \brief String representations of the T.38 state enum
540  */
541 static const char *t38state_to_string[T38_MAX_ENUM] = {
542  [T38_DISABLED] = "DISABLED",
543  [T38_LOCAL_REINVITE] = "LOCAL_REINVITE",
544  [T38_PEER_REINVITE] = "REMOTE_REINVITE",
545  [T38_ENABLED] = "ENABLED",
546  [T38_REJECTED] = "REJECTED",
547 };
548 
549 /*!
550  * \internal \brief Handle reading RTP information
551  */
552 static int channel_read_rtp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
553 {
555  struct ast_sip_session *session;
556  struct ast_sip_session_media *media;
557  struct ast_sockaddr addr;
558 
559  if (!channel) {
560  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
561  return -1;
562  }
563 
564  session = channel->session;
565  if (!session) {
566  ast_log(AST_LOG_WARNING, "Channel %s has no session!\n", ast_channel_name(chan));
567  return -1;
568  }
569 
570  if (ast_strlen_zero(type)) {
571  ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtp' information\n");
572  return -1;
573  }
574 
575  if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
577  } else if (!strcmp(field, "video")) {
579  } else {
580  ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtp' information\n", field);
581  return -1;
582  }
583 
584  if (!media || !media->rtp) {
585  ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
586  ast_channel_name(chan), S_OR(field, "audio"));
587  return -1;
588  }
589 
590  if (!strcmp(type, "src")) {
592  ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
593  } else if (!strcmp(type, "dest")) {
595  ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
596  } else if (!strcmp(type, "direct")) {
598  } else if (!strcmp(type, "secure")) {
599  if (media->srtp) {
600  struct ast_sdp_srtp *srtp = media->srtp;
602  snprintf(buf, buflen, "%d", flag ? 1 : 0);
603  } else {
604  snprintf(buf, buflen, "%d", 0);
605  }
606  } else if (!strcmp(type, "hold")) {
607  snprintf(buf, buflen, "%d", media->remotely_held ? 1 : 0);
608  } else {
609  ast_log(AST_LOG_WARNING, "Unknown type field '%s' specified for 'rtp' information\n", type);
610  return -1;
611  }
612 
613  return 0;
614 }
615 
616 /*!
617  * \internal \brief Handle reading RTCP information
618  */
619 static int channel_read_rtcp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
620 {
622  struct ast_sip_session *session;
623  struct ast_sip_session_media *media;
624 
625  if (!channel) {
626  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
627  return -1;
628  }
629 
630  session = channel->session;
631  if (!session) {
632  ast_log(AST_LOG_WARNING, "Channel %s has no session!\n", ast_channel_name(chan));
633  return -1;
634  }
635 
636  if (ast_strlen_zero(type)) {
637  ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtcp' information\n");
638  return -1;
639  }
640 
641  if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
643  } else if (!strcmp(field, "video")) {
645  } else {
646  ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtcp' information\n", field);
647  return -1;
648  }
649 
650  if (!media || !media->rtp) {
651  ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
652  ast_channel_name(chan), S_OR(field, "audio"));
653  return -1;
654  }
655 
656  if (!strncasecmp(type, "all", 3)) {
658 
659  if (!strcasecmp(type, "all_jitter")) {
661  } else if (!strcasecmp(type, "all_rtt")) {
663  } else if (!strcasecmp(type, "all_loss")) {
665  }
666 
667  if (!ast_rtp_instance_get_quality(media->rtp, stat_field, buf, buflen)) {
668  ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
669  return -1;
670  }
671  } else {
672  struct ast_rtp_instance_stats stats;
673  int i;
674  struct {
675  const char *name;
676  enum { INT, DBL } type;
677  union {
678  unsigned int *i4;
679  double *d8;
680  };
681  } lookup[] = {
682  { "txcount", INT, { .i4 = &stats.txcount, }, },
683  { "rxcount", INT, { .i4 = &stats.rxcount, }, },
684  { "txjitter", DBL, { .d8 = &stats.txjitter, }, },
685  { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, },
686  { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, },
687  { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, },
688  { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, },
689  { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, },
690  { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, },
691  { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, },
692  { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, },
693  { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, },
694  { "txploss", INT, { .i4 = &stats.txploss, }, },
695  { "rxploss", INT, { .i4 = &stats.rxploss, }, },
696  { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, },
697  { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, },
698  { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, },
699  { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, },
700  { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, },
701  { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, },
702  { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, },
703  { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, },
704  { "rtt", DBL, { .d8 = &stats.rtt, }, },
705  { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, },
706  { "minrtt", DBL, { .d8 = &stats.minrtt, }, },
707  { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, },
708  { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, },
709  { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, },
710  { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, },
711  { NULL, },
712  };
713 
715  ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
716  return -1;
717  }
718 
719  for (i = 0; !ast_strlen_zero(lookup[i].name); i++) {
720  if (!strcasecmp(type, lookup[i].name)) {
721  if (lookup[i].type == INT) {
722  snprintf(buf, buflen, "%u", *lookup[i].i4);
723  } else {
724  snprintf(buf, buflen, "%f", *lookup[i].d8);
725  }
726  return 0;
727  }
728  }
729  ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'rtcp' information\n", type);
730  return -1;
731  }
732 
733  return 0;
734 }
735 
736 static int print_escaped_uri(struct ast_channel *chan, const char *type,
737  pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
738 {
739  int res;
740  char *buf_copy;
741 
742  res = pjsip_uri_print(context, uri, buf, size);
743  if (res < 0) {
744  ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n",
745  ast_channel_name(chan), type, (int) size);
746 
747  /* Empty buffer that likely is not terminated. */
748  buf[0] = '\0';
749  return -1;
750  }
751 
752  buf_copy = ast_strdupa(buf);
753  ast_escape_quoted(buf_copy, buf, size);
754  return 0;
755 }
756 
757 /*!
758  * \internal \brief Handle reading signalling information
759  */
760 static int channel_read_pjsip(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
761 {
763  char *buf_copy;
764  pjsip_dialog *dlg;
765  int res = 0;
766 
767  if (!channel) {
768  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
769  return -1;
770  }
771 
772  dlg = channel->session->inv_session->dlg;
773 
774  if (ast_strlen_zero(type)) {
775  ast_log(LOG_WARNING, "You must supply a type field for 'pjsip' information\n");
776  return -1;
777  } else if (!strcmp(type, "call-id")) {
778  snprintf(buf, buflen, "%.*s", (int) pj_strlen(&dlg->call_id->id), pj_strbuf(&dlg->call_id->id));
779  } else if (!strcmp(type, "secure")) {
780 #ifdef HAVE_PJSIP_GET_DEST_INFO
781  pjsip_host_info dest;
782  pj_pool_t *pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "secure-check", 128, 128);
783  pjsip_get_dest_info(dlg->target, NULL, pool, &dest);
784  snprintf(buf, buflen, "%d", dest.flag & PJSIP_TRANSPORT_SECURE ? 1 : 0);
785  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
786 #else
787  ast_log(LOG_WARNING, "Asterisk has been built against a version of pjproject which does not have the required functionality to support the 'secure' argument. Please upgrade to version 2.3 or later.\n");
788  return -1;
789 #endif
790  } else if (!strcmp(type, "target_uri")) {
791  res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf,
792  buflen);
793  } else if (!strcmp(type, "local_uri")) {
794  res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri,
795  buf, buflen);
796  } else if (!strcmp(type, "local_tag")) {
797  ast_copy_pj_str(buf, &dlg->local.info->tag, buflen);
798  buf_copy = ast_strdupa(buf);
799  ast_escape_quoted(buf_copy, buf, buflen);
800  } else if (!strcmp(type, "remote_uri")) {
801  res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR,
802  dlg->remote.info->uri, buf, buflen);
803  } else if (!strcmp(type, "remote_tag")) {
804  ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen);
805  buf_copy = ast_strdupa(buf);
806  ast_escape_quoted(buf_copy, buf, buflen);
807  } else if (!strcmp(type, "request_uri")) {
808  if (channel->session->request_uri) {
809  res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI,
810  channel->session->request_uri, buf, buflen);
811  }
812  } else if (!strcmp(type, "t38state")) {
813  ast_copy_string(buf, t38state_to_string[channel->session->t38state], buflen);
814  } else if (!strcmp(type, "local_addr")) {
815  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
816  struct transport_info_data *transport_data;
817 
818  datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
819  if (!datastore) {
820  ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
821  return -1;
822  }
823  transport_data = datastore->data;
824 
825  if (pj_sockaddr_has_addr(&transport_data->local_addr)) {
826  pj_sockaddr_print(&transport_data->local_addr, buf, buflen, 3);
827  }
828  } else if (!strcmp(type, "remote_addr")) {
829  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
830  struct transport_info_data *transport_data;
831 
832  datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
833  if (!datastore) {
834  ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
835  return -1;
836  }
837  transport_data = datastore->data;
838 
839  if (pj_sockaddr_has_addr(&transport_data->remote_addr)) {
840  pj_sockaddr_print(&transport_data->remote_addr, buf, buflen, 3);
841  }
842  } else {
843  ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'pjsip' information\n", type);
844  return -1;
845  }
846 
847  return res;
848 }
849 
850 /*! \brief Struct used to push function arguments to task processor */
853  const char *param;
854  const char *type;
855  const char *field;
856  char *buf;
857  size_t len;
858  int ret;
859 };
860 
861 /*! \internal \brief Taskprocessor callback that handles the read on a PJSIP thread */
862 static int read_pjsip(void *data)
863 {
864  struct pjsip_func_args *func_args = data;
865 
866  if (!strcmp(func_args->param, "rtp")) {
867  if (!func_args->session->channel) {
868  func_args->ret = -1;
869  return 0;
870  }
871  func_args->ret = channel_read_rtp(func_args->session->channel, func_args->type,
872  func_args->field, func_args->buf,
873  func_args->len);
874  } else if (!strcmp(func_args->param, "rtcp")) {
875  if (!func_args->session->channel) {
876  func_args->ret = -1;
877  return 0;
878  }
879  func_args->ret = channel_read_rtcp(func_args->session->channel, func_args->type,
880  func_args->field, func_args->buf,
881  func_args->len);
882  } else if (!strcmp(func_args->param, "endpoint")) {
883  if (!func_args->session->endpoint) {
884  ast_log(AST_LOG_WARNING, "Channel %s has no endpoint!\n", func_args->session->channel ?
885  ast_channel_name(func_args->session->channel) : "<unknown>");
886  func_args->ret = -1;
887  return 0;
888  }
889  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->endpoint));
890  } else if (!strcmp(func_args->param, "contact")) {
891  if (!func_args->session->contact) {
892  return 0;
893  }
894  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->contact));
895  } else if (!strcmp(func_args->param, "aor")) {
896  if (!func_args->session->aor) {
897  return 0;
898  }
899  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->aor));
900  } else if (!strcmp(func_args->param, "pjsip")) {
901  if (!func_args->session->channel) {
902  func_args->ret = -1;
903  return 0;
904  }
905  func_args->ret = channel_read_pjsip(func_args->session->channel, func_args->type,
906  func_args->field, func_args->buf,
907  func_args->len);
908  } else {
909  func_args->ret = -1;
910  }
911 
912  return 0;
913 }
914 
915 
916 int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
917 {
918  struct pjsip_func_args func_args = { 0, };
920  char *parse = ast_strdupa(data);
921 
923  AST_APP_ARG(param);
924  AST_APP_ARG(type);
925  AST_APP_ARG(field);
926  );
927 
928  if (!chan) {
929  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
930  return -1;
931  }
932 
933  /* Check for zero arguments */
934  if (ast_strlen_zero(parse)) {
935  ast_log(LOG_ERROR, "Cannot call %s without arguments\n", cmd);
936  return -1;
937  }
938 
939  AST_STANDARD_APP_ARGS(args, parse);
940 
941  ast_channel_lock(chan);
942 
943  /* Sanity check */
944  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
945  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
946  ast_channel_unlock(chan);
947  return 0;
948  }
949 
950  channel = ast_channel_tech_pvt(chan);
951  if (!channel) {
952  ast_log(LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
953  ast_channel_unlock(chan);
954  return -1;
955  }
956 
957  if (!channel->session) {
958  ast_log(LOG_WARNING, "Channel %s has no session\n", ast_channel_name(chan));
959  ast_channel_unlock(chan);
960  return -1;
961  }
962 
963  func_args.session = ao2_bump(channel->session);
964  ast_channel_unlock(chan);
965 
966  memset(buf, 0, len);
967 
968  func_args.param = args.param;
969  func_args.type = args.type;
970  func_args.field = args.field;
971  func_args.buf = buf;
972  func_args.len = len;
973  if (ast_sip_push_task_wait_serializer(func_args.session->serializer, read_pjsip, &func_args)) {
974  ast_log(LOG_WARNING, "Unable to read properties of channel %s: failed to push task\n", ast_channel_name(chan));
975  ao2_ref(func_args.session, -1);
976  return -1;
977  }
978  ao2_ref(func_args.session, -1);
979 
980  return func_args.ret;
981 }
982 
983 int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
984 {
985  RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
986  RAII_VAR(struct ast_str *, dial, NULL, ast_free_ptr);
987  const char *aor_name;
988  char *rest;
989 
991  AST_APP_ARG(endpoint_name);
992  AST_APP_ARG(aor_name);
993  AST_APP_ARG(request_user);
994  );
995 
997 
998  if (ast_strlen_zero(args.endpoint_name)) {
999  ast_log(LOG_WARNING, "An endpoint name must be specified when using the '%s' dialplan function\n", cmd);
1000  return -1;
1001  } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", args.endpoint_name))) {
1002  ast_log(LOG_WARNING, "Specified endpoint '%s' was not found\n", args.endpoint_name);
1003  return -1;
1004  }
1005 
1006  aor_name = S_OR(args.aor_name, endpoint->aors);
1007 
1008  if (ast_strlen_zero(aor_name)) {
1009  ast_log(LOG_WARNING, "No AOR has been provided and no AORs are configured on endpoint '%s'\n", args.endpoint_name);
1010  return -1;
1011  } else if (!(dial = ast_str_create(len))) {
1012  ast_log(LOG_WARNING, "Could not get enough buffer space for dialing contacts\n");
1013  return -1;
1014  } else if (!(rest = ast_strdupa(aor_name))) {
1015  ast_log(LOG_WARNING, "Could not duplicate provided AORs\n");
1016  return -1;
1017  }
1018 
1019  while ((aor_name = ast_strip(strsep(&rest, ",")))) {
1021  RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
1022  struct ao2_iterator it_contacts;
1023  struct ast_sip_contact *contact;
1024 
1025  if (!aor) {
1026  /* If the AOR provided is not found skip it, there may be more */
1027  continue;
1029  /* No contacts are available, skip it as well */
1030  continue;
1031  } else if (!ao2_container_count(contacts)) {
1032  /* We were given a container but no contacts are in it... */
1033  continue;
1034  }
1035 
1036  it_contacts = ao2_iterator_init(contacts, 0);
1037  for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
1038  ast_str_append(&dial, -1, "PJSIP/");
1039 
1040  if (!ast_strlen_zero(args.request_user)) {
1041  ast_str_append(&dial, -1, "%s@", args.request_user);
1042  }
1043  ast_str_append(&dial, -1, "%s/%s&", args.endpoint_name, contact->uri);
1044  }
1045  ao2_iterator_destroy(&it_contacts);
1046  }
1047 
1048  /* Trim the '&' at the end off */
1049  ast_str_truncate(dial, ast_str_strlen(dial) - 1);
1050 
1051  ast_copy_string(buf, ast_str_buffer(dial), len);
1052 
1053  return 0;
1054 }
1055 
1056 /*! \brief Session refresh state information */
1058  /*! \brief Created proposed media state */
1060 };
1061 
1062 /*! \brief Destructor for session refresh information */
1063 static void session_refresh_state_destroy(void *obj)
1064 {
1065  struct session_refresh_state *state = obj;
1066 
1068  ast_free(obj);
1069 }
1070 
1071 /*! \brief Datastore for attaching session refresh state information */
1073  .type = "pjsip_session_refresh",
1074  .destroy = session_refresh_state_destroy,
1075 };
1076 
1077 /*! \brief Helper function which retrieves or allocates a session refresh state information datastore */
1079 {
1080  RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "pjsip_session_refresh"), ao2_cleanup);
1081  struct session_refresh_state *state;
1082 
1083  /* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
1084  if (datastore) {
1085  return datastore->data;
1086  }
1087 
1088  if (!(datastore = ast_sip_session_alloc_datastore(&session_refresh_datastore, "pjsip_session_refresh"))
1089  || !(datastore->data = ast_calloc(1, sizeof(struct session_refresh_state)))
1090  || ast_sip_session_add_datastore(session, datastore)) {
1091  return NULL;
1092  }
1093 
1094  state = datastore->data;
1096  if (!state->media_state) {
1097  ast_sip_session_remove_datastore(session, "pjsip_session_refresh");
1098  return NULL;
1099  }
1101  if (!state->media_state->topology) {
1102  ast_sip_session_remove_datastore(session, "pjsip_session_refresh");
1103  return NULL;
1104  }
1105 
1106  datastore->data = state;
1107 
1108  return state;
1109 }
1110 
1111 /*! \brief Struct used to push PJSIP_PARSE_URI function arguments to task processor */
1113  const char *uri;
1114  const char *type;
1115  char *buf;
1116  size_t buflen;
1117  int ret;
1118 };
1119 
1120 /*! \internal \brief Taskprocessor callback that handles the PJSIP_PARSE_URI on a PJSIP thread */
1121 static int parse_uri_cb(void *data)
1122 {
1123  struct parse_uri_args *args = data;
1124  pj_pool_t *pool;
1125  pjsip_name_addr *uri;
1126  pjsip_sip_uri *sip_uri;
1127  pj_str_t tmp;
1128 
1129  args->ret = 0;
1130 
1131  pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "ParseUri", 128, 128);
1132  if (!pool) {
1133  ast_log(LOG_ERROR, "Failed to allocate ParseUri endpoint pool.\n");
1134  args->ret = -1;
1135  return 0;
1136  }
1137 
1138  pj_strdup2_with_null(pool, &tmp, args->uri);
1139  uri = (pjsip_name_addr *)pjsip_parse_uri(pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
1140  if (!uri || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1141  ast_log(LOG_WARNING, "Failed to parse URI '%s'\n", args->uri);
1142  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1143  args->ret = -1;
1144  return 0;
1145  }
1146 
1147  if (!strcmp(args->type, "scheme")) {
1148  ast_copy_pj_str(args->buf, pjsip_uri_get_scheme(uri), args->buflen);
1149  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1150  return 0;
1151  } else if (!strcmp(args->type, "display")) {
1152  ast_copy_pj_str(args->buf, &uri->display, args->buflen);
1153  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1154  return 0;
1155  }
1156 
1157  sip_uri = pjsip_uri_get_uri(uri);
1158  if (!sip_uri) {
1159  ast_log(LOG_ERROR, "Failed to get an URI object for '%s'\n", args->uri);
1160  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1161  args->ret = -1;
1162  return 0;
1163  }
1164 
1165  if (!strcmp(args->type, "user")) {
1166  ast_copy_pj_str(args->buf, &sip_uri->user, args->buflen);
1167  } else if (!strcmp(args->type, "passwd")) {
1168  ast_copy_pj_str(args->buf, &sip_uri->passwd, args->buflen);
1169  } else if (!strcmp(args->type, "host")) {
1170  ast_copy_pj_str(args->buf, &sip_uri->host, args->buflen);
1171  } else if (!strcmp(args->type, "port")) {
1172  snprintf(args->buf, args->buflen, "%d", sip_uri->port);
1173  } else if (!strcmp(args->type, "user_param")) {
1174  ast_copy_pj_str(args->buf, &sip_uri->user_param, args->buflen);
1175  } else if (!strcmp(args->type, "method_param")) {
1176  ast_copy_pj_str(args->buf, &sip_uri->method_param, args->buflen);
1177  } else if (!strcmp(args->type, "transport_param")) {
1178  ast_copy_pj_str(args->buf, &sip_uri->transport_param, args->buflen);
1179  } else if (!strcmp(args->type, "ttl_param")) {
1180  snprintf(args->buf, args->buflen, "%d", sip_uri->ttl_param);
1181  } else if (!strcmp(args->type, "lr_param")) {
1182  snprintf(args->buf, args->buflen, "%d", sip_uri->lr_param);
1183  } else if (!strcmp(args->type, "maddr_param")) {
1184  ast_copy_pj_str(args->buf, &sip_uri->maddr_param, args->buflen);
1185  } else {
1186  ast_log(AST_LOG_WARNING, "Unknown type part '%s' specified\n", args->type);
1187  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1188  args->ret = -1;
1189  return 0;
1190  }
1191 
1192  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1193 
1194  return 0;
1195 }
1196 
1197 int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
1198 {
1199  struct parse_uri_args func_args = { 0, };
1200 
1202  AST_APP_ARG(uri_str);
1203  AST_APP_ARG(type);
1204  );
1205 
1206  AST_STANDARD_APP_ARGS(args, data);
1207 
1208  if (ast_strlen_zero(args.uri_str)) {
1209  ast_log(LOG_WARNING, "An URI must be specified when using the '%s' dialplan function\n", cmd);
1210  return -1;
1211  }
1212 
1213  if (ast_strlen_zero(args.type)) {
1214  ast_log(LOG_WARNING, "A type part of the URI must be specified when using the '%s' dialplan function\n", cmd);
1215  return -1;
1216  }
1217 
1218  memset(buf, 0, buflen);
1219 
1220  func_args.uri = args.uri_str;
1221  func_args.type = args.type;
1222  func_args.buf = buf;
1223  func_args.buflen = buflen;
1225  ast_log(LOG_WARNING, "Unable to parse URI: failed to push task\n");
1226  return -1;
1227  }
1228 
1229  return func_args.ret;
1230 }
1231 
1233  size_t len, enum ast_media_type media_type)
1234 {
1235  struct ast_stream_topology *topology;
1236  int idx;
1237  struct ast_stream *stream = NULL;
1238  const struct ast_format_cap *caps;
1239  size_t accum = 0;
1240 
1241  if (session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1242  struct session_refresh_state *state;
1243 
1244  /* As we've already answered we need to store our media state until we are ready to send it */
1245  state = session_refresh_state_get_or_alloc(session);
1246  if (!state) {
1247  return -1;
1248  }
1249  topology = state->media_state->topology;
1250  } else {
1251  /* The session is not yet up so we are initially answering or offering */
1252  if (!session->pending_media_state->topology) {
1254  if (!session->pending_media_state->topology) {
1255  return -1;
1256  }
1257  }
1258  topology = session->pending_media_state->topology;
1259  }
1260 
1261  /* Find the first suitable stream */
1262  for (idx = 0; idx < ast_stream_topology_get_count(topology); ++idx) {
1263  stream = ast_stream_topology_get_stream(topology, idx);
1264 
1265  if (ast_stream_get_type(stream) != media_type ||
1267  stream = NULL;
1268  continue;
1269  }
1270 
1271  break;
1272  }
1273 
1274  /* If no suitable stream then exit early */
1275  if (!stream) {
1276  buf[0] = '\0';
1277  return 0;
1278  }
1279 
1280  caps = ast_stream_get_formats(stream);
1281 
1282  /* Note: buf is not terminated while the string is being built. */
1283  for (idx = 0; idx < ast_format_cap_count(caps); ++idx) {
1284  struct ast_format *fmt;
1285  size_t size;
1286 
1287  fmt = ast_format_cap_get_format(caps, idx);
1288 
1289  /* Add one for a comma or terminator */
1290  size = strlen(ast_format_get_name(fmt)) + 1;
1291  if (len < size) {
1292  ao2_ref(fmt, -1);
1293  break;
1294  }
1295 
1296  /* Append the format name */
1297  strcpy(buf + accum, ast_format_get_name(fmt));/* Safe */
1298  ao2_ref(fmt, -1);
1299 
1300  accum += size;
1301  len -= size;
1302 
1303  /* The last comma on the built string will be set to the terminator. */
1304  buf[accum - 1] = ',';
1305  }
1306 
1307  /* Remove the trailing comma or terminate an empty buffer. */
1308  buf[accum ? accum - 1 : 0] = '\0';
1309  return 0;
1310 }
1311 
1315  const char *value;
1316 };
1317 
1318 static int media_offer_write_av(void *obj)
1319 {
1320  struct media_offer_data *data = obj;
1321  struct ast_stream_topology *topology;
1322  struct ast_stream *stream;
1323  struct ast_format_cap *caps;
1324 
1325  if (data->session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1326  struct session_refresh_state *state;
1327 
1328  /* As we've already answered we need to store our media state until we are ready to send it */
1330  if (!state) {
1331  return -1;
1332  }
1333  topology = state->media_state->topology;
1334  } else {
1335  /* The session is not yet up so we are initially answering or offering */
1336  if (!data->session->pending_media_state->topology) {
1338  if (!data->session->pending_media_state->topology) {
1339  return -1;
1340  }
1341  }
1342  topology = data->session->pending_media_state->topology;
1343  }
1344 
1345  /* XXX This method won't work when it comes time to do multistream support. The proper way to do this
1346  * will either be to
1347  * a) Alter all media streams of a particular type.
1348  * b) Change the dialplan function to be able to specify which stream to alter and alter only that
1349  * one stream
1350  */
1351  stream = ast_stream_topology_get_first_stream_by_type(topology, data->media_type);
1352  if (!stream) {
1353  return 0;
1354  }
1355 
1357  if (!caps) {
1358  return -1;
1359  }
1360 
1365  ast_stream_set_formats(stream, caps);
1366  ast_stream_set_metadata(stream, "pjsip_session_refresh", "force");
1367  ao2_ref(caps, -1);
1368 
1369  return 0;
1370 }
1371 
1372 int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1373 {
1374  struct ast_sip_channel_pvt *channel;
1375 
1376  if (!chan) {
1377  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1378  return -1;
1379  }
1380 
1381  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1382  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1383  return -1;
1384  }
1385 
1386  channel = ast_channel_tech_pvt(chan);
1387 
1388  if (!strcmp(data, "audio")) {
1389  return media_offer_read_av(channel->session, buf, len, AST_MEDIA_TYPE_AUDIO);
1390  } else if (!strcmp(data, "video")) {
1391  return media_offer_read_av(channel->session, buf, len, AST_MEDIA_TYPE_VIDEO);
1392  } else {
1393  /* Ensure that the buffer is empty */
1394  buf[0] = '\0';
1395  }
1396 
1397  return 0;
1398 }
1399 
1400 int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1401 {
1402  struct ast_sip_channel_pvt *channel;
1403  struct media_offer_data mdata = {
1404  .value = value
1405  };
1406 
1407  if (!chan) {
1408  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1409  return -1;
1410  }
1411 
1412  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1413  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1414  return -1;
1415  }
1416 
1417  channel = ast_channel_tech_pvt(chan);
1418  mdata.session = channel->session;
1419 
1420  if (!strcmp(data, "audio")) {
1422  } else if (!strcmp(data, "video")) {
1424  }
1425 
1427 }
1428 
1429 int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1430 {
1431  struct ast_sip_channel_pvt *channel;
1432 
1433  if (!chan) {
1434  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1435  return -1;
1436  }
1437 
1438  ast_channel_lock(chan);
1439  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1440  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1441  ast_channel_unlock(chan);
1442  return -1;
1443  }
1444 
1445  channel = ast_channel_tech_pvt(chan);
1446 
1447  if (ast_sip_dtmf_to_str(channel->session->dtmf, buf, len) < 0) {
1448  ast_log(LOG_WARNING, "Unknown DTMF mode %d on PJSIP channel %s\n", channel->session->dtmf, ast_channel_name(chan));
1449  ast_channel_unlock(chan);
1450  return -1;
1451  }
1452 
1453  ast_channel_unlock(chan);
1454  return 0;
1455 }
1456 
1457 int pjsip_acf_moh_passthrough_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
1458 {
1459  struct ast_sip_channel_pvt *channel;
1460 
1461  if (!chan) {
1462  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1463  return -1;
1464  }
1465 
1466  if (len < 3) {
1467  ast_log(LOG_WARNING, "%s: buffer too small\n", cmd);
1468  return -1;
1469  }
1470 
1471  ast_channel_lock(chan);
1472  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1473  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1474  ast_channel_unlock(chan);
1475  return -1;
1476  }
1477 
1478  channel = ast_channel_tech_pvt(chan);
1479  strncpy(buf, AST_YESNO(channel->session->moh_passthrough), len);
1480 
1481  ast_channel_unlock(chan);
1482  return 0;
1483 }
1484 
1488 };
1489 
1490 static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
1491 {
1492  struct ast_format *fmt;
1493 
1494  if (!session->channel) {
1495  /* Egads! */
1496  return 0;
1497  }
1498 
1500  if (!fmt) {
1501  /* No format? That's weird. */
1502  return 0;
1503  }
1504  ast_channel_set_writeformat(session->channel, fmt);
1505  ast_channel_set_rawwriteformat(session->channel, fmt);
1506  ast_channel_set_readformat(session->channel, fmt);
1507  ast_channel_set_rawreadformat(session->channel, fmt);
1508  ao2_ref(fmt, -1);
1509 
1510  return 0;
1511 }
1512 
1513 static int dtmf_mode_refresh_cb(void *obj)
1514 {
1515  struct refresh_data *data = obj;
1516 
1517  if (data->session->inv_session->state == PJSIP_INV_STATE_CONFIRMED) {
1518  ast_debug(3, "Changing DTMF mode on channel %s after OFFER/ANSWER completion. Sending session refresh\n", ast_channel_name(data->session->channel));
1519 
1521  sip_session_response_cb, data->method, 1, NULL);
1522  } else if (data->session->inv_session->state == PJSIP_INV_STATE_INCOMING) {
1523  ast_debug(3, "Changing DTMF mode on channel %s during OFFER/ANSWER exchange. Updating SDP answer\n", ast_channel_name(data->session->channel));
1525  }
1526 
1527  return 0;
1528 }
1529 
1530 int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1531 {
1532  struct ast_sip_channel_pvt *channel;
1533  struct ast_sip_session_media *media;
1534  int dsp_features = 0;
1535  int dtmf = -1;
1536  struct refresh_data rdata = {
1538  };
1539 
1540  if (!chan) {
1541  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1542  return -1;
1543  }
1544 
1545  ast_channel_lock(chan);
1546  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1547  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1548  ast_channel_unlock(chan);
1549  return -1;
1550  }
1551 
1552  channel = ast_channel_tech_pvt(chan);
1553  rdata.session = channel->session;
1554 
1555  dtmf = ast_sip_str_to_dtmf(value);
1556 
1557  if (dtmf == -1) {
1558  ast_log(LOG_WARNING, "Cannot set DTMF mode to '%s' on channel '%s' as value is invalid.\n", value,
1559  ast_channel_name(chan));
1560  ast_channel_unlock(chan);
1561  return -1;
1562  }
1563 
1564  if (channel->session->dtmf == dtmf) {
1565  /* DTMF mode unchanged, nothing to do! */
1566  ast_channel_unlock(chan);
1567  return 0;
1568  }
1569 
1570  channel->session->dtmf = dtmf;
1571 
1573 
1574  if (media && media->rtp) {
1575  if (channel->session->dtmf == AST_SIP_DTMF_RFC_4733) {
1578  } else if (channel->session->dtmf == AST_SIP_DTMF_INFO) {
1581  } else if (channel->session->dtmf == AST_SIP_DTMF_INBAND) {
1584  } else if (channel->session->dtmf == AST_SIP_DTMF_NONE) {
1587  } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO) {
1589  /* no RFC4733 negotiated, enable inband */
1591  }
1592  } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
1595  /* if inband, switch to INFO */
1597  }
1598  }
1599  }
1600 
1601  if (channel->session->dsp) {
1602  dsp_features = ast_dsp_get_features(channel->session->dsp);
1603  }
1604  if (channel->session->dtmf == AST_SIP_DTMF_INBAND ||
1605  channel->session->dtmf == AST_SIP_DTMF_AUTO) {
1606  dsp_features |= DSP_FEATURE_DIGIT_DETECT;
1607  } else {
1608  dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
1609  }
1610  if (dsp_features) {
1611  if (!channel->session->dsp) {
1612  if (!(channel->session->dsp = ast_dsp_new())) {
1613  ast_channel_unlock(chan);
1614  return 0;
1615  }
1616  }
1617  ast_dsp_set_features(channel->session->dsp, dsp_features);
1618  } else if (channel->session->dsp) {
1619  ast_dsp_free(channel->session->dsp);
1620  channel->session->dsp = NULL;
1621  }
1622 
1623  ast_channel_unlock(chan);
1624 
1626 }
1627 
1628 int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1629 {
1630  struct ast_sip_channel_pvt *channel;
1631 
1632  if (!chan) {
1633  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1634  return -1;
1635  }
1636 
1637  ast_channel_lock(chan);
1638  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1639  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1640  ast_channel_unlock(chan);
1641  return -1;
1642  }
1643 
1644  channel = ast_channel_tech_pvt(chan);
1645  channel->session->moh_passthrough = ast_true(value);
1646 
1647  ast_channel_unlock(chan);
1648 
1649  return 0;
1650 }
1651 
1652 static int refresh_write_cb(void *obj)
1653 {
1654  struct refresh_data *data = obj;
1655  struct session_refresh_state *state;
1656 
1658  if (!state) {
1659  return -1;
1660  }
1661 
1663  sip_session_response_cb, data->method, 1, state->media_state);
1664 
1665  state->media_state = NULL;
1666  ast_sip_session_remove_datastore(data->session, "pjsip_session_refresh");
1667 
1668  return 0;
1669 }
1670 
1671 int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
1672 {
1673  struct ast_sip_channel_pvt *channel;
1674  struct refresh_data rdata = {
1676  };
1677 
1678  if (!chan) {
1679  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1680  return -1;
1681  }
1682 
1683  if (ast_channel_state(chan) != AST_STATE_UP) {
1684  ast_log(LOG_WARNING, "'%s' not allowed on unanswered channel '%s'.\n", cmd, ast_channel_name(chan));
1685  return -1;
1686  }
1687 
1688  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1689  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1690  return -1;
1691  }
1692 
1693  channel = ast_channel_tech_pvt(chan);
1694  rdata.session = channel->session;
1695 
1696  if (!strcmp(value, "invite")) {
1698  } else if (!strcmp(value, "update")) {
1700  }
1701 
1703 }
const char * type
Definition: datastore.h:32
int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_MEDIA_OFFER function read callback.
static const char type[]
Definition: chan_ooh323.c:109
structure for secure RTP audio
Definition: sdp_srtp.h:37
enum sip_cc_notify_state state
Definition: chan_sip.c:959
enum ast_sip_session_t38state t38state
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define T38_ENABLED
Definition: chan_ooh323.c:102
static int print_escaped_uri(struct ast_channel *chan, const char *type, pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
Asterisk main include file. File version handling, generic pbx functions.
Structure which contains media state information (streams, sessions)
enum ast_media_type media_type
A SIP address of record.
Definition: res_pjsip.h:361
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_sip_session_media_state * pending_media_state
struct ast_sockaddr direct_media_addr
Direct media address.
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2123
static int channel_read_rtcp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
Struct used to push PJSIP_PARSE_URI function arguments to task processor.
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2446
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
void * ast_channel_tech_pvt(const struct ast_channel *chan)
pjsip_uri * request_uri
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Convenient Signal Processing routines.
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
unsigned int txcount
Definition: rtp_engine.h:368
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
struct ast_sip_session_media_state * media_state
Created proposed media state.
static int tmp()
Definition: bt_open.c:389
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define AST_LOG_WARNING
Definition: logger.h:279
static int media_offer_write_av(void *obj)
Set when the stream has been removed/declined.
Definition: stream.h:78
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
unsigned int rxploss
Definition: rtp_engine.h:394
Session refresh state information.
int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MOH_PASSTHROUGH function write callback.
Structure for a data store type.
Definition: datastore.h:31
ast_channel_state
ast_channel states
Definition: channelstate.h:35
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition of a media format.
Definition: format.c:43
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417
Definition: muted.c:95
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Structure for a data store object.
Definition: datastore.h:68
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
int ast_sip_str_to_dtmf(const char *dtmf_mode)
Convert the DTMF mode name into an enum.
Definition: res_pjsip.c:5513
int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
CHANNEL function read callback.
const char * args
static int read_pjsip(void *data)
static int channel_read_rtp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
struct pjsip_inv_session * inv_session
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
Definition: stream.c:365
int ast_sip_dtmf_to_str(const enum ast_sip_dtmf_mode dtmf, char *buf, size_t buf_len)
Convert the DTMF mode enum value into a string.
Definition: res_pjsip.c:5484
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
Socket address structure.
Definition: netsock2.h:97
A structure describing a SIP session.
Media Stream API.
Media Format API.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sip_session_media_state * active_media_state
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
enum ast_sip_session_refresh_method method
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_dsp * dsp
static int parse_uri_cb(void *data)
static struct session_refresh_state * session_refresh_state_get_or_alloc(struct ast_sip_session *session)
Helper function which retrieves or allocates a session refresh state information datastore.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1764
struct ast_stream * ast_stream_topology_get_first_stream_by_type(const struct ast_stream_topology *topology, enum ast_media_type type)
Gets the first active stream of a specific type from the topology.
Definition: stream.c:964
General Asterisk PBX channel definitions.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct ast_mansession session
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Definition: res_pjsip.c:5218
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_DTMF_MODE function read callback.
Access Control of various sorts.
int ast_sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *media_state)
Send a reinvite or UPDATE on a session.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:44
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_channel * channel
const char * method
Definition: res_pjsip.c:4335
struct ast_sdp_srtp * srtp
Holds SRTP information.
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MEDIA_OFFER function write callback.
char * ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
Retrieve quality statistics about an RTP instance.
Definition: rtp_engine.c:2460
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static const struct ast_datastore_info session_refresh_datastore
Datastore for attaching session refresh state information.
Core PBX routines and definitions.
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
struct ast_taskprocessor * serializer
unsigned int rxcount
Definition: rtp_engine.h:370
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition: location.c:147
int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
PJSIP_PARSE_URI function read callback.
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
unsigned int local_ssrc
Definition: rtp_engine.h:422
int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_DTMF_MODE function write callback.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_sip_dtmf_mode dtmf
Contact associated with an address of record.
Definition: res_pjsip.h:281
#define T38_DISABLED
Definition: chan_ooh323.c:101
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
ast_sip_session_refresh_method
Definition: res_pjsip.h:484
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
unsigned int remotely_held
Stream is on hold by remote side.
static int channel_read_pjsip(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
long int flag
Definition: f2c.h:83
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
static const char name[]
Definition: cdr_mysql.c:74
unsigned int txploss
Definition: rtp_engine.h:392
#define ast_free(a)
Definition: astmm.h:182
static const char * t38state_to_string[T38_MAX_ENUM]
String representations of the T.38 state enum.
PJSIP Channel Driver shared data structures.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
struct ast_sip_session * session
static int dtmf_mode_refresh_cb(void *obj)
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
A structure containing SIP session media information.
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
static int refresh_write_cb(void *obj)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3718
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:139
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
const ast_string_field aor
Definition: res_pjsip.h:303
ast_rtp_instance_stat_field
Definition: rtp_engine.h:168
char * strsep(char **str, const char *delims)
struct ast_stream_topology * topology
Definition: res_pjsip.h:772
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_stream_topology * topology
The media stream topology.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition: stream.c:460
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2137
struct ast_sip_session * session
struct ast_sip_session * session
struct ao2_container * ast_sip_location_retrieve_aor_contacts_filtered(const struct ast_sip_aor *aor, unsigned int flags)
Retrieve all contacts currently available for an AOR and filter based on flags.
Definition: location.c:252
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
ast_media_type
Types of media.
Definition: codec.h:30
Struct used to push function arguments to task processor.
Return only reachable or unknown contacts.
Definition: res_pjsip.h:1009
static int media_offer_read_av(struct ast_sip_session *session, char *buf, size_t len, enum ast_media_type media_type)
Generic container type.
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
int ast_sip_session_regenerate_answer(struct ast_sip_session *session, ast_sip_session_sdp_creation_cb on_sdp_creation)
Regenerate SDP Answer.
static void session_refresh_state_destroy(void *obj)
Destructor for session refresh information.
int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_DIAL_CONTACTS function read callback.
const ast_string_field uri
Definition: res_pjsip.h:303
struct ast_sip_contact * contact
Asterisk module definitions.
struct ast_sip_aor * aor
int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_SEND_SESSION_REFRESH function write callback.
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1192
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
int pjsip_acf_moh_passthrough_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_MOH_PASSTHROUGH function read callback.
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
unsigned int moh_passthrough
unsigned int remote_ssrc
Definition: rtp_engine.h:424
#define AST_APP_ARG(name)
Define an application argument.