manager_channels.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * David M. Lee, II <dlee@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief The Asterisk Management Interface - AMI (channel event handling)
  21. *
  22. * \author David M. Lee, II <dlee@digium.com>
  23. *
  24. * AMI generated many per-channel and global-channel events by converting Stasis
  25. * messages to AMI events. It makes sense to simply put them into a single file.
  26. */
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include "asterisk/callerid.h"
  30. #include "asterisk/channel.h"
  31. #include "asterisk/manager.h"
  32. #include "asterisk/stasis_message_router.h"
  33. #include "asterisk/pbx.h"
  34. #include "asterisk/stasis_channels.h"
  35. /*** DOCUMENTATION
  36. <managerEvent language="en_US" name="Newchannel">
  37. <managerEventInstance class="EVENT_FLAG_CALL">
  38. <synopsis>Raised when a new channel is created.</synopsis>
  39. <syntax>
  40. <channel_snapshot/>
  41. </syntax>
  42. <see-also>
  43. <ref type="managerEvent">Newstate</ref>
  44. <ref type="managerEvent">Hangup</ref>
  45. </see-also>
  46. </managerEventInstance>
  47. </managerEvent>
  48. <managerEvent language="en_US" name="Newstate">
  49. <managerEventInstance class="EVENT_FLAG_CALL">
  50. <synopsis>Raised when a channel's state changes.</synopsis>
  51. <syntax>
  52. <channel_snapshot/>
  53. </syntax>
  54. <see-also>
  55. <ref type="managerEvent">Newchannel</ref>
  56. <ref type="managerEvent">Hangup</ref>
  57. </see-also>
  58. </managerEventInstance>
  59. </managerEvent>
  60. <managerEvent language="en_US" name="Hangup">
  61. <managerEventInstance class="EVENT_FLAG_CALL">
  62. <synopsis>Raised when a channel is hung up.</synopsis>
  63. <syntax>
  64. <channel_snapshot/>
  65. <parameter name="Cause">
  66. <para>A numeric cause code for why the channel was hung up.</para>
  67. </parameter>
  68. <parameter name="Cause-txt">
  69. <para>A description of why the channel was hung up.</para>
  70. </parameter>
  71. </syntax>
  72. <see-also>
  73. <ref type="managerEvent">Newchannel</ref>
  74. <ref type="managerEvent">SoftHangupRequest</ref>
  75. <ref type="managerEvent">HangupRequest</ref>
  76. <ref type="managerEvent">Newstate</ref>
  77. </see-also>
  78. </managerEventInstance>
  79. </managerEvent>
  80. <managerEvent language="en_US" name="HangupRequest">
  81. <managerEventInstance class="EVENT_FLAG_CALL">
  82. <synopsis>Raised when a hangup is requested.</synopsis>
  83. <syntax>
  84. <channel_snapshot/>
  85. <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
  86. </syntax>
  87. <see-also>
  88. <ref type="managerEvent">SoftHangupRequest</ref>
  89. <ref type="managerEvent">Hangup</ref>
  90. </see-also>
  91. </managerEventInstance>
  92. </managerEvent>
  93. <managerEvent language="en_US" name="SoftHangupRequest">
  94. <managerEventInstance class="EVENT_FLAG_CALL">
  95. <synopsis>Raised when a soft hangup is requested with a specific cause code.</synopsis>
  96. <syntax>
  97. <channel_snapshot/>
  98. <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
  99. </syntax>
  100. <see-also>
  101. <ref type="managerEvent">HangupRequest</ref>
  102. <ref type="managerEvent">Hangup</ref>
  103. </see-also>
  104. </managerEventInstance>
  105. </managerEvent>
  106. <managerEvent language="en_US" name="NewExten">
  107. <managerEventInstance class="EVENT_FLAG_DIALPLAN">
  108. <synopsis>Raised when a channel enters a new context, extension, priority.</synopsis>
  109. <syntax>
  110. <channel_snapshot/>
  111. <parameter name="Extension">
  112. <para>Deprecated in 12, but kept for
  113. backward compatability. Please use
  114. 'Exten' instead.</para>
  115. </parameter>
  116. <parameter name="Application">
  117. <para>The application about to be executed.</para>
  118. </parameter>
  119. <parameter name="AppData">
  120. <para>The data to be passed to the application.</para>
  121. </parameter>
  122. </syntax>
  123. </managerEventInstance>
  124. </managerEvent>
  125. <managerEvent language="en_US" name="NewCallerid">
  126. <managerEventInstance class="EVENT_FLAG_CALL">
  127. <synopsis>Raised when a channel receives new Caller ID information.</synopsis>
  128. <syntax>
  129. <channel_snapshot/>
  130. <parameter name="CID-CallingPres">
  131. <para>A description of the Caller ID presentation.</para>
  132. </parameter>
  133. </syntax>
  134. <see-also>
  135. <ref type="function">CALLERID</ref>
  136. </see-also>
  137. </managerEventInstance>
  138. </managerEvent>
  139. <managerEvent language="en_US" name="NewConnectedLine">
  140. <managerEventInstance class="EVENT_FLAG_CALL">
  141. <synopsis>Raised when a channel's connected line information is changed.</synopsis>
  142. <syntax>
  143. <channel_snapshot/>
  144. </syntax>
  145. <see-also>
  146. <ref type="function">CONNECTEDLINE</ref>
  147. </see-also>
  148. </managerEventInstance>
  149. </managerEvent>
  150. <managerEvent language="en_US" name="NewAccountCode">
  151. <managerEventInstance class="EVENT_FLAG_CALL">
  152. <synopsis>Raised when a Channel's AccountCode is changed.</synopsis>
  153. <syntax>
  154. <channel_snapshot/>
  155. <parameter name="OldAccountCode">
  156. <para>The channel's previous account code</para>
  157. </parameter>
  158. </syntax>
  159. <see-also>
  160. <ref type="function">CHANNEL</ref>
  161. </see-also>
  162. </managerEventInstance>
  163. </managerEvent>
  164. <managerEvent language="en_US" name="DialBegin">
  165. <managerEventInstance class="EVENT_FLAG_CALL">
  166. <synopsis>Raised when a dial action has started.</synopsis>
  167. <syntax>
  168. <channel_snapshot/>
  169. <channel_snapshot prefix="Dest"/>
  170. <parameter name="DialString">
  171. <para>The non-technology specific device being dialed.</para>
  172. </parameter>
  173. </syntax>
  174. <see-also>
  175. <ref type="application">Dial</ref>
  176. <ref type="application">Originate</ref>
  177. <ref type="manager">Originate</ref>
  178. <ref type="managerEvent">DialEnd</ref>
  179. </see-also>
  180. </managerEventInstance>
  181. </managerEvent>
  182. <managerEvent language="en_US" name="DialEnd">
  183. <managerEventInstance class="EVENT_FLAG_CALL">
  184. <synopsis>Raised when a dial action has completed.</synopsis>
  185. <syntax>
  186. <channel_snapshot/>
  187. <channel_snapshot prefix="Dest"/>
  188. <parameter name="DialStatus">
  189. <para>The result of the dial operation.</para>
  190. <enumlist>
  191. <enum name="ABORT">
  192. <para>The call was aborted.</para>
  193. </enum>
  194. <enum name="ANSWER">
  195. <para>The caller answered.</para>
  196. </enum>
  197. <enum name="BUSY">
  198. <para>The caller was busy.</para>
  199. </enum>
  200. <enum name="CANCEL">
  201. <para>The caller cancelled the call.</para>
  202. </enum>
  203. <enum name="CHANUNAVAIL">
  204. <para>The requested channel is unavailable.</para>
  205. </enum>
  206. <enum name="CONGESTION">
  207. <para>The called party is congested.</para>
  208. </enum>
  209. <enum name="CONTINUE">
  210. <para>The dial completed, but the caller elected
  211. to continue in the dialplan.</para>
  212. </enum>
  213. <enum name="GOTO">
  214. <para>The dial completed, but the caller jumped to
  215. a dialplan location.</para>
  216. <para>If known, the location the caller is jumping
  217. to will be appended to the result following a
  218. ":".</para>
  219. </enum>
  220. <enum name="NOANSWER">
  221. <para>The called party failed to answer.</para>
  222. </enum>
  223. </enumlist>
  224. </parameter>
  225. <parameter name="Forward" required="false">
  226. <para>If the call was forwarded, where the call was
  227. forwarded to.</para>
  228. </parameter>
  229. </syntax>
  230. <see-also>
  231. <ref type="application">Dial</ref>
  232. <ref type="application">Originate</ref>
  233. <ref type="manager">Originate</ref>
  234. <ref type="managerEvent">DialBegin</ref>
  235. </see-also>
  236. </managerEventInstance>
  237. </managerEvent>
  238. <managerEvent language="en_US" name="Hold">
  239. <managerEventInstance class="EVENT_FLAG_CALL">
  240. <synopsis>Raised when a channel goes on hold.</synopsis>
  241. <syntax>
  242. <channel_snapshot/>
  243. <parameter name="MusicClass">
  244. <para>The suggested MusicClass, if provided.</para>
  245. </parameter>
  246. </syntax>
  247. <see-also>
  248. <ref type="managerEvent">Unhold</ref>
  249. </see-also>
  250. </managerEventInstance>
  251. </managerEvent>
  252. <managerEvent language="en_US" name="Unhold">
  253. <managerEventInstance class="EVENT_FLAG_CALL">
  254. <synopsis>Raised when a channel goes off hold.</synopsis>
  255. <syntax>
  256. <channel_snapshot/>
  257. </syntax>
  258. <see-also>
  259. <ref type="managerEvent">Hold</ref>
  260. </see-also>
  261. </managerEventInstance>
  262. </managerEvent>
  263. <managerEvent language="en_US" name="ChanSpyStart">
  264. <managerEventInstance class="EVENT_FLAG_CALL">
  265. <synopsis>Raised when one channel begins spying on another channel.</synopsis>
  266. <syntax>
  267. <channel_snapshot prefix="Spyer"/>
  268. <channel_snapshot prefix="Spyee"/>
  269. </syntax>
  270. <see-also>
  271. <ref type="managerEvent">ChanSpyStop</ref>
  272. <ref type="application">ChanSpy</ref>
  273. </see-also>
  274. </managerEventInstance>
  275. </managerEvent>
  276. <managerEvent language="en_US" name="ChanSpyStop">
  277. <managerEventInstance class="EVENT_FLAG_CALL">
  278. <synopsis>Raised when a channel has stopped spying.</synopsis>
  279. <syntax>
  280. <channel_snapshot prefix="Spyer"/>
  281. <channel_snapshot prefix="Spyee"/>
  282. </syntax>
  283. <see-also>
  284. <ref type="managerEvent">ChanSpyStart</ref>
  285. <ref type="application">ChanSpy</ref>
  286. </see-also>
  287. </managerEventInstance>
  288. </managerEvent>
  289. <managerEvent language="en_US" name="HangupHandlerRun">
  290. <managerEventInstance class="EVENT_FLAG_DIALPLAN">
  291. <synopsis>Raised when a hangup handler is about to be called.</synopsis>
  292. <syntax>
  293. <channel_snapshot/>
  294. <parameter name="Handler">
  295. <para>Hangup handler parameter string passed to the Gosub application.</para>
  296. </parameter>
  297. </syntax>
  298. <see-also>
  299. <ref type="function">CHANNEL</ref>
  300. </see-also>
  301. </managerEventInstance>
  302. </managerEvent>
  303. <managerEvent language="en_US" name="HangupHandlerPop">
  304. <managerEventInstance class="EVENT_FLAG_DIALPLAN">
  305. <synopsis>
  306. Raised when a hangup handler is removed from the handler stack
  307. by the CHANNEL() function.
  308. </synopsis>
  309. <syntax>
  310. <channel_snapshot/>
  311. <xi:include xpointer="xpointer(/docs/managerEvent[@name='HangupHandlerRun']/managerEventInstance/syntax/parameter)" />
  312. </syntax>
  313. <see-also>
  314. <ref type="managerEvent">HangupHandlerPush</ref>
  315. <ref type="function">CHANNEL</ref>
  316. </see-also>
  317. </managerEventInstance>
  318. </managerEvent>
  319. <managerEvent language="en_US" name="HangupHandlerPush">
  320. <managerEventInstance class="EVENT_FLAG_DIALPLAN">
  321. <synopsis>
  322. Raised when a hangup handler is added to the handler stack by
  323. the CHANNEL() function.
  324. </synopsis>
  325. <syntax>
  326. <channel_snapshot/>
  327. <xi:include xpointer="xpointer(/docs/managerEvent[@name='HangupHandlerRun']/managerEventInstance/syntax/parameter)" />
  328. </syntax>
  329. <see-also>
  330. <ref type="managerEvent">HangupHandlerPop</ref>
  331. <ref type="function">CHANNEL</ref>
  332. </see-also>
  333. </managerEventInstance>
  334. </managerEvent>
  335. <managerEvent language="en_US" name="FAXStatus">
  336. <managerEventInstance class="EVENT_FLAG_CALL">
  337. <synopsis>
  338. Raised periodically during a fax transmission.
  339. </synopsis>
  340. <syntax>
  341. <channel_snapshot/>
  342. <parameter name="Operation">
  343. <enumlist>
  344. <enum name="gateway"/>
  345. <enum name="receive"/>
  346. <enum name="send"/>
  347. </enumlist>
  348. </parameter>
  349. <parameter name="Status">
  350. <para>A text message describing the current status of the fax</para>
  351. </parameter>
  352. <xi:include xpointer="xpointer(/docs/managerEvent[@name='ReceiveFAX']/managerEventInstance/syntax/parameter[@name='LocalStationID'])" />
  353. <xi:include xpointer="xpointer(/docs/managerEvent[@name='ReceiveFAX']/managerEventInstance/syntax/parameter[@name='FileName'])" />
  354. </syntax>
  355. </managerEventInstance>
  356. </managerEvent>
  357. <managerEvent language="en_US" name="ReceiveFAX">
  358. <managerEventInstance class="EVENT_FLAG_CALL">
  359. <synopsis>
  360. Raised when a receive fax operation has completed.
  361. </synopsis>
  362. <syntax>
  363. <channel_snapshot/>
  364. <parameter name="LocalStationID">
  365. <para>The value of the <variable>LOCALSTATIONID</variable> channel variable</para>
  366. </parameter>
  367. <parameter name="RemoteStationID">
  368. <para>The value of the <variable>REMOTESTATIONID</variable> channel variable</para>
  369. </parameter>
  370. <parameter name="PagesTransferred">
  371. <para>The number of pages that have been transferred</para>
  372. </parameter>
  373. <parameter name="Resolution">
  374. <para>The negotiated resolution</para>
  375. </parameter>
  376. <parameter name="TransferRate">
  377. <para>The negotiated transfer rate</para>
  378. </parameter>
  379. <parameter name="FileName" multiple="yes">
  380. <para>The files being affected by the fax operation</para>
  381. </parameter>
  382. </syntax>
  383. </managerEventInstance>
  384. </managerEvent>
  385. <managerEvent language="en_US" name="SendFAX">
  386. <managerEventInstance class="EVENT_FLAG_CALL">
  387. <synopsis>
  388. Raised when a send fax operation has completed.
  389. </synopsis>
  390. <syntax>
  391. <channel_snapshot/>
  392. <xi:include xpointer="xpointer(/docs/managerEvent[@name='ReceiveFAX']/managerEventInstance/syntax/parameter)" />
  393. </syntax>
  394. </managerEventInstance>
  395. </managerEvent>
  396. <managerEvent language="en_US" name="MusicOnHoldStart">
  397. <managerEventInstance class="EVENT_FLAG_CALL">
  398. <synopsis>Raised when music on hold has started on a channel.</synopsis>
  399. <syntax>
  400. <channel_snapshot/>
  401. <parameter name="Class">
  402. <para>The class of music being played on the channel</para>
  403. </parameter>
  404. </syntax>
  405. <see-also>
  406. <ref type="managerEvent">MusicOnHoldStop</ref>
  407. <ref type="application">StartMusicOnHold</ref>
  408. <ref type="application">MusicOnHold</ref>
  409. </see-also>
  410. </managerEventInstance>
  411. </managerEvent>
  412. <managerEvent language="en_US" name="MusicOnHoldStop">
  413. <managerEventInstance class="EVENT_FLAG_CALL">
  414. <synopsis>Raised when music on hold has stopped on a channel.</synopsis>
  415. <syntax>
  416. <channel_snapshot/>
  417. </syntax>
  418. <see-also>
  419. <ref type="managerEvent">MusicOnHoldStart</ref>
  420. <ref type="application">StopMusicOnHold</ref>
  421. </see-also>
  422. </managerEventInstance>
  423. </managerEvent>
  424. <managerEvent language="en_US" name="MonitorStart">
  425. <managerEventInstance class="EVENT_FLAG_CALL">
  426. <synopsis>Raised when monitoring has started on a channel.</synopsis>
  427. <syntax>
  428. <channel_snapshot/>
  429. </syntax>
  430. <see-also>
  431. <ref type="managerEvent">MonitorStop</ref>
  432. <ref type="application">Monitor</ref>
  433. <ref type="manager">Monitor</ref>
  434. </see-also>
  435. </managerEventInstance>
  436. </managerEvent>
  437. <managerEvent language="en_US" name="MonitorStop">
  438. <managerEventInstance class="EVENT_FLAG_CALL">
  439. <synopsis>Raised when monitoring has stopped on a channel.</synopsis>
  440. <syntax>
  441. <channel_snapshot/>
  442. </syntax>
  443. <see-also>
  444. <ref type="managerEvent">MonitorStart</ref>
  445. <ref type="application">StopMonitor</ref>
  446. <ref type="manager">StopMonitor</ref>
  447. </see-also>
  448. </managerEventInstance>
  449. </managerEvent>
  450. ***/
  451. /*! \brief The \ref stasis subscription returned by the forwarding of the channel topic
  452. * to the manager topic
  453. */
  454. static struct stasis_forward *topic_forwarder;
  455. struct ast_str *ast_manager_build_channel_state_string_prefix(
  456. const struct ast_channel_snapshot *snapshot,
  457. const char *prefix)
  458. {
  459. struct ast_str *out;
  460. char *caller_name;
  461. char *connected_name;
  462. int res;
  463. if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) {
  464. return NULL;
  465. }
  466. out = ast_str_create(1024);
  467. if (!out) {
  468. return NULL;
  469. }
  470. caller_name = ast_escape_c_alloc(snapshot->caller_name);
  471. connected_name = ast_escape_c_alloc(snapshot->connected_name);
  472. res = ast_str_set(&out, 0,
  473. "%sChannel: %s\r\n"
  474. "%sChannelState: %u\r\n"
  475. "%sChannelStateDesc: %s\r\n"
  476. "%sCallerIDNum: %s\r\n"
  477. "%sCallerIDName: %s\r\n"
  478. "%sConnectedLineNum: %s\r\n"
  479. "%sConnectedLineName: %s\r\n"
  480. "%sLanguage: %s\r\n"
  481. "%sAccountCode: %s\r\n"
  482. "%sContext: %s\r\n"
  483. "%sExten: %s\r\n"
  484. "%sPriority: %d\r\n"
  485. "%sUniqueid: %s\r\n"
  486. "%sLinkedid: %s\r\n",
  487. prefix, snapshot->name,
  488. prefix, snapshot->state,
  489. prefix, ast_state2str(snapshot->state),
  490. prefix, S_OR(snapshot->caller_number, "<unknown>"),
  491. prefix, S_OR(caller_name, "<unknown>"),
  492. prefix, S_OR(snapshot->connected_number, "<unknown>"),
  493. prefix, S_OR(connected_name, "<unknown>"),
  494. prefix, snapshot->language,
  495. prefix, snapshot->accountcode,
  496. prefix, snapshot->context,
  497. prefix, snapshot->exten,
  498. prefix, snapshot->priority,
  499. prefix, snapshot->uniqueid,
  500. prefix, snapshot->linkedid);
  501. ast_free(caller_name);
  502. ast_free(connected_name);
  503. if (!res) {
  504. ast_free(out);
  505. return NULL;
  506. }
  507. if (snapshot->manager_vars) {
  508. struct ast_var_t *var;
  509. char *val;
  510. AST_LIST_TRAVERSE(snapshot->manager_vars, var, entries) {
  511. val = ast_escape_c_alloc(var->value);
  512. ast_str_append(&out, 0, "%sChanVariable: %s=%s\r\n",
  513. prefix,
  514. var->name, S_OR(val, ""));
  515. ast_free(val);
  516. }
  517. }
  518. return out;
  519. }
  520. struct ast_str *ast_manager_build_channel_state_string(
  521. const struct ast_channel_snapshot *snapshot)
  522. {
  523. return ast_manager_build_channel_state_string_prefix(snapshot, "");
  524. }
  525. /*! \brief Typedef for callbacks that get called on channel snapshot updates */
  526. typedef struct ast_manager_event_blob *(*channel_snapshot_monitor)(
  527. struct ast_channel_snapshot *old_snapshot,
  528. struct ast_channel_snapshot *new_snapshot);
  529. /*! \brief Handle channel state changes */
  530. static struct ast_manager_event_blob *channel_state_change(
  531. struct ast_channel_snapshot *old_snapshot,
  532. struct ast_channel_snapshot *new_snapshot)
  533. {
  534. int is_hungup, was_hungup;
  535. if (!new_snapshot) {
  536. /* Ignore cache clearing events; we'll see the hangup first */
  537. return NULL;
  538. }
  539. /* The Newchannel, Newstate and Hangup events are closely related, in
  540. * in that they are mutually exclusive, basically different flavors
  541. * of a new channel state event.
  542. */
  543. if (!old_snapshot) {
  544. return ast_manager_event_blob_create(
  545. EVENT_FLAG_CALL, "Newchannel", NO_EXTRA_FIELDS);
  546. }
  547. was_hungup = ast_test_flag(&old_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
  548. is_hungup = ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
  549. if (!was_hungup && is_hungup) {
  550. return ast_manager_event_blob_create(
  551. EVENT_FLAG_CALL, "Hangup",
  552. "Cause: %d\r\n"
  553. "Cause-txt: %s\r\n",
  554. new_snapshot->hangupcause,
  555. ast_cause2str(new_snapshot->hangupcause));
  556. }
  557. if (old_snapshot->state != new_snapshot->state) {
  558. return ast_manager_event_blob_create(
  559. EVENT_FLAG_CALL, "Newstate", NO_EXTRA_FIELDS);
  560. }
  561. /* No event */
  562. return NULL;
  563. }
  564. static struct ast_manager_event_blob *channel_newexten(
  565. struct ast_channel_snapshot *old_snapshot,
  566. struct ast_channel_snapshot *new_snapshot)
  567. {
  568. /* No Newexten event on cache clear */
  569. if (!new_snapshot) {
  570. return NULL;
  571. }
  572. /* Empty application is not valid for a Newexten event */
  573. if (ast_strlen_zero(new_snapshot->appl)) {
  574. return NULL;
  575. }
  576. /* Ignore any updates if we're hungup */
  577. if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
  578. return NULL;
  579. }
  580. /* Ignore updates if the CEP is unchanged */
  581. if (old_snapshot && ast_channel_snapshot_cep_equal(old_snapshot, new_snapshot)) {
  582. return NULL;
  583. }
  584. /* DEPRECATED: Extension field deprecated in 12; remove in 14 */
  585. return ast_manager_event_blob_create(
  586. EVENT_FLAG_CALL, "Newexten",
  587. "Extension: %s\r\n"
  588. "Application: %s\r\n"
  589. "AppData: %s\r\n",
  590. new_snapshot->exten,
  591. new_snapshot->appl,
  592. new_snapshot->data);
  593. }
  594. static struct ast_manager_event_blob *channel_new_callerid(
  595. struct ast_channel_snapshot *old_snapshot,
  596. struct ast_channel_snapshot *new_snapshot)
  597. {
  598. struct ast_manager_event_blob *res;
  599. char *callerid;
  600. /* No NewCallerid event on cache clear or first event */
  601. if (!old_snapshot || !new_snapshot) {
  602. return NULL;
  603. }
  604. if (ast_channel_snapshot_caller_id_equal(old_snapshot, new_snapshot)) {
  605. return NULL;
  606. }
  607. if (!(callerid = ast_escape_c_alloc(
  608. ast_describe_caller_presentation(new_snapshot->caller_pres)))) {
  609. return NULL;
  610. }
  611. res = ast_manager_event_blob_create(
  612. EVENT_FLAG_CALL, "NewCallerid",
  613. "CID-CallingPres: %d (%s)\r\n",
  614. new_snapshot->caller_pres,
  615. callerid);
  616. ast_free(callerid);
  617. return res;
  618. }
  619. static struct ast_manager_event_blob *channel_new_connected_line(
  620. struct ast_channel_snapshot *old_snapshot,
  621. struct ast_channel_snapshot *new_snapshot)
  622. {
  623. /* No NewConnectedLine event on cache clear or first event */
  624. if (!old_snapshot || !new_snapshot) {
  625. return NULL;
  626. }
  627. if (ast_channel_snapshot_connected_line_equal(old_snapshot, new_snapshot)) {
  628. return NULL;
  629. }
  630. return ast_manager_event_blob_create(
  631. EVENT_FLAG_CALL, "NewConnectedLine", "%s", "");
  632. }
  633. static struct ast_manager_event_blob *channel_new_accountcode(
  634. struct ast_channel_snapshot *old_snapshot,
  635. struct ast_channel_snapshot *new_snapshot)
  636. {
  637. if (!old_snapshot || !new_snapshot) {
  638. return NULL;
  639. }
  640. if (!strcmp(old_snapshot->accountcode, new_snapshot->accountcode)) {
  641. return NULL;
  642. }
  643. return ast_manager_event_blob_create(
  644. EVENT_FLAG_CALL, "NewAccountCode",
  645. "OldAccountCode: %s\r\n", old_snapshot->accountcode);
  646. }
  647. channel_snapshot_monitor channel_monitors[] = {
  648. channel_state_change,
  649. channel_newexten,
  650. channel_new_callerid,
  651. channel_new_accountcode,
  652. channel_new_connected_line,
  653. };
  654. static void channel_snapshot_update(void *data, struct stasis_subscription *sub,
  655. struct stasis_message *message)
  656. {
  657. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  658. struct stasis_cache_update *update;
  659. struct ast_channel_snapshot *old_snapshot;
  660. struct ast_channel_snapshot *new_snapshot;
  661. size_t i;
  662. update = stasis_message_data(message);
  663. ast_assert(ast_channel_snapshot_type() == update->type);
  664. old_snapshot = stasis_message_data(update->old_snapshot);
  665. new_snapshot = stasis_message_data(update->new_snapshot);
  666. for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
  667. RAII_VAR(struct ast_manager_event_blob *, ev, NULL, ao2_cleanup);
  668. ev = channel_monitors[i](old_snapshot, new_snapshot);
  669. if (!ev) {
  670. continue;
  671. }
  672. /* If we haven't already, build the channel event string */
  673. if (!channel_event_string) {
  674. channel_event_string =
  675. ast_manager_build_channel_state_string(new_snapshot);
  676. if (!channel_event_string) {
  677. return;
  678. }
  679. }
  680. manager_event(ev->event_flags, ev->manager_event, "%s%s",
  681. ast_str_buffer(channel_event_string),
  682. ev->extra_fields);
  683. }
  684. }
  685. static void publish_basic_channel_event(const char *event, int class, struct ast_channel_snapshot *snapshot)
  686. {
  687. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  688. channel_event_string = ast_manager_build_channel_state_string(snapshot);
  689. if (!channel_event_string) {
  690. return;
  691. }
  692. manager_event(class, event,
  693. "%s",
  694. ast_str_buffer(channel_event_string));
  695. }
  696. static void channel_hangup_request_cb(void *data,
  697. struct stasis_subscription *sub,
  698. struct stasis_message *message)
  699. {
  700. struct ast_channel_blob *obj = stasis_message_data(message);
  701. struct ast_str *extra;
  702. struct ast_str *channel_event_string;
  703. struct ast_json *cause;
  704. int is_soft;
  705. char *manager_event = "HangupRequest";
  706. if (!obj->snapshot) {
  707. /* No snapshot? Likely an earlier allocation failure creating it. */
  708. return;
  709. }
  710. extra = ast_str_create(20);
  711. if (!extra) {
  712. return;
  713. }
  714. channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
  715. if (!channel_event_string) {
  716. ast_free(extra);
  717. return;
  718. }
  719. cause = ast_json_object_get(obj->blob, "cause");
  720. if (cause) {
  721. ast_str_append(&extra, 0,
  722. "Cause: %jd\r\n",
  723. ast_json_integer_get(cause));
  724. }
  725. is_soft = ast_json_is_true(ast_json_object_get(obj->blob, "soft"));
  726. if (is_soft) {
  727. manager_event = "SoftHangupRequest";
  728. }
  729. manager_event(EVENT_FLAG_CALL, manager_event,
  730. "%s%s",
  731. ast_str_buffer(channel_event_string),
  732. ast_str_buffer(extra));
  733. ast_free(channel_event_string);
  734. ast_free(extra);
  735. }
  736. static void channel_chanspy_stop_cb(void *data, struct stasis_subscription *sub,
  737. struct stasis_message *message)
  738. {
  739. RAII_VAR(struct ast_str *, spyer_channel_string, NULL, ast_free);
  740. struct ast_channel_snapshot *spyer;
  741. struct ast_multi_channel_blob *payload = stasis_message_data(message);
  742. spyer = ast_multi_channel_blob_get_channel(payload, "spyer_channel");
  743. if (!spyer) {
  744. ast_log(AST_LOG_WARNING, "Received ChanSpy Start event with no spyer channel!\n");
  745. return;
  746. }
  747. spyer_channel_string = ast_manager_build_channel_state_string_prefix(spyer, "Spyer");
  748. if (!spyer_channel_string) {
  749. return;
  750. }
  751. manager_event(EVENT_FLAG_CALL, "ChanSpyStop",
  752. "%s",
  753. ast_str_buffer(spyer_channel_string));
  754. }
  755. static void channel_chanspy_start_cb(void *data, struct stasis_subscription *sub,
  756. struct stasis_message *message)
  757. {
  758. RAII_VAR(struct ast_str *, spyer_channel_string, NULL, ast_free);
  759. RAII_VAR(struct ast_str *, spyee_channel_string, NULL, ast_free);
  760. struct ast_channel_snapshot *spyer;
  761. struct ast_channel_snapshot *spyee;
  762. struct ast_multi_channel_blob *payload = stasis_message_data(message);
  763. spyer = ast_multi_channel_blob_get_channel(payload, "spyer_channel");
  764. if (!spyer) {
  765. ast_log(AST_LOG_WARNING, "Received ChanSpy Start event with no spyer channel!\n");
  766. return;
  767. }
  768. spyee = ast_multi_channel_blob_get_channel(payload, "spyee_channel");
  769. if (!spyee) {
  770. ast_log(AST_LOG_WARNING, "Received ChanSpy Start event with no spyee channel!\n");
  771. return;
  772. }
  773. spyer_channel_string = ast_manager_build_channel_state_string_prefix(spyer, "Spyer");
  774. if (!spyer_channel_string) {
  775. return;
  776. }
  777. spyee_channel_string = ast_manager_build_channel_state_string_prefix(spyee, "Spyee");
  778. if (!spyee_channel_string) {
  779. return;
  780. }
  781. manager_event(EVENT_FLAG_CALL, "ChanSpyStart",
  782. "%s%s",
  783. ast_str_buffer(spyer_channel_string),
  784. ast_str_buffer(spyee_channel_string));
  785. }
  786. static void channel_dtmf_begin_cb(void *data, struct stasis_subscription *sub,
  787. struct stasis_message *message)
  788. {
  789. struct ast_channel_blob *obj = stasis_message_data(message);
  790. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  791. const char *digit =
  792. ast_json_string_get(ast_json_object_get(obj->blob, "digit"));
  793. const char *direction =
  794. ast_json_string_get(ast_json_object_get(obj->blob, "direction"));
  795. channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
  796. if (!channel_event_string) {
  797. return;
  798. }
  799. /*** DOCUMENTATION
  800. <managerEventInstance>
  801. <synopsis>Raised when a DTMF digit has started on a channel.</synopsis>
  802. <syntax>
  803. <channel_snapshot/>
  804. <parameter name="Digit">
  805. <para>DTMF digit received or transmitted (0-9, A-E, # or *</para>
  806. </parameter>
  807. <parameter name="Direction">
  808. <enumlist>
  809. <enum name="Received"/>
  810. <enum name="Sent"/>
  811. </enumlist>
  812. </parameter>
  813. </syntax>
  814. <see-also>
  815. <ref type="managerEvent">DTMFEnd</ref>
  816. </see-also>
  817. </managerEventInstance>
  818. ***/
  819. manager_event(EVENT_FLAG_DTMF, "DTMFBegin",
  820. "%s"
  821. "Digit: %s\r\n"
  822. "Direction: %s\r\n",
  823. ast_str_buffer(channel_event_string),
  824. digit, direction);
  825. }
  826. static void channel_dtmf_end_cb(void *data, struct stasis_subscription *sub,
  827. struct stasis_message *message)
  828. {
  829. struct ast_channel_blob *obj = stasis_message_data(message);
  830. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  831. const char *digit =
  832. ast_json_string_get(ast_json_object_get(obj->blob, "digit"));
  833. const char *direction =
  834. ast_json_string_get(ast_json_object_get(obj->blob, "direction"));
  835. long duration_ms =
  836. ast_json_integer_get(ast_json_object_get(obj->blob, "duration_ms"));
  837. channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
  838. if (!channel_event_string) {
  839. return;
  840. }
  841. /*** DOCUMENTATION
  842. <managerEventInstance>
  843. <synopsis>Raised when a DTMF digit has ended on a channel.</synopsis>
  844. <syntax>
  845. <channel_snapshot/>
  846. <parameter name="Digit">
  847. <para>DTMF digit received or transmitted (0-9, A-E, # or *</para>
  848. </parameter>
  849. <parameter name="DurationMs">
  850. <para>Duration (in milliseconds) DTMF was sent/received</para>
  851. </parameter>
  852. <parameter name="Direction">
  853. <enumlist>
  854. <enum name="Received"/>
  855. <enum name="Sent"/>
  856. </enumlist>
  857. </parameter>
  858. </syntax>
  859. <see-also>
  860. <ref type="managerEvent">DTMFBegin</ref>
  861. </see-also>
  862. </managerEventInstance>
  863. ***/
  864. manager_event(EVENT_FLAG_DTMF, "DTMFEnd",
  865. "%s"
  866. "Digit: %s\r\n"
  867. "DurationMs: %ld\r\n"
  868. "Direction: %s\r\n",
  869. ast_str_buffer(channel_event_string),
  870. digit, duration_ms, direction);
  871. }
  872. static void channel_hangup_handler_cb(void *data, struct stasis_subscription *sub,
  873. struct stasis_message *message)
  874. {
  875. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  876. struct ast_channel_blob *payload = stasis_message_data(message);
  877. const char *action = ast_json_string_get(ast_json_object_get(payload->blob, "type"));
  878. const char *handler = ast_json_string_get(ast_json_object_get(payload->blob, "handler"));
  879. const char *event;
  880. channel_event_string = ast_manager_build_channel_state_string(payload->snapshot);
  881. if (!channel_event_string) {
  882. return;
  883. }
  884. if (!strcmp(action, "run")) {
  885. event = "HangupHandlerRun";
  886. } else if (!strcmp(action, "pop")) {
  887. event = "HangupHandlerPop";
  888. } else if (!strcmp(action, "push")) {
  889. event = "HangupHandlerPush";
  890. } else {
  891. return;
  892. }
  893. manager_event(EVENT_FLAG_DIALPLAN, event,
  894. "%s"
  895. "Handler: %s\r\n",
  896. ast_str_buffer(channel_event_string),
  897. handler);
  898. }
  899. static void channel_fax_cb(void *data, struct stasis_subscription *sub,
  900. struct stasis_message *message)
  901. {
  902. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  903. RAII_VAR(struct ast_str *, event_buffer, ast_str_create(256), ast_free);
  904. struct ast_channel_blob *payload = stasis_message_data(message);
  905. const char *type = ast_json_string_get(ast_json_object_get(payload->blob, "type"));
  906. struct ast_json *operation = ast_json_object_get(payload->blob, "operation");
  907. struct ast_json *status = ast_json_object_get(payload->blob, "status");
  908. struct ast_json *local_station_id = ast_json_object_get(payload->blob, "local_station_id");
  909. struct ast_json *remote_station_id = ast_json_object_get(payload->blob, "remote_station_id");
  910. struct ast_json *fax_pages = ast_json_object_get(payload->blob, "fax_pages");
  911. struct ast_json *fax_resolution = ast_json_object_get(payload->blob, "fax_resolution");
  912. struct ast_json *fax_bitrate = ast_json_object_get(payload->blob, "fax_bitrate");
  913. struct ast_json *filenames = ast_json_object_get(payload->blob, "filenames");
  914. const char *event;
  915. size_t array_len;
  916. size_t i;
  917. if (!event_buffer) {
  918. return;
  919. }
  920. channel_event_string = ast_manager_build_channel_state_string(payload->snapshot);
  921. if (!channel_event_string) {
  922. return;
  923. }
  924. if (!strcmp(type, "status")) {
  925. event = "FAXStatus";
  926. } else if (!strcmp(type, "receive")) {
  927. event = "ReceiveFAX";
  928. } else if (!strcmp(type, "send")) {
  929. event = "SendFAX";
  930. } else {
  931. return;
  932. }
  933. if (operation) {
  934. ast_str_append(&event_buffer, 0, "Operation: %s\r\n", ast_json_string_get(operation));
  935. }
  936. if (status) {
  937. ast_str_append(&event_buffer, 0, "Status: %s\r\n", ast_json_string_get(status));
  938. }
  939. if (local_station_id) {
  940. ast_str_append(&event_buffer, 0, "LocalStationID: %s\r\n", ast_json_string_get(local_station_id));
  941. }
  942. if (remote_station_id) {
  943. ast_str_append(&event_buffer, 0, "RemoteStationID: %s\r\n", ast_json_string_get(remote_station_id));
  944. }
  945. if (fax_pages) {
  946. ast_str_append(&event_buffer, 0, "PagesTransferred: %s\r\n", ast_json_string_get(fax_pages));
  947. }
  948. if (fax_resolution) {
  949. ast_str_append(&event_buffer, 0, "Resolution: %s\r\n", ast_json_string_get(fax_resolution));
  950. }
  951. if (fax_bitrate) {
  952. ast_str_append(&event_buffer, 0, "TransferRate: %s\r\n", ast_json_string_get(fax_bitrate));
  953. }
  954. if (filenames) {
  955. array_len = ast_json_array_size(filenames);
  956. for (i = 0; i < array_len; i++) {
  957. ast_str_append(&event_buffer, 0, "FileName: %s\r\n", ast_json_string_get(ast_json_array_get(filenames, i)));
  958. }
  959. }
  960. manager_event(EVENT_FLAG_CALL, event,
  961. "%s"
  962. "%s",
  963. ast_str_buffer(channel_event_string),
  964. ast_str_buffer(event_buffer));
  965. }
  966. static void channel_moh_start_cb(void *data, struct stasis_subscription *sub,
  967. struct stasis_message *message)
  968. {
  969. struct ast_channel_blob *payload = stasis_message_data(message);
  970. struct ast_json *blob = payload->blob;
  971. RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
  972. channel_event_string = ast_manager_build_channel_state_string(payload->snapshot);
  973. if (!channel_event_string) {
  974. return;
  975. }
  976. manager_event(EVENT_FLAG_CALL, "MusicOnHoldStart",
  977. "%s"
  978. "Class: %s\r\n",
  979. ast_str_buffer(channel_event_string),
  980. ast_json_string_get(ast_json_object_get(blob, "class")));
  981. }
  982. static void channel_moh_stop_cb(void *data, struct stasis_subscription *sub,
  983. struct stasis_message *message)
  984. {
  985. struct ast_channel_blob *payload = stasis_message_data(message);
  986. publish_basic_channel_event("MusicOnHoldStop", EVENT_FLAG_CALL, payload->snapshot);
  987. }
  988. static void channel_monitor_start_cb(void *data, struct stasis_subscription *sub,
  989. struct stasis_message *message)
  990. {
  991. struct ast_channel_blob *payload = stasis_message_data(message);
  992. publish_basic_channel_event("MonitorStart", EVENT_FLAG_CALL, payload->snapshot);
  993. }
  994. static void channel_monitor_stop_cb(void *data, struct stasis_subscription *sub,
  995. struct stasis_message *message)
  996. {
  997. struct ast_channel_blob *payload = stasis_message_data(message);
  998. publish_basic_channel_event("MonitorStop", EVENT_FLAG_CALL, payload->snapshot);
  999. }
  1000. /*!
  1001. * \brief Callback processing messages for channel dialing
  1002. */
  1003. static void channel_dial_cb(void *data, struct stasis_subscription *sub,
  1004. struct stasis_message *message)
  1005. {
  1006. struct ast_multi_channel_blob *obj = stasis_message_data(message);
  1007. const char *dialstatus;
  1008. const char *dialstring;
  1009. const char *forward;
  1010. struct ast_channel_snapshot *caller;
  1011. struct ast_channel_snapshot *peer;
  1012. RAII_VAR(struct ast_str *, caller_event_string, NULL, ast_free);
  1013. RAII_VAR(struct ast_str *, peer_event_string, NULL, ast_free);
  1014. caller = ast_multi_channel_blob_get_channel(obj, "caller");
  1015. peer = ast_multi_channel_blob_get_channel(obj, "peer");
  1016. /* Peer is required - otherwise, who are we dialing? */
  1017. ast_assert(peer != NULL);
  1018. peer_event_string = ast_manager_build_channel_state_string_prefix(peer, "Dest");
  1019. if (!peer_event_string) {
  1020. return;
  1021. }
  1022. if (caller && !(caller_event_string = ast_manager_build_channel_state_string(caller))) {
  1023. return;
  1024. }
  1025. dialstatus = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "dialstatus"));
  1026. dialstring = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "dialstring"));
  1027. forward = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "forward"));
  1028. if (ast_strlen_zero(dialstatus)) {
  1029. manager_event(EVENT_FLAG_CALL, "DialBegin",
  1030. "%s"
  1031. "%s"
  1032. "DialString: %s\r\n",
  1033. caller_event_string ? ast_str_buffer(caller_event_string) : "",
  1034. ast_str_buffer(peer_event_string),
  1035. S_OR(dialstring, "unknown"));
  1036. } else {
  1037. int forwarded = !ast_strlen_zero(forward);
  1038. manager_event(EVENT_FLAG_CALL, "DialEnd",
  1039. "%s"
  1040. "%s"
  1041. "%s%s%s"
  1042. "DialStatus: %s\r\n",
  1043. caller_event_string ? ast_str_buffer(caller_event_string) : "",
  1044. ast_str_buffer(peer_event_string),
  1045. forwarded ? "Forward: " : "", S_OR(forward, ""), forwarded ? "\r\n" : "",
  1046. S_OR(dialstatus, "unknown"));
  1047. }
  1048. }
  1049. static void channel_hold_cb(void *data, struct stasis_subscription *sub,
  1050. struct stasis_message *message)
  1051. {
  1052. struct ast_channel_blob *obj = stasis_message_data(message);
  1053. struct ast_str *musicclass_string = ast_str_create(32);
  1054. struct ast_str *channel_event_string;
  1055. if (!musicclass_string) {
  1056. return;
  1057. }
  1058. channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
  1059. if (!channel_event_string) {
  1060. ast_free(musicclass_string);
  1061. return;
  1062. }
  1063. if (obj->blob) {
  1064. const char *musicclass;
  1065. musicclass = ast_json_string_get(ast_json_object_get(obj->blob, "musicclass"));
  1066. if (!ast_strlen_zero(musicclass)) {
  1067. ast_str_set(&musicclass_string, 0, "MusicClass: %s\r\n", musicclass);
  1068. }
  1069. }
  1070. manager_event(EVENT_FLAG_CALL, "Hold",
  1071. "%s"
  1072. "%s",
  1073. ast_str_buffer(channel_event_string),
  1074. ast_str_buffer(musicclass_string));
  1075. ast_free(musicclass_string);
  1076. ast_free(channel_event_string);
  1077. }
  1078. static void channel_unhold_cb(void *data, struct stasis_subscription *sub,
  1079. struct stasis_message *message)
  1080. {
  1081. struct ast_channel_blob *obj = stasis_message_data(message);
  1082. struct ast_str *channel_event_string;
  1083. channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
  1084. if (!channel_event_string) {
  1085. return;
  1086. }
  1087. manager_event(EVENT_FLAG_CALL, "Unhold",
  1088. "%s",
  1089. ast_str_buffer(channel_event_string));
  1090. ast_free(channel_event_string);
  1091. }
  1092. static void manager_channels_shutdown(void)
  1093. {
  1094. stasis_forward_cancel(topic_forwarder);
  1095. topic_forwarder = NULL;
  1096. }
  1097. int manager_channels_init(void)
  1098. {
  1099. int ret = 0;
  1100. struct stasis_topic *manager_topic;
  1101. struct stasis_topic *channel_topic;
  1102. struct stasis_message_router *message_router;
  1103. manager_topic = ast_manager_get_topic();
  1104. if (!manager_topic) {
  1105. return -1;
  1106. }
  1107. message_router = ast_manager_get_message_router();
  1108. if (!message_router) {
  1109. return -1;
  1110. }
  1111. channel_topic = ast_channel_topic_all_cached();
  1112. if (!channel_topic) {
  1113. return -1;
  1114. }
  1115. topic_forwarder = stasis_forward_all(channel_topic, manager_topic);
  1116. if (!topic_forwarder) {
  1117. return -1;
  1118. }
  1119. ast_register_cleanup(manager_channels_shutdown);
  1120. /* The snapshot type has a special handler as it can result in multiple
  1121. * manager events being queued due to aspects of the snapshot itself
  1122. * changing.
  1123. */
  1124. ret |= stasis_message_router_add_cache_update(message_router,
  1125. ast_channel_snapshot_type(), channel_snapshot_update, NULL);
  1126. ret |= stasis_message_router_add(message_router,
  1127. ast_channel_dtmf_begin_type(), channel_dtmf_begin_cb, NULL);
  1128. ret |= stasis_message_router_add(message_router,
  1129. ast_channel_dtmf_end_type(), channel_dtmf_end_cb, NULL);
  1130. ret |= stasis_message_router_add(message_router,
  1131. ast_channel_hangup_request_type(), channel_hangup_request_cb,
  1132. NULL);
  1133. ret |= stasis_message_router_add(message_router,
  1134. ast_channel_dial_type(), channel_dial_cb, NULL);
  1135. ret |= stasis_message_router_add(message_router,
  1136. ast_channel_hold_type(), channel_hold_cb, NULL);
  1137. ret |= stasis_message_router_add(message_router,
  1138. ast_channel_unhold_type(), channel_unhold_cb, NULL);
  1139. ret |= stasis_message_router_add(message_router,
  1140. ast_channel_fax_type(), channel_fax_cb, NULL);
  1141. ret |= stasis_message_router_add(message_router,
  1142. ast_channel_chanspy_start_type(), channel_chanspy_start_cb,
  1143. NULL);
  1144. ret |= stasis_message_router_add(message_router,
  1145. ast_channel_chanspy_stop_type(), channel_chanspy_stop_cb, NULL);
  1146. ret |= stasis_message_router_add(message_router,
  1147. ast_channel_hangup_handler_type(), channel_hangup_handler_cb,
  1148. NULL);
  1149. ret |= stasis_message_router_add(message_router,
  1150. ast_channel_moh_start_type(), channel_moh_start_cb, NULL);
  1151. ret |= stasis_message_router_add(message_router,
  1152. ast_channel_moh_stop_type(), channel_moh_stop_cb, NULL);
  1153. ret |= stasis_message_router_add(message_router,
  1154. ast_channel_monitor_start_type(), channel_monitor_start_cb,
  1155. NULL);
  1156. ret |= stasis_message_router_add(message_router,
  1157. ast_channel_monitor_stop_type(), channel_monitor_stop_cb, NULL);
  1158. /* If somehow we failed to add any routes, just shut down the whole
  1159. * thing and fail it.
  1160. */
  1161. if (ret) {
  1162. manager_channels_shutdown();
  1163. return -1;
  1164. }
  1165. return 0;
  1166. }