dialplan_functions.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  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. * \file
  18. *
  19. * \author \verbatim Joshua Colp <jcolp@digium.com> \endverbatim
  20. * \author \verbatim Matt Jordan <mjordan@digium.com> \endverbatim
  21. *
  22. * \ingroup functions
  23. *
  24. * \brief PJSIP channel dialplan functions
  25. */
  26. /*** MODULEINFO
  27. <support_level>core</support_level>
  28. ***/
  29. /*** DOCUMENTATION
  30. <function name="PJSIP_DIAL_CONTACTS" language="en_US">
  31. <synopsis>
  32. Return a dial string for dialing all contacts on an AOR.
  33. </synopsis>
  34. <syntax>
  35. <parameter name="endpoint" required="true">
  36. <para>Name of the endpoint</para>
  37. </parameter>
  38. <parameter name="aor" required="false">
  39. <para>Name of an AOR to use, if not specified the configured AORs on the endpoint are used</para>
  40. </parameter>
  41. <parameter name="request_user" required="false">
  42. <para>Optional request user to use in the request URI</para>
  43. </parameter>
  44. </syntax>
  45. <description>
  46. <para>Returns a properly formatted dial string for dialing all contacts on an AOR.</para>
  47. </description>
  48. </function>
  49. <function name="PJSIP_MEDIA_OFFER" language="en_US">
  50. <synopsis>
  51. Media and codec offerings to be set on an outbound SIP channel prior to dialing.
  52. </synopsis>
  53. <syntax>
  54. <parameter name="media" required="true">
  55. <para>types of media offered</para>
  56. </parameter>
  57. </syntax>
  58. <description>
  59. <para>When read, returns the codecs offered based upon the media choice.</para>
  60. <para>When written, sets the codecs to offer when an outbound dial attempt is made,
  61. or when a session refresh is sent using <replaceable>PJSIP_SEND_SESSION_REFRESH</replaceable>.
  62. </para>
  63. </description>
  64. <see-also>
  65. <ref type="function">PJSIP_SEND_SESSION_REFRESH</ref>
  66. </see-also>
  67. </function>
  68. <function name="PJSIP_DTMF_MODE" language="en_US">
  69. <synopsis>
  70. Get or change the DTMF mode for a SIP call.
  71. </synopsis>
  72. <syntax>
  73. </syntax>
  74. <description>
  75. <para>When read, returns the current DTMF mode</para>
  76. <para>When written, sets the current DTMF mode</para>
  77. <para>This function uses the same DTMF mode naming as the dtmf_mode configuration option</para>
  78. </description>
  79. </function>
  80. <function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
  81. <synopsis>
  82. W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session
  83. </synopsis>
  84. <syntax>
  85. <parameter name="update_type" required="false">
  86. <para>The type of update to send. Default is <literal>invite</literal>.</para>
  87. <enumlist>
  88. <enum name="invite">
  89. <para>Send the session refresh as a re-INVITE.</para>
  90. </enum>
  91. <enum name="update">
  92. <para>Send the session refresh as an UPDATE.</para>
  93. </enum>
  94. </enumlist>
  95. </parameter>
  96. </syntax>
  97. <description>
  98. <para>This function will cause the PJSIP stack to immediately refresh
  99. the media session for the channel. This will be done using either a
  100. re-INVITE (default) or an UPDATE request.
  101. </para>
  102. <para>This is most useful when combined with the <replaceable>PJSIP_MEDIA_OFFER</replaceable>
  103. dialplan function, as it allows the formats in use on a channel to be
  104. re-negotiated after call setup.</para>
  105. <warning>
  106. <para>The formats the endpoint supports are <emphasis>not</emphasis>
  107. checked or enforced by this function. Using this function to offer
  108. formats not supported by the endpoint <emphasis>may</emphasis> result
  109. in a loss of media.</para>
  110. </warning>
  111. <example title="Re-negotiate format to g722">
  112. ; Within some existing extension on an answered channel
  113. same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,g722)
  114. same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite)
  115. </example>
  116. </description>
  117. <see-also>
  118. <ref type="function">PJSIP_MEDIA_OFFER</ref>
  119. </see-also>
  120. </function>
  121. <function name="PJSIP_PARSE_URI" language="en_US">
  122. <synopsis>
  123. Parse an uri and return a type part of the URI.
  124. </synopsis>
  125. <syntax>
  126. <parameter name="uri" required="true">
  127. <para>URI to parse</para>
  128. </parameter>
  129. <parameter name="type" required="true">
  130. <para>The <literal>type</literal> parameter specifies which URI part to read</para>
  131. <enumlist>
  132. <enum name="display">
  133. <para>Display name.</para>
  134. </enum>
  135. <enum name="scheme">
  136. <para>URI scheme.</para>
  137. </enum>
  138. <enum name="user">
  139. <para>User part.</para>
  140. </enum>
  141. <enum name="passwd">
  142. <para>Password part.</para>
  143. </enum>
  144. <enum name="host">
  145. <para>Host part.</para>
  146. </enum>
  147. <enum name="port">
  148. <para>Port number, or zero.</para>
  149. </enum>
  150. <enum name="user_param">
  151. <para>User parameter.</para>
  152. </enum>
  153. <enum name="method_param">
  154. <para>Method parameter.</para>
  155. </enum>
  156. <enum name="transport_param">
  157. <para>Transport parameter.</para>
  158. </enum>
  159. <enum name="ttl_param">
  160. <para>TTL param, or -1.</para>
  161. </enum>
  162. <enum name="lr_param">
  163. <para>Loose routing param, or zero.</para>
  164. </enum>
  165. <enum name="maddr_param">
  166. <para>Maddr param.</para>
  167. </enum>
  168. </enumlist>
  169. </parameter>
  170. </syntax>
  171. <description>
  172. <para>Parse an URI and return a specified part of the URI.</para>
  173. </description>
  174. </function>
  175. <info name="CHANNEL" language="en_US" tech="PJSIP">
  176. <enumlist>
  177. <enum name="rtp">
  178. <para>R/O Retrieve media related information.</para>
  179. <parameter name="type" required="true">
  180. <para>When <replaceable>rtp</replaceable> is specified, the
  181. <literal>type</literal> parameter must be provided. It specifies
  182. which RTP parameter to read.</para>
  183. <enumlist>
  184. <enum name="src">
  185. <para>Retrieve the local address for RTP.</para>
  186. </enum>
  187. <enum name="dest">
  188. <para>Retrieve the remote address for RTP.</para>
  189. </enum>
  190. <enum name="direct">
  191. <para>If direct media is enabled, this address is the remote address
  192. used for RTP.</para>
  193. </enum>
  194. <enum name="secure">
  195. <para>Whether or not the media stream is encrypted.</para>
  196. <enumlist>
  197. <enum name="0">
  198. <para>The media stream is not encrypted.</para>
  199. </enum>
  200. <enum name="1">
  201. <para>The media stream is encrypted.</para>
  202. </enum>
  203. </enumlist>
  204. </enum>
  205. <enum name="hold">
  206. <para>Whether or not the media stream is currently restricted
  207. due to a call hold.</para>
  208. <enumlist>
  209. <enum name="0">
  210. <para>The media stream is not held.</para>
  211. </enum>
  212. <enum name="1">
  213. <para>The media stream is held.</para>
  214. </enum>
  215. </enumlist>
  216. </enum>
  217. </enumlist>
  218. </parameter>
  219. <parameter name="media_type" required="false">
  220. <para>When <replaceable>rtp</replaceable> is specified, the
  221. <literal>media_type</literal> parameter may be provided. It specifies
  222. which media stream the chosen RTP parameter should be retrieved
  223. from.</para>
  224. <enumlist>
  225. <enum name="audio">
  226. <para>Retrieve information from the audio media stream.</para>
  227. <note><para>If not specified, <literal>audio</literal> is used
  228. by default.</para></note>
  229. </enum>
  230. <enum name="video">
  231. <para>Retrieve information from the video media stream.</para>
  232. </enum>
  233. </enumlist>
  234. </parameter>
  235. </enum>
  236. <enum name="rtcp">
  237. <para>R/O Retrieve RTCP statistics.</para>
  238. <parameter name="statistic" required="true">
  239. <para>When <replaceable>rtcp</replaceable> is specified, the
  240. <literal>statistic</literal> parameter must be provided. It specifies
  241. which RTCP statistic parameter to read.</para>
  242. <enumlist>
  243. <enum name="all">
  244. <para>Retrieve a summary of all RTCP statistics.</para>
  245. <para>The following data items are returned in a semi-colon
  246. delineated list:</para>
  247. <enumlist>
  248. <enum name="ssrc">
  249. <para>Our Synchronization Source identifier</para>
  250. </enum>
  251. <enum name="themssrc">
  252. <para>Their Synchronization Source identifier</para>
  253. </enum>
  254. <enum name="lp">
  255. <para>Our lost packet count</para>
  256. </enum>
  257. <enum name="rxjitter">
  258. <para>Received packet jitter</para>
  259. </enum>
  260. <enum name="rxcount">
  261. <para>Received packet count</para>
  262. </enum>
  263. <enum name="txjitter">
  264. <para>Transmitted packet jitter</para>
  265. </enum>
  266. <enum name="txcount">
  267. <para>Transmitted packet count</para>
  268. </enum>
  269. <enum name="rlp">
  270. <para>Remote lost packet count</para>
  271. </enum>
  272. <enum name="rtt">
  273. <para>Round trip time</para>
  274. </enum>
  275. </enumlist>
  276. </enum>
  277. <enum name="all_jitter">
  278. <para>Retrieve a summary of all RTCP Jitter statistics.</para>
  279. <para>The following data items are returned in a semi-colon
  280. delineated list:</para>
  281. <enumlist>
  282. <enum name="minrxjitter">
  283. <para>Our minimum jitter</para>
  284. </enum>
  285. <enum name="maxrxjitter">
  286. <para>Our max jitter</para>
  287. </enum>
  288. <enum name="avgrxjitter">
  289. <para>Our average jitter</para>
  290. </enum>
  291. <enum name="stdevrxjitter">
  292. <para>Our jitter standard deviation</para>
  293. </enum>
  294. <enum name="reported_minjitter">
  295. <para>Their minimum jitter</para>
  296. </enum>
  297. <enum name="reported_maxjitter">
  298. <para>Their max jitter</para>
  299. </enum>
  300. <enum name="reported_avgjitter">
  301. <para>Their average jitter</para>
  302. </enum>
  303. <enum name="reported_stdevjitter">
  304. <para>Their jitter standard deviation</para>
  305. </enum>
  306. </enumlist>
  307. </enum>
  308. <enum name="all_loss">
  309. <para>Retrieve a summary of all RTCP packet loss statistics.</para>
  310. <para>The following data items are returned in a semi-colon
  311. delineated list:</para>
  312. <enumlist>
  313. <enum name="minrxlost">
  314. <para>Our minimum lost packets</para>
  315. </enum>
  316. <enum name="maxrxlost">
  317. <para>Our max lost packets</para>
  318. </enum>
  319. <enum name="avgrxlost">
  320. <para>Our average lost packets</para>
  321. </enum>
  322. <enum name="stdevrxlost">
  323. <para>Our lost packets standard deviation</para>
  324. </enum>
  325. <enum name="reported_minlost">
  326. <para>Their minimum lost packets</para>
  327. </enum>
  328. <enum name="reported_maxlost">
  329. <para>Their max lost packets</para>
  330. </enum>
  331. <enum name="reported_avglost">
  332. <para>Their average lost packets</para>
  333. </enum>
  334. <enum name="reported_stdevlost">
  335. <para>Their lost packets standard deviation</para>
  336. </enum>
  337. </enumlist>
  338. </enum>
  339. <enum name="all_rtt">
  340. <para>Retrieve a summary of all RTCP round trip time information.</para>
  341. <para>The following data items are returned in a semi-colon
  342. delineated list:</para>
  343. <enumlist>
  344. <enum name="minrtt">
  345. <para>Minimum round trip time</para>
  346. </enum>
  347. <enum name="maxrtt">
  348. <para>Maximum round trip time</para>
  349. </enum>
  350. <enum name="avgrtt">
  351. <para>Average round trip time</para>
  352. </enum>
  353. <enum name="stdevrtt">
  354. <para>Standard deviation round trip time</para>
  355. </enum>
  356. </enumlist>
  357. </enum>
  358. <enum name="txcount"><para>Transmitted packet count</para></enum>
  359. <enum name="rxcount"><para>Received packet count</para></enum>
  360. <enum name="txjitter"><para>Transmitted packet jitter</para></enum>
  361. <enum name="rxjitter"><para>Received packet jitter</para></enum>
  362. <enum name="remote_maxjitter"><para>Their max jitter</para></enum>
  363. <enum name="remote_minjitter"><para>Their minimum jitter</para></enum>
  364. <enum name="remote_normdevjitter"><para>Their average jitter</para></enum>
  365. <enum name="remote_stdevjitter"><para>Their jitter standard deviation</para></enum>
  366. <enum name="local_maxjitter"><para>Our max jitter</para></enum>
  367. <enum name="local_minjitter"><para>Our minimum jitter</para></enum>
  368. <enum name="local_normdevjitter"><para>Our average jitter</para></enum>
  369. <enum name="local_stdevjitter"><para>Our jitter standard deviation</para></enum>
  370. <enum name="txploss"><para>Transmitted packet loss</para></enum>
  371. <enum name="rxploss"><para>Received packet loss</para></enum>
  372. <enum name="remote_maxrxploss"><para>Their max lost packets</para></enum>
  373. <enum name="remote_minrxploss"><para>Their minimum lost packets</para></enum>
  374. <enum name="remote_normdevrxploss"><para>Their average lost packets</para></enum>
  375. <enum name="remote_stdevrxploss"><para>Their lost packets standard deviation</para></enum>
  376. <enum name="local_maxrxploss"><para>Our max lost packets</para></enum>
  377. <enum name="local_minrxploss"><para>Our minimum lost packets</para></enum>
  378. <enum name="local_normdevrxploss"><para>Our average lost packets</para></enum>
  379. <enum name="local_stdevrxploss"><para>Our lost packets standard deviation</para></enum>
  380. <enum name="rtt"><para>Round trip time</para></enum>
  381. <enum name="maxrtt"><para>Maximum round trip time</para></enum>
  382. <enum name="minrtt"><para>Minimum round trip time</para></enum>
  383. <enum name="normdevrtt"><para>Average round trip time</para></enum>
  384. <enum name="stdevrtt"><para>Standard deviation round trip time</para></enum>
  385. <enum name="local_ssrc"><para>Our Synchronization Source identifier</para></enum>
  386. <enum name="remote_ssrc"><para>Their Synchronization Source identifier</para></enum>
  387. </enumlist>
  388. </parameter>
  389. <parameter name="media_type" required="false">
  390. <para>When <replaceable>rtcp</replaceable> is specified, the
  391. <literal>media_type</literal> parameter may be provided. It specifies
  392. which media stream the chosen RTCP parameter should be retrieved
  393. from.</para>
  394. <enumlist>
  395. <enum name="audio">
  396. <para>Retrieve information from the audio media stream.</para>
  397. <note><para>If not specified, <literal>audio</literal> is used
  398. by default.</para></note>
  399. </enum>
  400. <enum name="video">
  401. <para>Retrieve information from the video media stream.</para>
  402. </enum>
  403. </enumlist>
  404. </parameter>
  405. </enum>
  406. <enum name="endpoint">
  407. <para>R/O The name of the endpoint associated with this channel.
  408. Use the <replaceable>PJSIP_ENDPOINT</replaceable> function to obtain
  409. further endpoint related information.</para>
  410. </enum>
  411. <enum name="contact">
  412. <para>R/O The name of the contact associated with this channel.
  413. Use the <replaceable>PJSIP_CONTACT</replaceable> function to obtain
  414. further contact related information. Note this may not be present and if so
  415. is only available on outgoing legs.</para>
  416. </enum>
  417. <enum name="aor">
  418. <para>R/O The name of the AOR associated with this channel.
  419. Use the <replaceable>PJSIP_AOR</replaceable> function to obtain
  420. further AOR related information. Note this may not be present and if so
  421. is only available on outgoing legs.</para>
  422. </enum>
  423. <enum name="pjsip">
  424. <para>R/O Obtain information about the current PJSIP channel and its
  425. session.</para>
  426. <parameter name="type" required="true">
  427. <para>When <replaceable>pjsip</replaceable> is specified, the
  428. <literal>type</literal> parameter must be provided. It specifies
  429. which signalling parameter to read.</para>
  430. <enumlist>
  431. <enum name="call-id">
  432. <para>The SIP call-id.</para>
  433. </enum>
  434. <enum name="secure">
  435. <para>Whether or not the signalling uses a secure transport.</para>
  436. <enumlist>
  437. <enum name="0"><para>The signalling uses a non-secure transport.</para></enum>
  438. <enum name="1"><para>The signalling uses a secure transport.</para></enum>
  439. </enumlist>
  440. </enum>
  441. <enum name="target_uri">
  442. <para>The contact URI where requests are sent.</para>
  443. </enum>
  444. <enum name="local_uri">
  445. <para>The local URI.</para>
  446. </enum>
  447. <enum name="local_tag">
  448. <para>Tag in From header</para>
  449. </enum>
  450. <enum name="remote_uri">
  451. <para>The remote URI.</para>
  452. </enum>
  453. <enum name="remote_tag">
  454. <para>Tag in To header</para>
  455. </enum>
  456. <enum name="request_uri">
  457. <para>The request URI of the incoming <literal>INVITE</literal>
  458. associated with the creation of this channel.</para>
  459. </enum>
  460. <enum name="t38state">
  461. <para>The current state of any T.38 fax on this channel.</para>
  462. <enumlist>
  463. <enum name="DISABLED"><para>T.38 faxing is disabled on this channel.</para></enum>
  464. <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>
  465. <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>
  466. <enum name="ENABLED"><para>A T.38 fax session has been enabled.</para></enum>
  467. <enum name="REJECTED"><para>A T.38 fax session was attempted but was rejected.</para></enum>
  468. </enumlist>
  469. </enum>
  470. <enum name="local_addr">
  471. <para>On inbound calls, the full IP address and port number that
  472. the <literal>INVITE</literal> request was received on. On outbound
  473. calls, the full IP address and port number that the <literal>INVITE</literal>
  474. request was transmitted from.</para>
  475. </enum>
  476. <enum name="remote_addr">
  477. <para>On inbound calls, the full IP address and port number that
  478. the <literal>INVITE</literal> request was received from. On outbound
  479. calls, the full IP address and port number that the <literal>INVITE</literal>
  480. request was transmitted to.</para>
  481. </enum>
  482. </enumlist>
  483. </parameter>
  484. </enum>
  485. </enumlist>
  486. </info>
  487. <info name="CHANNEL_EXAMPLES" language="en_US" tech="PJSIP">
  488. <example title="PJSIP specific CHANNEL examples">
  489. ; Log the current Call-ID
  490. same => n,Log(NOTICE, ${CHANNEL(pjsip,call-id)})
  491. ; Log the destination address of the audio stream
  492. same => n,Log(NOTICE, ${CHANNEL(rtp,dest)})
  493. ; Store the round-trip time associated with a
  494. ; video stream in the CDR field video-rtt
  495. same => n,Set(CDR(video-rtt)=${CHANNEL(rtcp,rtt,video)})
  496. </example>
  497. </info>
  498. ***/
  499. #include "asterisk.h"
  500. #include <pjsip.h>
  501. #include <pjlib.h>
  502. #include <pjsip_ua.h>
  503. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  504. #include "asterisk/astobj2.h"
  505. #include "asterisk/module.h"
  506. #include "asterisk/acl.h"
  507. #include "asterisk/app.h"
  508. #include "asterisk/channel.h"
  509. #include "asterisk/format.h"
  510. #include "asterisk/dsp.h"
  511. #include "asterisk/pbx.h"
  512. #include "asterisk/res_pjsip.h"
  513. #include "asterisk/res_pjsip_session.h"
  514. #include "include/chan_pjsip.h"
  515. #include "include/dialplan_functions.h"
  516. /*!
  517. * \brief String representations of the T.38 state enum
  518. */
  519. static const char *t38state_to_string[T38_MAX_ENUM] = {
  520. [T38_DISABLED] = "DISABLED",
  521. [T38_LOCAL_REINVITE] = "LOCAL_REINVITE",
  522. [T38_PEER_REINVITE] = "REMOTE_REINVITE",
  523. [T38_ENABLED] = "ENABLED",
  524. [T38_REJECTED] = "REJECTED",
  525. };
  526. /*!
  527. * \internal \brief Handle reading RTP information
  528. */
  529. static int channel_read_rtp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
  530. {
  531. struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
  532. struct chan_pjsip_pvt *pvt;
  533. struct ast_sip_session_media *media = NULL;
  534. struct ast_sockaddr addr;
  535. if (!channel) {
  536. ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
  537. return -1;
  538. }
  539. pvt = channel->pvt;
  540. if (!pvt) {
  541. ast_log(AST_LOG_WARNING, "Channel %s has no chan_pjsip pvt!\n", ast_channel_name(chan));
  542. return -1;
  543. }
  544. if (ast_strlen_zero(type)) {
  545. ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtp' information\n");
  546. return -1;
  547. }
  548. if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
  549. media = pvt->media[SIP_MEDIA_AUDIO];
  550. } else if (!strcmp(field, "video")) {
  551. media = pvt->media[SIP_MEDIA_VIDEO];
  552. } else {
  553. ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtp' information\n", field);
  554. return -1;
  555. }
  556. if (!media || !media->rtp) {
  557. ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
  558. ast_channel_name(chan), S_OR(field, "audio"));
  559. return -1;
  560. }
  561. if (!strcmp(type, "src")) {
  562. ast_rtp_instance_get_local_address(media->rtp, &addr);
  563. ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
  564. } else if (!strcmp(type, "dest")) {
  565. ast_rtp_instance_get_remote_address(media->rtp, &addr);
  566. ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
  567. } else if (!strcmp(type, "direct")) {
  568. ast_copy_string(buf, ast_sockaddr_stringify(&media->direct_media_addr), buflen);
  569. } else if (!strcmp(type, "secure")) {
  570. if (media->srtp) {
  571. struct ast_sdp_srtp *srtp = media->srtp;
  572. int flag = ast_test_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
  573. snprintf(buf, buflen, "%d", flag ? 1 : 0);
  574. } else {
  575. snprintf(buf, buflen, "%d", 0);
  576. }
  577. } else if (!strcmp(type, "hold")) {
  578. snprintf(buf, buflen, "%d", media->held ? 1 : 0);
  579. } else {
  580. ast_log(AST_LOG_WARNING, "Unknown type field '%s' specified for 'rtp' information\n", type);
  581. return -1;
  582. }
  583. return 0;
  584. }
  585. /*!
  586. * \internal \brief Handle reading RTCP information
  587. */
  588. static int channel_read_rtcp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
  589. {
  590. struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
  591. struct chan_pjsip_pvt *pvt;
  592. struct ast_sip_session_media *media = NULL;
  593. if (!channel) {
  594. ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
  595. return -1;
  596. }
  597. pvt = channel->pvt;
  598. if (!pvt) {
  599. ast_log(AST_LOG_WARNING, "Channel %s has no chan_pjsip pvt!\n", ast_channel_name(chan));
  600. return -1;
  601. }
  602. if (ast_strlen_zero(type)) {
  603. ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtcp' information\n");
  604. return -1;
  605. }
  606. if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
  607. media = pvt->media[SIP_MEDIA_AUDIO];
  608. } else if (!strcmp(field, "video")) {
  609. media = pvt->media[SIP_MEDIA_VIDEO];
  610. } else {
  611. ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtcp' information\n", field);
  612. return -1;
  613. }
  614. if (!media || !media->rtp) {
  615. ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
  616. ast_channel_name(chan), S_OR(field, "audio"));
  617. return -1;
  618. }
  619. if (!strncasecmp(type, "all", 3)) {
  620. enum ast_rtp_instance_stat_field stat_field = AST_RTP_INSTANCE_STAT_FIELD_QUALITY;
  621. if (!strcasecmp(type, "all_jitter")) {
  622. stat_field = AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER;
  623. } else if (!strcasecmp(type, "all_rtt")) {
  624. stat_field = AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT;
  625. } else if (!strcasecmp(type, "all_loss")) {
  626. stat_field = AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS;
  627. }
  628. if (!ast_rtp_instance_get_quality(media->rtp, stat_field, buf, buflen)) {
  629. ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
  630. return -1;
  631. }
  632. } else {
  633. struct ast_rtp_instance_stats stats;
  634. int i;
  635. struct {
  636. const char *name;
  637. enum { INT, DBL } type;
  638. union {
  639. unsigned int *i4;
  640. double *d8;
  641. };
  642. } lookup[] = {
  643. { "txcount", INT, { .i4 = &stats.txcount, }, },
  644. { "rxcount", INT, { .i4 = &stats.rxcount, }, },
  645. { "txjitter", DBL, { .d8 = &stats.txjitter, }, },
  646. { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, },
  647. { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, },
  648. { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, },
  649. { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, },
  650. { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, },
  651. { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, },
  652. { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, },
  653. { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, },
  654. { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, },
  655. { "txploss", INT, { .i4 = &stats.txploss, }, },
  656. { "rxploss", INT, { .i4 = &stats.rxploss, }, },
  657. { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, },
  658. { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, },
  659. { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, },
  660. { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, },
  661. { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, },
  662. { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, },
  663. { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, },
  664. { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, },
  665. { "rtt", DBL, { .d8 = &stats.rtt, }, },
  666. { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, },
  667. { "minrtt", DBL, { .d8 = &stats.minrtt, }, },
  668. { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, },
  669. { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, },
  670. { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, },
  671. { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, },
  672. { NULL, },
  673. };
  674. if (ast_rtp_instance_get_stats(media->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) {
  675. ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
  676. return -1;
  677. }
  678. for (i = 0; !ast_strlen_zero(lookup[i].name); i++) {
  679. if (!strcasecmp(type, lookup[i].name)) {
  680. if (lookup[i].type == INT) {
  681. snprintf(buf, buflen, "%u", *lookup[i].i4);
  682. } else {
  683. snprintf(buf, buflen, "%f", *lookup[i].d8);
  684. }
  685. return 0;
  686. }
  687. }
  688. ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'rtcp' information\n", type);
  689. return -1;
  690. }
  691. return 0;
  692. }
  693. static int print_escaped_uri(struct ast_channel *chan, const char *type,
  694. pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
  695. {
  696. int res;
  697. char *buf_copy;
  698. res = pjsip_uri_print(context, uri, buf, size);
  699. if (res < 0) {
  700. ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n",
  701. ast_channel_name(chan), type, (int) size);
  702. /* Empty buffer that likely is not terminated. */
  703. buf[0] = '\0';
  704. return -1;
  705. }
  706. buf_copy = ast_strdupa(buf);
  707. ast_escape_quoted(buf_copy, buf, size);
  708. return 0;
  709. }
  710. /*!
  711. * \internal \brief Handle reading signalling information
  712. */
  713. static int channel_read_pjsip(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
  714. {
  715. struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
  716. char *buf_copy;
  717. pjsip_dialog *dlg;
  718. int res = 0;
  719. if (!channel) {
  720. ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
  721. return -1;
  722. }
  723. dlg = channel->session->inv_session->dlg;
  724. if (ast_strlen_zero(type)) {
  725. ast_log(LOG_WARNING, "You must supply a type field for 'pjsip' information\n");
  726. return -1;
  727. } else if (!strcmp(type, "call-id")) {
  728. snprintf(buf, buflen, "%.*s", (int) pj_strlen(&dlg->call_id->id), pj_strbuf(&dlg->call_id->id));
  729. } else if (!strcmp(type, "secure")) {
  730. #ifdef HAVE_PJSIP_GET_DEST_INFO
  731. pjsip_host_info dest;
  732. pj_pool_t *pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "secure-check", 128, 128);
  733. pjsip_get_dest_info(dlg->target, NULL, pool, &dest);
  734. snprintf(buf, buflen, "%d", dest.flag & PJSIP_TRANSPORT_SECURE ? 1 : 0);
  735. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  736. #else
  737. 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");
  738. return -1;
  739. #endif
  740. } else if (!strcmp(type, "target_uri")) {
  741. res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf,
  742. buflen);
  743. } else if (!strcmp(type, "local_uri")) {
  744. res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri,
  745. buf, buflen);
  746. } else if (!strcmp(type, "local_tag")) {
  747. ast_copy_pj_str(buf, &dlg->local.info->tag, buflen);
  748. buf_copy = ast_strdupa(buf);
  749. ast_escape_quoted(buf_copy, buf, buflen);
  750. } else if (!strcmp(type, "remote_uri")) {
  751. res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR,
  752. dlg->remote.info->uri, buf, buflen);
  753. } else if (!strcmp(type, "remote_tag")) {
  754. ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen);
  755. buf_copy = ast_strdupa(buf);
  756. ast_escape_quoted(buf_copy, buf, buflen);
  757. } else if (!strcmp(type, "request_uri")) {
  758. if (channel->session->request_uri) {
  759. res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI,
  760. channel->session->request_uri, buf, buflen);
  761. }
  762. } else if (!strcmp(type, "t38state")) {
  763. ast_copy_string(buf, t38state_to_string[channel->session->t38state], buflen);
  764. } else if (!strcmp(type, "local_addr")) {
  765. RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
  766. struct transport_info_data *transport_data;
  767. datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
  768. if (!datastore) {
  769. ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
  770. return -1;
  771. }
  772. transport_data = datastore->data;
  773. if (pj_sockaddr_has_addr(&transport_data->local_addr)) {
  774. pj_sockaddr_print(&transport_data->local_addr, buf, buflen, 3);
  775. }
  776. } else if (!strcmp(type, "remote_addr")) {
  777. RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
  778. struct transport_info_data *transport_data;
  779. datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
  780. if (!datastore) {
  781. ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
  782. return -1;
  783. }
  784. transport_data = datastore->data;
  785. if (pj_sockaddr_has_addr(&transport_data->remote_addr)) {
  786. pj_sockaddr_print(&transport_data->remote_addr, buf, buflen, 3);
  787. }
  788. } else {
  789. ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'pjsip' information\n", type);
  790. return -1;
  791. }
  792. return res;
  793. }
  794. /*! \brief Struct used to push function arguments to task processor */
  795. struct pjsip_func_args {
  796. struct ast_sip_session *session;
  797. const char *param;
  798. const char *type;
  799. const char *field;
  800. char *buf;
  801. size_t len;
  802. int ret;
  803. };
  804. /*! \internal \brief Taskprocessor callback that handles the read on a PJSIP thread */
  805. static int read_pjsip(void *data)
  806. {
  807. struct pjsip_func_args *func_args = data;
  808. if (!strcmp(func_args->param, "rtp")) {
  809. if (!func_args->session->channel) {
  810. func_args->ret = -1;
  811. return 0;
  812. }
  813. func_args->ret = channel_read_rtp(func_args->session->channel, func_args->type,
  814. func_args->field, func_args->buf,
  815. func_args->len);
  816. } else if (!strcmp(func_args->param, "rtcp")) {
  817. if (!func_args->session->channel) {
  818. func_args->ret = -1;
  819. return 0;
  820. }
  821. func_args->ret = channel_read_rtcp(func_args->session->channel, func_args->type,
  822. func_args->field, func_args->buf,
  823. func_args->len);
  824. } else if (!strcmp(func_args->param, "endpoint")) {
  825. if (!func_args->session->endpoint) {
  826. ast_log(AST_LOG_WARNING, "Channel %s has no endpoint!\n", func_args->session->channel ?
  827. ast_channel_name(func_args->session->channel) : "<unknown>");
  828. func_args->ret = -1;
  829. return 0;
  830. }
  831. snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->endpoint));
  832. } else if (!strcmp(func_args->param, "contact")) {
  833. if (!func_args->session->contact) {
  834. return 0;
  835. }
  836. snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->contact));
  837. } else if (!strcmp(func_args->param, "aor")) {
  838. if (!func_args->session->aor) {
  839. return 0;
  840. }
  841. snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->aor));
  842. } else if (!strcmp(func_args->param, "pjsip")) {
  843. if (!func_args->session->channel) {
  844. func_args->ret = -1;
  845. return 0;
  846. }
  847. func_args->ret = channel_read_pjsip(func_args->session->channel, func_args->type,
  848. func_args->field, func_args->buf,
  849. func_args->len);
  850. } else {
  851. func_args->ret = -1;
  852. }
  853. return 0;
  854. }
  855. int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
  856. {
  857. struct pjsip_func_args func_args = { 0, };
  858. struct ast_sip_channel_pvt *channel;
  859. char *parse = ast_strdupa(data);
  860. AST_DECLARE_APP_ARGS(args,
  861. AST_APP_ARG(param);
  862. AST_APP_ARG(type);
  863. AST_APP_ARG(field);
  864. );
  865. if (!chan) {
  866. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  867. return -1;
  868. }
  869. /* Check for zero arguments */
  870. if (ast_strlen_zero(parse)) {
  871. ast_log(LOG_ERROR, "Cannot call %s without arguments\n", cmd);
  872. return -1;
  873. }
  874. AST_STANDARD_APP_ARGS(args, parse);
  875. ast_channel_lock(chan);
  876. /* Sanity check */
  877. if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
  878. ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
  879. ast_channel_unlock(chan);
  880. return 0;
  881. }
  882. channel = ast_channel_tech_pvt(chan);
  883. if (!channel) {
  884. ast_log(LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
  885. ast_channel_unlock(chan);
  886. return -1;
  887. }
  888. if (!channel->session) {
  889. ast_log(LOG_WARNING, "Channel %s has no session\n", ast_channel_name(chan));
  890. ast_channel_unlock(chan);
  891. return -1;
  892. }
  893. func_args.session = ao2_bump(channel->session);
  894. ast_channel_unlock(chan);
  895. memset(buf, 0, len);
  896. func_args.param = args.param;
  897. func_args.type = args.type;
  898. func_args.field = args.field;
  899. func_args.buf = buf;
  900. func_args.len = len;
  901. if (ast_sip_push_task_wait_serializer(func_args.session->serializer, read_pjsip, &func_args)) {
  902. ast_log(LOG_WARNING, "Unable to read properties of channel %s: failed to push task\n", ast_channel_name(chan));
  903. ao2_ref(func_args.session, -1);
  904. return -1;
  905. }
  906. ao2_ref(func_args.session, -1);
  907. return func_args.ret;
  908. }
  909. int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
  910. {
  911. RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
  912. RAII_VAR(struct ast_str *, dial, NULL, ast_free_ptr);
  913. const char *aor_name;
  914. char *rest;
  915. AST_DECLARE_APP_ARGS(args,
  916. AST_APP_ARG(endpoint_name);
  917. AST_APP_ARG(aor_name);
  918. AST_APP_ARG(request_user);
  919. );
  920. AST_STANDARD_APP_ARGS(args, data);
  921. if (ast_strlen_zero(args.endpoint_name)) {
  922. ast_log(LOG_WARNING, "An endpoint name must be specified when using the '%s' dialplan function\n", cmd);
  923. return -1;
  924. } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", args.endpoint_name))) {
  925. ast_log(LOG_WARNING, "Specified endpoint '%s' was not found\n", args.endpoint_name);
  926. return -1;
  927. }
  928. aor_name = S_OR(args.aor_name, endpoint->aors);
  929. if (ast_strlen_zero(aor_name)) {
  930. ast_log(LOG_WARNING, "No AOR has been provided and no AORs are configured on endpoint '%s'\n", args.endpoint_name);
  931. return -1;
  932. } else if (!(dial = ast_str_create(len))) {
  933. ast_log(LOG_WARNING, "Could not get enough buffer space for dialing contacts\n");
  934. return -1;
  935. } else if (!(rest = ast_strdupa(aor_name))) {
  936. ast_log(LOG_WARNING, "Could not duplicate provided AORs\n");
  937. return -1;
  938. }
  939. while ((aor_name = ast_strip(strsep(&rest, ",")))) {
  940. RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
  941. RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
  942. struct ao2_iterator it_contacts;
  943. struct ast_sip_contact *contact;
  944. if (!aor) {
  945. /* If the AOR provided is not found skip it, there may be more */
  946. continue;
  947. } else if (!(contacts = ast_sip_location_retrieve_aor_contacts_filtered(aor, AST_SIP_CONTACT_FILTER_REACHABLE))) {
  948. /* No contacts are available, skip it as well */
  949. continue;
  950. } else if (!ao2_container_count(contacts)) {
  951. /* We were given a container but no contacts are in it... */
  952. continue;
  953. }
  954. it_contacts = ao2_iterator_init(contacts, 0);
  955. for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
  956. ast_str_append(&dial, -1, "PJSIP/");
  957. if (!ast_strlen_zero(args.request_user)) {
  958. ast_str_append(&dial, -1, "%s@", args.request_user);
  959. }
  960. ast_str_append(&dial, -1, "%s/%s&", args.endpoint_name, contact->uri);
  961. }
  962. ao2_iterator_destroy(&it_contacts);
  963. }
  964. /* Trim the '&' at the end off */
  965. ast_str_truncate(dial, ast_str_strlen(dial) - 1);
  966. ast_copy_string(buf, ast_str_buffer(dial), len);
  967. return 0;
  968. }
  969. /*! \brief Struct used to push PJSIP_PARSE_URI function arguments to task processor */
  970. struct parse_uri_args {
  971. const char *uri;
  972. const char *type;
  973. char *buf;
  974. size_t buflen;
  975. int ret;
  976. };
  977. /*! \internal \brief Taskprocessor callback that handles the PJSIP_PARSE_URI on a PJSIP thread */
  978. static int parse_uri_cb(void *data)
  979. {
  980. struct parse_uri_args *args = data;
  981. pj_pool_t *pool;
  982. pjsip_name_addr *uri;
  983. pjsip_sip_uri *sip_uri;
  984. pj_str_t tmp;
  985. args->ret = 0;
  986. pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "ParseUri", 128, 128);
  987. if (!pool) {
  988. ast_log(LOG_ERROR, "Failed to allocate ParseUri endpoint pool.\n");
  989. args->ret = -1;
  990. return 0;
  991. }
  992. pj_strdup2_with_null(pool, &tmp, args->uri);
  993. uri = (pjsip_name_addr *)pjsip_parse_uri(pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
  994. if (!uri) {
  995. ast_log(LOG_WARNING, "Failed to parse URI '%s'\n", args->uri);
  996. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  997. args->ret = -1;
  998. return 0;
  999. }
  1000. if (!strcmp(args->type, "scheme")) {
  1001. ast_copy_pj_str(args->buf, pjsip_uri_get_scheme(uri), args->buflen);
  1002. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  1003. return 0;
  1004. } else if (!strcmp(args->type, "display")) {
  1005. ast_copy_pj_str(args->buf, &uri->display, args->buflen);
  1006. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  1007. return 0;
  1008. }
  1009. sip_uri = pjsip_uri_get_uri(uri);
  1010. if (!sip_uri) {
  1011. ast_log(LOG_ERROR, "Failed to get an URI object for '%s'\n", args->uri);
  1012. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  1013. args->ret = -1;
  1014. return 0;
  1015. }
  1016. if (!strcmp(args->type, "user")) {
  1017. ast_copy_pj_str(args->buf, &sip_uri->user, args->buflen);
  1018. } else if (!strcmp(args->type, "passwd")) {
  1019. ast_copy_pj_str(args->buf, &sip_uri->passwd, args->buflen);
  1020. } else if (!strcmp(args->type, "host")) {
  1021. ast_copy_pj_str(args->buf, &sip_uri->host, args->buflen);
  1022. } else if (!strcmp(args->type, "port")) {
  1023. snprintf(args->buf, args->buflen, "%d", sip_uri->port);
  1024. } else if (!strcmp(args->type, "user_param")) {
  1025. ast_copy_pj_str(args->buf, &sip_uri->user_param, args->buflen);
  1026. } else if (!strcmp(args->type, "method_param")) {
  1027. ast_copy_pj_str(args->buf, &sip_uri->method_param, args->buflen);
  1028. } else if (!strcmp(args->type, "transport_param")) {
  1029. ast_copy_pj_str(args->buf, &sip_uri->transport_param, args->buflen);
  1030. } else if (!strcmp(args->type, "ttl_param")) {
  1031. snprintf(args->buf, args->buflen, "%d", sip_uri->ttl_param);
  1032. } else if (!strcmp(args->type, "lr_param")) {
  1033. snprintf(args->buf, args->buflen, "%d", sip_uri->lr_param);
  1034. } else if (!strcmp(args->type, "maddr_param")) {
  1035. ast_copy_pj_str(args->buf, &sip_uri->maddr_param, args->buflen);
  1036. } else {
  1037. ast_log(AST_LOG_WARNING, "Unknown type part '%s' specified\n", args->type);
  1038. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  1039. args->ret = -1;
  1040. return 0;
  1041. }
  1042. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
  1043. return 0;
  1044. }
  1045. int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
  1046. {
  1047. struct parse_uri_args func_args = { 0, };
  1048. AST_DECLARE_APP_ARGS(args,
  1049. AST_APP_ARG(uri_str);
  1050. AST_APP_ARG(type);
  1051. );
  1052. AST_STANDARD_APP_ARGS(args, data);
  1053. if (ast_strlen_zero(args.uri_str)) {
  1054. ast_log(LOG_WARNING, "An URI must be specified when using the '%s' dialplan function\n", cmd);
  1055. return -1;
  1056. }
  1057. if (ast_strlen_zero(args.type)) {
  1058. ast_log(LOG_WARNING, "A type part of the URI must be specified when using the '%s' dialplan function\n", cmd);
  1059. return -1;
  1060. }
  1061. memset(buf, 0, buflen);
  1062. func_args.uri = args.uri_str;
  1063. func_args.type = args.type;
  1064. func_args.buf = buf;
  1065. func_args.buflen = buflen;
  1066. if (ast_sip_push_task_wait_serializer(NULL, parse_uri_cb, &func_args)) {
  1067. ast_log(LOG_WARNING, "Unable to parse URI: failed to push task\n");
  1068. return -1;
  1069. }
  1070. return func_args.ret;
  1071. }
  1072. static int media_offer_read_av(struct ast_sip_session *session, char *buf,
  1073. size_t len, enum ast_media_type media_type)
  1074. {
  1075. int idx;
  1076. size_t accum = 0;
  1077. /* Note: buf is not terminated while the string is being built. */
  1078. for (idx = 0; idx < ast_format_cap_count(session->req_caps); ++idx) {
  1079. struct ast_format *fmt;
  1080. size_t size;
  1081. fmt = ast_format_cap_get_format(session->req_caps, idx);
  1082. if (ast_format_get_type(fmt) != media_type) {
  1083. ao2_ref(fmt, -1);
  1084. continue;
  1085. }
  1086. /* Add one for a comma or terminator */
  1087. size = strlen(ast_format_get_name(fmt)) + 1;
  1088. if (len < size) {
  1089. ao2_ref(fmt, -1);
  1090. break;
  1091. }
  1092. /* Append the format name */
  1093. strcpy(buf + accum, ast_format_get_name(fmt));/* Safe */
  1094. ao2_ref(fmt, -1);
  1095. accum += size;
  1096. len -= size;
  1097. /* The last comma on the built string will be set to the terminator. */
  1098. buf[accum - 1] = ',';
  1099. }
  1100. /* Remove the trailing comma or terminate an empty buffer. */
  1101. buf[accum ? accum - 1 : 0] = '\0';
  1102. return 0;
  1103. }
  1104. struct media_offer_data {
  1105. struct ast_sip_session *session;
  1106. enum ast_media_type media_type;
  1107. const char *value;
  1108. };
  1109. static int media_offer_write_av(void *obj)
  1110. {
  1111. struct media_offer_data *data = obj;
  1112. ast_format_cap_remove_by_type(data->session->req_caps, data->media_type);
  1113. ast_format_cap_update_by_allow_disallow(data->session->req_caps, data->value, 1);
  1114. return 0;
  1115. }
  1116. int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
  1117. {
  1118. struct ast_sip_channel_pvt *channel;
  1119. if (!chan) {
  1120. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  1121. return -1;
  1122. }
  1123. if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
  1124. ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
  1125. return -1;
  1126. }
  1127. channel = ast_channel_tech_pvt(chan);
  1128. if (!strcmp(data, "audio")) {
  1129. return media_offer_read_av(channel->session, buf, len, AST_MEDIA_TYPE_AUDIO);
  1130. } else if (!strcmp(data, "video")) {
  1131. return media_offer_read_av(channel->session, buf, len, AST_MEDIA_TYPE_VIDEO);
  1132. } else {
  1133. /* Ensure that the buffer is empty */
  1134. buf[0] = '\0';
  1135. }
  1136. return 0;
  1137. }
  1138. int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
  1139. {
  1140. struct ast_sip_channel_pvt *channel;
  1141. struct media_offer_data mdata = {
  1142. .value = value
  1143. };
  1144. if (!chan) {
  1145. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  1146. return -1;
  1147. }
  1148. if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
  1149. ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
  1150. return -1;
  1151. }
  1152. channel = ast_channel_tech_pvt(chan);
  1153. mdata.session = channel->session;
  1154. if (!strcmp(data, "audio")) {
  1155. mdata.media_type = AST_MEDIA_TYPE_AUDIO;
  1156. } else if (!strcmp(data, "video")) {
  1157. mdata.media_type = AST_MEDIA_TYPE_VIDEO;
  1158. }
  1159. return ast_sip_push_task_wait_serializer(channel->session->serializer, media_offer_write_av, &mdata);
  1160. }
  1161. int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
  1162. {
  1163. struct ast_sip_channel_pvt *channel;
  1164. if (!chan) {
  1165. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  1166. return -1;
  1167. }
  1168. ast_channel_lock(chan);
  1169. if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
  1170. ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
  1171. ast_channel_unlock(chan);
  1172. return -1;
  1173. }
  1174. channel = ast_channel_tech_pvt(chan);
  1175. if (ast_sip_dtmf_to_str(channel->session->dtmf, buf, len) < 0) {
  1176. ast_log(LOG_WARNING, "Unknown DTMF mode %d on PJSIP channel %s\n", channel->session->dtmf, ast_channel_name(chan));
  1177. ast_channel_unlock(chan);
  1178. return -1;
  1179. }
  1180. ast_channel_unlock(chan);
  1181. return 0;
  1182. }
  1183. struct refresh_data {
  1184. struct ast_sip_session *session;
  1185. enum ast_sip_session_refresh_method method;
  1186. };
  1187. static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
  1188. {
  1189. struct ast_format *fmt;
  1190. if (!session->channel) {
  1191. /* Egads! */
  1192. return 0;
  1193. }
  1194. fmt = ast_format_cap_get_best_by_type(ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_AUDIO);
  1195. if (!fmt) {
  1196. /* No format? That's weird. */
  1197. return 0;
  1198. }
  1199. ast_channel_set_writeformat(session->channel, fmt);
  1200. ast_channel_set_rawwriteformat(session->channel, fmt);
  1201. ast_channel_set_readformat(session->channel, fmt);
  1202. ast_channel_set_rawreadformat(session->channel, fmt);
  1203. ao2_ref(fmt, -1);
  1204. return 0;
  1205. }
  1206. static int dtmf_mode_refresh_cb(void *obj)
  1207. {
  1208. struct refresh_data *data = obj;
  1209. if (data->session->inv_session->state == PJSIP_INV_STATE_CONFIRMED) {
  1210. ast_debug(3, "Changing DTMF mode on channel %s after OFFER/ANSWER completion. Sending session refresh\n", ast_channel_name(data->session->channel));
  1211. ast_sip_session_refresh(data->session, NULL, NULL,
  1212. sip_session_response_cb, data->method, 1);
  1213. } else if (data->session->inv_session->state == PJSIP_INV_STATE_INCOMING) {
  1214. ast_debug(3, "Changing DTMF mode on channel %s during OFFER/ANSWER exchange. Updating SDP answer\n", ast_channel_name(data->session->channel));
  1215. ast_sip_session_regenerate_answer(data->session, NULL);
  1216. }
  1217. return 0;
  1218. }
  1219. int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
  1220. {
  1221. struct ast_sip_channel_pvt *channel;
  1222. struct chan_pjsip_pvt *pjsip_pvt;
  1223. int dsp_features = 0;
  1224. int dtmf = -1;
  1225. struct refresh_data rdata = {
  1226. .method = AST_SIP_SESSION_REFRESH_METHOD_INVITE,
  1227. };
  1228. if (!chan) {
  1229. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  1230. return -1;
  1231. }
  1232. ast_channel_lock(chan);
  1233. if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
  1234. ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
  1235. ast_channel_unlock(chan);
  1236. return -1;
  1237. }
  1238. channel = ast_channel_tech_pvt(chan);
  1239. rdata.session = channel->session;
  1240. dtmf = ast_sip_str_to_dtmf(value);
  1241. if (dtmf == -1) {
  1242. ast_log(LOG_WARNING, "Cannot set DTMF mode to '%s' on channel '%s' as value is invalid.\n", value,
  1243. ast_channel_name(chan));
  1244. ast_channel_unlock(chan);
  1245. return -1;
  1246. }
  1247. if (channel->session->dtmf == dtmf) {
  1248. /* DTMF mode unchanged, nothing to do! */
  1249. ast_channel_unlock(chan);
  1250. return 0;
  1251. }
  1252. channel->session->dtmf = dtmf;
  1253. pjsip_pvt = channel->pvt;
  1254. if (pjsip_pvt->media[SIP_MEDIA_AUDIO] && (pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp) {
  1255. if (channel->session->dtmf == AST_SIP_DTMF_RFC_4733) {
  1256. ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 1);
  1257. ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_RFC2833);
  1258. } else if (channel->session->dtmf == AST_SIP_DTMF_INFO) {
  1259. ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 0);
  1260. ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_NONE);
  1261. } else if (channel->session->dtmf == AST_SIP_DTMF_INBAND) {
  1262. ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 0);
  1263. ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_INBAND);
  1264. } else if (channel->session->dtmf == AST_SIP_DTMF_NONE) {
  1265. ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 0);
  1266. ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_NONE);
  1267. } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO) {
  1268. if (ast_rtp_instance_dtmf_mode_get((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp) != AST_RTP_DTMF_MODE_RFC2833) {
  1269. /* no RFC4733 negotiated, enable inband */
  1270. ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_INBAND);
  1271. }
  1272. } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
  1273. ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 0);
  1274. if (ast_rtp_instance_dtmf_mode_get((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp) == AST_RTP_DTMF_MODE_INBAND) {
  1275. /* if inband, switch to INFO */
  1276. ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_NONE);
  1277. }
  1278. }
  1279. }
  1280. if (channel->session->dsp) {
  1281. dsp_features = ast_dsp_get_features(channel->session->dsp);
  1282. }
  1283. if (channel->session->dtmf == AST_SIP_DTMF_INBAND ||
  1284. channel->session->dtmf == AST_SIP_DTMF_AUTO) {
  1285. dsp_features |= DSP_FEATURE_DIGIT_DETECT;
  1286. } else {
  1287. dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
  1288. }
  1289. if (dsp_features) {
  1290. if (!channel->session->dsp) {
  1291. if (!(channel->session->dsp = ast_dsp_new())) {
  1292. ast_channel_unlock(chan);
  1293. return 0;
  1294. }
  1295. }
  1296. ast_dsp_set_features(channel->session->dsp, dsp_features);
  1297. } else if (channel->session->dsp) {
  1298. ast_dsp_free(channel->session->dsp);
  1299. channel->session->dsp = NULL;
  1300. }
  1301. ast_channel_unlock(chan);
  1302. return ast_sip_push_task_wait_serializer(channel->session->serializer, dtmf_mode_refresh_cb, &rdata);
  1303. }
  1304. static int refresh_write_cb(void *obj)
  1305. {
  1306. struct refresh_data *data = obj;
  1307. ast_sip_session_refresh(data->session, NULL, NULL,
  1308. sip_session_response_cb, data->method, 1);
  1309. return 0;
  1310. }
  1311. int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
  1312. {
  1313. struct ast_sip_channel_pvt *channel;
  1314. struct refresh_data rdata = {
  1315. .method = AST_SIP_SESSION_REFRESH_METHOD_INVITE,
  1316. };
  1317. if (!chan) {
  1318. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  1319. return -1;
  1320. }
  1321. if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
  1322. ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
  1323. return -1;
  1324. }
  1325. channel = ast_channel_tech_pvt(chan);
  1326. rdata.session = channel->session;
  1327. if (!strcmp(value, "invite")) {
  1328. rdata.method = AST_SIP_SESSION_REFRESH_METHOD_INVITE;
  1329. } else if (!strcmp(value, "update")) {
  1330. rdata.method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
  1331. }
  1332. return ast_sip_push_task_wait_serializer(channel->session->serializer, refresh_write_cb, &rdata);
  1333. }