stasis_channels.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Matt Jordan <mjordan@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 Stasis Messages and Data Types for Channel Objects
  21. *
  22. * \author \verbatim Matt Jordan <mjordan@digium.com> \endverbatim
  23. *
  24. */
  25. /*** MODULEINFO
  26. <support_level>core</support_level>
  27. ***/
  28. #include "asterisk.h"
  29. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  30. #include "asterisk/astobj2.h"
  31. #include "asterisk/json.h"
  32. #include "asterisk/pbx.h"
  33. #include "asterisk/bridge.h"
  34. #include "asterisk/translate.h"
  35. #include "asterisk/stasis.h"
  36. #include "asterisk/stasis_cache_pattern.h"
  37. #include "asterisk/stasis_channels.h"
  38. #include "asterisk/dial.h"
  39. #include "asterisk/linkedlists.h"
  40. /*** DOCUMENTATION
  41. <managerEvent language="en_US" name="VarSet">
  42. <managerEventInstance class="EVENT_FLAG_DIALPLAN">
  43. <synopsis>Raised when a variable is set to a particular value.</synopsis>
  44. <syntax>
  45. <channel_snapshot/>
  46. <parameter name="Variable">
  47. <para>The variable being set.</para>
  48. </parameter>
  49. <parameter name="Value">
  50. <para>The new value of the variable.</para>
  51. </parameter>
  52. </syntax>
  53. </managerEventInstance>
  54. </managerEvent>
  55. <managerEvent language="en_US" name="AgentLogin">
  56. <managerEventInstance class="EVENT_FLAG_AGENT">
  57. <synopsis>Raised when an Agent has logged in.</synopsis>
  58. <syntax>
  59. <channel_snapshot/>
  60. <parameter name="Agent">
  61. <para>Agent ID of the agent.</para>
  62. </parameter>
  63. </syntax>
  64. <see-also>
  65. <ref type="application">AgentLogin</ref>
  66. <ref type="managerEvent">AgentLogoff</ref>
  67. </see-also>
  68. </managerEventInstance>
  69. </managerEvent>
  70. <managerEvent language="en_US" name="AgentLogoff">
  71. <managerEventInstance class="EVENT_FLAG_AGENT">
  72. <synopsis>Raised when an Agent has logged off.</synopsis>
  73. <syntax>
  74. <xi:include xpointer="xpointer(/docs/managerEvent[@name='AgentLogin']/managerEventInstance/syntax/parameter)" />
  75. <parameter name="Logintime">
  76. <para>The number of seconds the agent was logged in.</para>
  77. </parameter>
  78. </syntax>
  79. <see-also>
  80. <ref type="managerEvent">AgentLogin</ref>
  81. </see-also>
  82. </managerEventInstance>
  83. </managerEvent>
  84. <managerEvent language="en_US" name="ChannelTalkingStart">
  85. <managerEventInstance class="EVENT_FLAG_CLASS">
  86. <synopsis>Raised when talking is detected on a channel.</synopsis>
  87. <syntax>
  88. <channel_snapshot/>
  89. </syntax>
  90. <see-also>
  91. <ref type="function">TALK_DETECT</ref>
  92. <ref type="managerEvent">ChannelTalkingStop</ref>
  93. </see-also>
  94. </managerEventInstance>
  95. </managerEvent>
  96. <managerEvent language="en_US" name="ChannelTalkingStop">
  97. <managerEventInstance class="EVENT_FLAG_CLASS">
  98. <synopsis>Raised when talking is no longer detected on a channel.</synopsis>
  99. <syntax>
  100. <channel_snapshot/>
  101. <parameter name="Duration">
  102. <para>The length in time, in milliseconds, that talking was
  103. detected on the channel.</para>
  104. </parameter>
  105. </syntax>
  106. <see-also>
  107. <ref type="function">TALK_DETECT</ref>
  108. <ref type="managerEvent">ChannelTalkingStart</ref>
  109. </see-also>
  110. </managerEventInstance>
  111. </managerEvent>
  112. ***/
  113. #define NUM_MULTI_CHANNEL_BLOB_BUCKETS 7
  114. static struct stasis_cp_all *channel_cache_all;
  115. static struct stasis_cache *channel_cache_by_name;
  116. static struct stasis_caching_topic *channel_by_name_topic;
  117. struct stasis_cp_all *ast_channel_cache_all(void)
  118. {
  119. return channel_cache_all;
  120. }
  121. struct stasis_cache *ast_channel_cache(void)
  122. {
  123. return stasis_cp_all_cache(channel_cache_all);
  124. }
  125. struct stasis_topic *ast_channel_topic_all(void)
  126. {
  127. return stasis_cp_all_topic(channel_cache_all);
  128. }
  129. struct stasis_topic *ast_channel_topic_all_cached(void)
  130. {
  131. return stasis_cp_all_topic_cached(channel_cache_all);
  132. }
  133. struct stasis_cache *ast_channel_cache_by_name(void)
  134. {
  135. return channel_cache_by_name;
  136. }
  137. static const char *channel_snapshot_get_id(struct stasis_message *message)
  138. {
  139. struct ast_channel_snapshot *snapshot;
  140. if (ast_channel_snapshot_type() != stasis_message_type(message)) {
  141. return NULL;
  142. }
  143. snapshot = stasis_message_data(message);
  144. return snapshot->uniqueid;
  145. }
  146. static const char *channel_snapshot_get_name(struct stasis_message *message)
  147. {
  148. struct ast_channel_snapshot *snapshot;
  149. if (ast_channel_snapshot_type() != stasis_message_type(message)) {
  150. return NULL;
  151. }
  152. snapshot = stasis_message_data(message);
  153. return snapshot->name;
  154. }
  155. /*!
  156. * \internal
  157. * \brief Hash function for \ref ast_channel_snapshot objects
  158. */
  159. static int channel_snapshot_hash_cb(const void *obj, const int flags)
  160. {
  161. const struct ast_channel_snapshot *object = obj;
  162. const char *key;
  163. switch (flags & OBJ_SEARCH_MASK) {
  164. case OBJ_SEARCH_KEY:
  165. key = obj;
  166. break;
  167. case OBJ_SEARCH_OBJECT:
  168. key = object->name;
  169. break;
  170. default:
  171. ast_assert(0);
  172. return 0;
  173. }
  174. return ast_str_case_hash(key);
  175. }
  176. /*!
  177. * \internal
  178. * \brief Comparison function for \ref ast_channel_snapshot objects
  179. */
  180. static int channel_snapshot_cmp_cb(void *obj, void *arg, int flags)
  181. {
  182. const struct ast_channel_snapshot *object_left = obj;
  183. const struct ast_channel_snapshot *object_right = arg;
  184. const char *right_key = arg;
  185. int cmp;
  186. switch (flags & OBJ_SEARCH_MASK) {
  187. case OBJ_SEARCH_OBJECT:
  188. right_key = object_right->name;
  189. case OBJ_SEARCH_KEY:
  190. cmp = strcasecmp(object_left->name, right_key);
  191. break;
  192. case OBJ_SEARCH_PARTIAL_KEY:
  193. cmp = strncasecmp(object_left->name, right_key, strlen(right_key));
  194. break;
  195. default:
  196. cmp = 0;
  197. break;
  198. }
  199. if (cmp) {
  200. return 0;
  201. }
  202. return CMP_MATCH;
  203. }
  204. static void channel_snapshot_dtor(void *obj)
  205. {
  206. struct ast_channel_snapshot *snapshot = obj;
  207. ast_string_field_free_memory(snapshot);
  208. ao2_cleanup(snapshot->manager_vars);
  209. }
  210. struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
  211. {
  212. struct ast_channel_snapshot *snapshot;
  213. struct ast_bridge *bridge;
  214. /* no snapshots for dummy channels */
  215. if (!ast_channel_tech(chan)) {
  216. return NULL;
  217. }
  218. snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_dtor,
  219. AO2_ALLOC_OPT_LOCK_NOLOCK);
  220. if (!snapshot || ast_string_field_init(snapshot, 1024)) {
  221. ao2_cleanup(snapshot);
  222. return NULL;
  223. }
  224. ast_string_field_set(snapshot, name, ast_channel_name(chan));
  225. ast_string_field_set(snapshot, type, ast_channel_tech(chan)->type);
  226. ast_string_field_set(snapshot, accountcode, ast_channel_accountcode(chan));
  227. ast_string_field_set(snapshot, peeraccount, ast_channel_peeraccount(chan));
  228. ast_string_field_set(snapshot, userfield, ast_channel_userfield(chan));
  229. ast_string_field_set(snapshot, uniqueid, ast_channel_uniqueid(chan));
  230. ast_string_field_set(snapshot, linkedid, ast_channel_linkedid(chan));
  231. ast_string_field_set(snapshot, hangupsource, ast_channel_hangupsource(chan));
  232. if (ast_channel_appl(chan)) {
  233. ast_string_field_set(snapshot, appl, ast_channel_appl(chan));
  234. }
  235. if (ast_channel_data(chan)) {
  236. ast_string_field_set(snapshot, data, ast_channel_data(chan));
  237. }
  238. ast_string_field_set(snapshot, context, ast_channel_context(chan));
  239. ast_string_field_set(snapshot, exten, ast_channel_exten(chan));
  240. ast_string_field_set(snapshot, caller_name,
  241. S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""));
  242. ast_string_field_set(snapshot, caller_number,
  243. S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""));
  244. ast_string_field_set(snapshot, caller_subaddr,
  245. S_COR(ast_channel_caller(chan)->id.subaddress.valid, ast_channel_caller(chan)->id.subaddress.str, ""));
  246. ast_string_field_set(snapshot, caller_ani,
  247. S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, ""));
  248. ast_string_field_set(snapshot, caller_rdnis,
  249. S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""));
  250. ast_string_field_set(snapshot, caller_dnid,
  251. S_OR(ast_channel_dialed(chan)->number.str, ""));
  252. ast_string_field_set(snapshot, dialed_subaddr,
  253. S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, ""));
  254. ast_string_field_set(snapshot, connected_name,
  255. S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, ""));
  256. ast_string_field_set(snapshot, connected_number,
  257. S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, ""));
  258. ast_string_field_set(snapshot, language, ast_channel_language(chan));
  259. if ((bridge = ast_channel_get_bridge(chan))) {
  260. ast_string_field_set(snapshot, bridgeid, bridge->uniqueid);
  261. ao2_cleanup(bridge);
  262. }
  263. snapshot->creationtime = ast_channel_creationtime(chan);
  264. snapshot->state = ast_channel_state(chan);
  265. snapshot->priority = ast_channel_priority(chan);
  266. snapshot->amaflags = ast_channel_amaflags(chan);
  267. snapshot->hangupcause = ast_channel_hangupcause(chan);
  268. ast_copy_flags(&snapshot->flags, ast_channel_flags(chan), 0xFFFFFFFF);
  269. snapshot->caller_pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
  270. ast_set_flag(&snapshot->softhangup_flags, ast_channel_softhangup_internal_flag(chan));
  271. snapshot->manager_vars = ast_channel_get_manager_vars(chan);
  272. snapshot->tech_properties = ast_channel_tech(chan)->properties;
  273. return snapshot;
  274. }
  275. static void publish_message_for_channel_topics(struct stasis_message *message, struct ast_channel *chan)
  276. {
  277. if (chan) {
  278. stasis_publish(ast_channel_topic(chan), message);
  279. } else {
  280. stasis_publish(ast_channel_topic_all(), message);
  281. }
  282. }
  283. static void channel_blob_dtor(void *obj)
  284. {
  285. struct ast_channel_blob *event = obj;
  286. ao2_cleanup(event->snapshot);
  287. ast_json_unref(event->blob);
  288. }
  289. static void ast_channel_publish_dial_internal(struct ast_channel *caller,
  290. struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring,
  291. const char *dialstatus, const char *forward)
  292. {
  293. struct ast_multi_channel_blob *payload;
  294. struct stasis_message *msg;
  295. struct ast_json *blob;
  296. struct ast_channel_snapshot *peer_snapshot;
  297. if (!ast_channel_dial_type()) {
  298. return;
  299. }
  300. ast_assert(peer != NULL);
  301. blob = ast_json_pack("{s: s, s: s, s: s}",
  302. "dialstatus", S_OR(dialstatus, ""),
  303. "forward", S_OR(forward, ""),
  304. "dialstring", S_OR(dialstring, ""));
  305. if (!blob) {
  306. return;
  307. }
  308. payload = ast_multi_channel_blob_create(blob);
  309. ast_json_unref(blob);
  310. if (!payload) {
  311. return;
  312. }
  313. if (caller) {
  314. struct ast_channel_snapshot *caller_snapshot;
  315. ast_channel_lock(caller);
  316. if (ast_strlen_zero(dialstatus)) {
  317. caller_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(caller));
  318. } else {
  319. caller_snapshot = ast_channel_snapshot_create(caller);
  320. }
  321. ast_channel_unlock(caller);
  322. if (!caller_snapshot) {
  323. ao2_ref(payload, -1);
  324. return;
  325. }
  326. ast_multi_channel_blob_add_channel(payload, "caller", caller_snapshot);
  327. ao2_ref(caller_snapshot, -1);
  328. }
  329. ast_channel_lock(peer);
  330. if (ast_strlen_zero(dialstatus)) {
  331. peer_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(peer));
  332. } else {
  333. peer_snapshot = ast_channel_snapshot_create(peer);
  334. }
  335. ast_channel_unlock(peer);
  336. if (!peer_snapshot) {
  337. ao2_ref(payload, -1);
  338. return;
  339. }
  340. ast_multi_channel_blob_add_channel(payload, "peer", peer_snapshot);
  341. ao2_ref(peer_snapshot, -1);
  342. if (forwarded) {
  343. struct ast_channel_snapshot *forwarded_snapshot;
  344. ast_channel_lock(forwarded);
  345. forwarded_snapshot = ast_channel_snapshot_create(forwarded);
  346. ast_channel_unlock(forwarded);
  347. if (!forwarded_snapshot) {
  348. ao2_ref(payload, -1);
  349. return;
  350. }
  351. ast_multi_channel_blob_add_channel(payload, "forwarded", forwarded_snapshot);
  352. ao2_ref(forwarded_snapshot, -1);
  353. }
  354. msg = stasis_message_create(ast_channel_dial_type(), payload);
  355. ao2_ref(payload, -1);
  356. if (msg) {
  357. publish_message_for_channel_topics(msg, caller);
  358. ao2_ref(msg, -1);
  359. }
  360. }
  361. static void remove_dial_masquerade(struct ast_channel *peer);
  362. static void remove_dial_masquerade_caller(struct ast_channel *caller);
  363. static int set_dial_masquerade(struct ast_channel *caller,
  364. struct ast_channel *peer, const char *dialstring);
  365. void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer,
  366. struct ast_channel *forwarded, const char *dialstring, const char *dialstatus,
  367. const char *forward)
  368. {
  369. ast_assert(peer != NULL);
  370. /* XXX With an early bridge the below dial masquerade datastore code could, theoretically,
  371. * go away as the act of changing the channel during dialing would be done using the bridge
  372. * API itself and not a masquerade.
  373. */
  374. if (caller) {
  375. /*
  376. * Lock two or three channels.
  377. *
  378. * We need to hold the locks to hold off a potential masquerade
  379. * messing up the stasis dial event ordering.
  380. */
  381. for (;; ast_channel_unlock(caller), sched_yield()) {
  382. ast_channel_lock(caller);
  383. if (ast_channel_trylock(peer)) {
  384. continue;
  385. }
  386. if (forwarded && ast_channel_trylock(forwarded)) {
  387. ast_channel_unlock(peer);
  388. continue;
  389. }
  390. break;
  391. }
  392. if (ast_strlen_zero(dialstatus)) {
  393. set_dial_masquerade(caller, peer, dialstring);
  394. } else {
  395. remove_dial_masquerade(peer);
  396. }
  397. }
  398. ast_channel_publish_dial_internal(caller, peer, forwarded, dialstring, dialstatus,
  399. forward);
  400. if (caller) {
  401. if (forwarded) {
  402. ast_channel_unlock(forwarded);
  403. }
  404. ast_channel_unlock(peer);
  405. remove_dial_masquerade_caller(caller);
  406. ast_channel_unlock(caller);
  407. }
  408. }
  409. void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer,
  410. const char *dialstring, const char *dialstatus)
  411. {
  412. ast_channel_publish_dial_forward(caller, peer, NULL, dialstring, dialstatus, NULL);
  413. }
  414. static struct stasis_message *create_channel_blob_message(struct ast_channel_snapshot *snapshot,
  415. struct stasis_message_type *type,
  416. struct ast_json *blob)
  417. {
  418. struct stasis_message *msg;
  419. struct ast_channel_blob *obj;
  420. obj = ao2_alloc(sizeof(*obj), channel_blob_dtor);
  421. if (!obj) {
  422. return NULL;
  423. }
  424. if (snapshot) {
  425. obj->snapshot = snapshot;
  426. ao2_ref(obj->snapshot, +1);
  427. }
  428. if (!blob) {
  429. blob = ast_json_null();
  430. }
  431. obj->blob = ast_json_ref(blob);
  432. msg = stasis_message_create(type, obj);
  433. ao2_cleanup(obj);
  434. return msg;
  435. }
  436. struct stasis_message *ast_channel_blob_create_from_cache(const char *channel_id,
  437. struct stasis_message_type *type,
  438. struct ast_json *blob)
  439. {
  440. struct ast_channel_snapshot *snapshot;
  441. struct stasis_message *msg;
  442. if (!type) {
  443. return NULL;
  444. }
  445. snapshot = ast_channel_snapshot_get_latest(channel_id);
  446. msg = create_channel_blob_message(snapshot, type, blob);
  447. ao2_cleanup(snapshot);
  448. return msg;
  449. }
  450. struct stasis_message *ast_channel_blob_create(struct ast_channel *chan,
  451. struct stasis_message_type *type, struct ast_json *blob)
  452. {
  453. struct ast_channel_snapshot *snapshot;
  454. struct stasis_message *msg;
  455. if (!type) {
  456. return NULL;
  457. }
  458. snapshot = chan ? ast_channel_snapshot_create(chan) : NULL;
  459. msg = create_channel_blob_message(snapshot, type, blob);
  460. ao2_cleanup(snapshot);
  461. return msg;
  462. }
  463. /*! \brief A channel snapshot wrapper object used in \ref ast_multi_channel_blob objects */
  464. struct channel_role_snapshot {
  465. struct ast_channel_snapshot *snapshot; /*!< A channel snapshot */
  466. char role[0]; /*!< The role assigned to the channel */
  467. };
  468. /*! \brief A multi channel blob data structure for multi_channel_blob stasis messages */
  469. struct ast_multi_channel_blob {
  470. struct ao2_container *channel_snapshots; /*!< A container holding the snapshots */
  471. struct ast_json *blob; /*!< A blob of JSON data */
  472. };
  473. /*!
  474. * \internal
  475. * \brief Comparison function for \ref channel_role_snapshot objects
  476. */
  477. static int channel_role_cmp_cb(void *obj, void *arg, int flags)
  478. {
  479. const struct channel_role_snapshot *object_left = obj;
  480. const struct channel_role_snapshot *object_right = arg;
  481. const char *right_key = arg;
  482. int cmp;
  483. switch (flags & OBJ_SEARCH_MASK) {
  484. case OBJ_SEARCH_OBJECT:
  485. right_key = object_right->role;
  486. case OBJ_SEARCH_KEY:
  487. cmp = strcasecmp(object_left->role, right_key);
  488. break;
  489. case OBJ_SEARCH_PARTIAL_KEY:
  490. cmp = strncasecmp(object_left->role, right_key, strlen(right_key));
  491. break;
  492. default:
  493. cmp = 0;
  494. break;
  495. }
  496. if (cmp) {
  497. return 0;
  498. }
  499. return CMP_MATCH;
  500. }
  501. /*!
  502. * \internal
  503. * \brief Hash function for \ref channel_role_snapshot objects
  504. */
  505. static int channel_role_hash_cb(const void *obj, const int flags)
  506. {
  507. const struct channel_role_snapshot *object = obj;
  508. const char *key;
  509. switch (flags & OBJ_SEARCH_MASK) {
  510. case OBJ_SEARCH_KEY:
  511. key = obj;
  512. break;
  513. case OBJ_SEARCH_OBJECT:
  514. key = object->role;
  515. break;
  516. default:
  517. ast_assert(0);
  518. return 0;
  519. }
  520. return ast_str_case_hash(key);
  521. }
  522. /*!
  523. * \internal
  524. * \brief Destructor for \ref ast_multi_channel_blob objects
  525. */
  526. static void multi_channel_blob_dtor(void *obj)
  527. {
  528. struct ast_multi_channel_blob *multi_blob = obj;
  529. ao2_cleanup(multi_blob->channel_snapshots);
  530. ast_json_unref(multi_blob->blob);
  531. }
  532. struct ast_multi_channel_blob *ast_multi_channel_blob_create(struct ast_json *blob)
  533. {
  534. struct ast_multi_channel_blob *obj;
  535. ast_assert(blob != NULL);
  536. obj = ao2_alloc(sizeof(*obj), multi_channel_blob_dtor);
  537. if (!obj) {
  538. return NULL;
  539. }
  540. obj->channel_snapshots = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
  541. NUM_MULTI_CHANNEL_BLOB_BUCKETS, channel_role_hash_cb, NULL, channel_role_cmp_cb);
  542. if (!obj->channel_snapshots) {
  543. ao2_ref(obj, -1);
  544. return NULL;
  545. }
  546. obj->blob = ast_json_ref(blob);
  547. return obj;
  548. }
  549. struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniqueid)
  550. {
  551. struct stasis_message *message;
  552. struct ast_channel_snapshot *snapshot;
  553. ast_assert(!ast_strlen_zero(uniqueid));
  554. message = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(),
  555. uniqueid);
  556. if (!message) {
  557. return NULL;
  558. }
  559. snapshot = ao2_bump(stasis_message_data(message));
  560. ao2_ref(message, -1);
  561. return snapshot;
  562. }
  563. struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name)
  564. {
  565. struct stasis_message *message;
  566. struct ast_channel_snapshot *snapshot;
  567. ast_assert(!ast_strlen_zero(name));
  568. message = stasis_cache_get(ast_channel_cache_by_name(), ast_channel_snapshot_type(),
  569. name);
  570. if (!message) {
  571. return NULL;
  572. }
  573. snapshot = ao2_bump(stasis_message_data(message));
  574. ao2_ref(message, -1);
  575. return snapshot;
  576. }
  577. static void channel_role_snapshot_dtor(void *obj)
  578. {
  579. struct channel_role_snapshot *role_snapshot = obj;
  580. ao2_cleanup(role_snapshot->snapshot);
  581. }
  582. void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
  583. {
  584. struct channel_role_snapshot *role_snapshot;
  585. int role_len = strlen(role) + 1;
  586. if (!obj || ast_strlen_zero(role) || !snapshot) {
  587. return;
  588. }
  589. role_snapshot = ao2_alloc_options(sizeof(*role_snapshot) + role_len,
  590. channel_role_snapshot_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
  591. if (!role_snapshot) {
  592. return;
  593. }
  594. ast_copy_string(role_snapshot->role, role, role_len);
  595. role_snapshot->snapshot = snapshot;
  596. ao2_ref(role_snapshot->snapshot, +1);
  597. ao2_link(obj->channel_snapshots, role_snapshot);
  598. ao2_ref(role_snapshot, -1);
  599. }
  600. struct ast_channel_snapshot *ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
  601. {
  602. struct channel_role_snapshot *role_snapshot;
  603. struct ast_channel_snapshot *snapshot;
  604. if (!obj || ast_strlen_zero(role)) {
  605. return NULL;
  606. }
  607. role_snapshot = ao2_find(obj->channel_snapshots, role, OBJ_SEARCH_KEY);
  608. /* Note that this function does not increase the ref count on snapshot */
  609. if (!role_snapshot) {
  610. return NULL;
  611. }
  612. snapshot = role_snapshot->snapshot;
  613. ao2_ref(role_snapshot, -1);
  614. return snapshot;
  615. }
  616. struct ao2_container *ast_multi_channel_blob_get_channels(struct ast_multi_channel_blob *obj, const char *role)
  617. {
  618. struct ao2_container *ret_container;
  619. struct ao2_iterator *it_role_snapshots;
  620. struct channel_role_snapshot *role_snapshot;
  621. char *arg;
  622. if (!obj || ast_strlen_zero(role)) {
  623. return NULL;
  624. }
  625. ret_container = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
  626. NUM_MULTI_CHANNEL_BLOB_BUCKETS,
  627. channel_snapshot_hash_cb, NULL, channel_snapshot_cmp_cb);
  628. if (!ret_container) {
  629. return NULL;
  630. }
  631. arg = ast_strdupa(role);
  632. it_role_snapshots = ao2_callback(obj->channel_snapshots,
  633. OBJ_MULTIPLE | OBJ_SEARCH_KEY, channel_role_cmp_cb, arg);
  634. if (!it_role_snapshots) {
  635. ao2_ref(ret_container, -1);
  636. return NULL;
  637. }
  638. while ((role_snapshot = ao2_iterator_next(it_role_snapshots))) {
  639. ao2_link(ret_container, role_snapshot->snapshot);
  640. ao2_ref(role_snapshot, -1);
  641. }
  642. ao2_iterator_destroy(it_role_snapshots);
  643. return ret_container;
  644. }
  645. struct ast_json *ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *obj)
  646. {
  647. if (!obj) {
  648. return NULL;
  649. }
  650. return obj->blob;
  651. }
  652. void ast_channel_stage_snapshot(struct ast_channel *chan)
  653. {
  654. ast_set_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE);
  655. }
  656. void ast_channel_stage_snapshot_done(struct ast_channel *chan)
  657. {
  658. ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE);
  659. ast_channel_publish_snapshot(chan);
  660. }
  661. void ast_channel_publish_snapshot(struct ast_channel *chan)
  662. {
  663. struct ast_channel_snapshot *snapshot;
  664. struct stasis_message *message;
  665. if (!ast_channel_snapshot_type()) {
  666. return;
  667. }
  668. if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE)) {
  669. return;
  670. }
  671. snapshot = ast_channel_snapshot_create(chan);
  672. if (!snapshot) {
  673. return;
  674. }
  675. message = stasis_message_create(ast_channel_snapshot_type(), snapshot);
  676. ao2_ref(snapshot, -1);
  677. if (!message) {
  678. return;
  679. }
  680. ast_assert(ast_channel_topic(chan) != NULL);
  681. stasis_publish(ast_channel_topic(chan), message);
  682. ao2_ref(message, -1);
  683. }
  684. void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
  685. {
  686. struct stasis_message *message;
  687. if (!blob) {
  688. blob = ast_json_null();
  689. }
  690. message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), type, blob);
  691. if (message) {
  692. stasis_publish(ast_channel_topic(chan), message);
  693. ao2_ref(message, -1);
  694. }
  695. }
  696. void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
  697. {
  698. struct stasis_message *message;
  699. if (!blob) {
  700. blob = ast_json_null();
  701. }
  702. message = ast_channel_blob_create(chan, type, blob);
  703. if (message) {
  704. stasis_publish(ast_channel_topic(chan), message);
  705. ao2_ref(message, -1);
  706. }
  707. }
  708. void ast_channel_publish_varset(struct ast_channel *chan, const char *name, const char *value)
  709. {
  710. struct ast_json *blob;
  711. ast_assert(name != NULL);
  712. ast_assert(value != NULL);
  713. blob = ast_json_pack("{s: s, s: s}",
  714. "variable", name,
  715. "value", value);
  716. if (!blob) {
  717. ast_log(LOG_ERROR, "Error creating message\n");
  718. return;
  719. }
  720. /*! If there are manager variables, force a cache update */
  721. if (chan && ast_channel_has_manager_vars()) {
  722. ast_channel_publish_snapshot(chan);
  723. }
  724. if (chan) {
  725. ast_channel_publish_cached_blob(chan, ast_channel_varset_type(), blob);
  726. } else {
  727. /* This function is NULL safe for global variables */
  728. ast_channel_publish_blob(NULL, ast_channel_varset_type(), blob);
  729. }
  730. ast_json_unref(blob);
  731. }
  732. static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg)
  733. {
  734. struct ast_str *channel_event_string;
  735. struct ast_channel_blob *obj = stasis_message_data(msg);
  736. const char *variable =
  737. ast_json_string_get(ast_json_object_get(obj->blob, "variable"));
  738. char *value;
  739. struct ast_manager_event_blob *ev;
  740. value = ast_escape_c_alloc(ast_json_string_get(ast_json_object_get(obj->blob,
  741. "value")));
  742. if (!value) {
  743. return NULL;
  744. }
  745. if (obj->snapshot) {
  746. channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
  747. } else {
  748. channel_event_string = ast_str_create(35);
  749. ast_str_set(&channel_event_string, 0,
  750. "Channel: none\r\n"
  751. "Uniqueid: none\r\n");
  752. }
  753. if (!channel_event_string) {
  754. ast_free(value);
  755. return NULL;
  756. }
  757. ev = ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet",
  758. "%s"
  759. "Variable: %s\r\n"
  760. "Value: %s\r\n",
  761. ast_str_buffer(channel_event_string), variable, value);
  762. ast_free(channel_event_string);
  763. ast_free(value);
  764. return ev;
  765. }
  766. static struct ast_manager_event_blob *agent_login_to_ami(struct stasis_message *msg)
  767. {
  768. struct ast_str *channel_string;
  769. struct ast_channel_blob *obj = stasis_message_data(msg);
  770. const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
  771. struct ast_manager_event_blob *ev;
  772. channel_string = ast_manager_build_channel_state_string(obj->snapshot);
  773. if (!channel_string) {
  774. return NULL;
  775. }
  776. ev = ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogin",
  777. "%s"
  778. "Agent: %s\r\n",
  779. ast_str_buffer(channel_string), agent);
  780. ast_free(channel_string);
  781. return ev;
  782. }
  783. static struct ast_manager_event_blob *agent_logoff_to_ami(struct stasis_message *msg)
  784. {
  785. struct ast_str *channel_string;
  786. struct ast_channel_blob *obj = stasis_message_data(msg);
  787. const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
  788. long logintime = ast_json_integer_get(ast_json_object_get(obj->blob, "logintime"));
  789. struct ast_manager_event_blob *ev;
  790. channel_string = ast_manager_build_channel_state_string(obj->snapshot);
  791. if (!channel_string) {
  792. return NULL;
  793. }
  794. ev = ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogoff",
  795. "%s"
  796. "Agent: %s\r\n"
  797. "Logintime: %ld\r\n",
  798. ast_str_buffer(channel_string), agent, logintime);
  799. ast_free(channel_string);
  800. return ev;
  801. }
  802. void ast_publish_channel_state(struct ast_channel *chan)
  803. {
  804. struct ast_channel_snapshot *snapshot;
  805. struct stasis_message *message;
  806. if (!ast_channel_snapshot_type()) {
  807. return;
  808. }
  809. ast_assert(chan != NULL);
  810. if (!chan) {
  811. return;
  812. }
  813. snapshot = ast_channel_snapshot_create(chan);
  814. if (!snapshot) {
  815. return;
  816. }
  817. message = stasis_message_create(ast_channel_snapshot_type(), snapshot);
  818. ao2_ref(snapshot, -1);
  819. if (!message) {
  820. return;
  821. }
  822. ast_assert(ast_channel_topic(chan) != NULL);
  823. stasis_publish(ast_channel_topic(chan), message);
  824. ao2_ref(message, -1);
  825. }
  826. struct ast_json *ast_channel_snapshot_to_json(
  827. const struct ast_channel_snapshot *snapshot,
  828. const struct stasis_message_sanitizer *sanitize)
  829. {
  830. struct ast_json *json_chan;
  831. if (snapshot == NULL
  832. || (sanitize
  833. && sanitize->channel_snapshot
  834. && sanitize->channel_snapshot(snapshot))) {
  835. return NULL;
  836. }
  837. json_chan = ast_json_pack(
  838. /* Broken up into groups of three for readability */
  839. "{ s: s, s: s, s: s,"
  840. " s: o, s: o, s: s,"
  841. " s: o, s: o, s: s }",
  842. /* First line */
  843. "id", snapshot->uniqueid,
  844. "name", snapshot->name,
  845. "state", ast_state2str(snapshot->state),
  846. /* Second line */
  847. "caller", ast_json_name_number(
  848. snapshot->caller_name, snapshot->caller_number),
  849. "connected", ast_json_name_number(
  850. snapshot->connected_name, snapshot->connected_number),
  851. "accountcode", snapshot->accountcode,
  852. /* Third line */
  853. "dialplan", ast_json_dialplan_cep(
  854. snapshot->context, snapshot->exten, snapshot->priority),
  855. "creationtime", ast_json_timeval(snapshot->creationtime, NULL),
  856. "language", snapshot->language);
  857. return json_chan;
  858. }
  859. int ast_channel_snapshot_cep_equal(
  860. const struct ast_channel_snapshot *old_snapshot,
  861. const struct ast_channel_snapshot *new_snapshot)
  862. {
  863. ast_assert(old_snapshot != NULL);
  864. ast_assert(new_snapshot != NULL);
  865. /* We actually get some snapshots with CEP set, but before the
  866. * application is set. Since empty application is invalid, we treat
  867. * setting the application from nothing as a CEP change.
  868. */
  869. if (ast_strlen_zero(old_snapshot->appl) &&
  870. !ast_strlen_zero(new_snapshot->appl)) {
  871. return 0;
  872. }
  873. return old_snapshot->priority == new_snapshot->priority &&
  874. strcmp(old_snapshot->context, new_snapshot->context) == 0 &&
  875. strcmp(old_snapshot->exten, new_snapshot->exten) == 0;
  876. }
  877. int ast_channel_snapshot_caller_id_equal(
  878. const struct ast_channel_snapshot *old_snapshot,
  879. const struct ast_channel_snapshot *new_snapshot)
  880. {
  881. ast_assert(old_snapshot != NULL);
  882. ast_assert(new_snapshot != NULL);
  883. return strcmp(old_snapshot->caller_number, new_snapshot->caller_number) == 0 &&
  884. strcmp(old_snapshot->caller_name, new_snapshot->caller_name) == 0;
  885. }
  886. int ast_channel_snapshot_connected_line_equal(
  887. const struct ast_channel_snapshot *old_snapshot,
  888. const struct ast_channel_snapshot *new_snapshot)
  889. {
  890. ast_assert(old_snapshot != NULL);
  891. ast_assert(new_snapshot != NULL);
  892. return strcmp(old_snapshot->connected_number, new_snapshot->connected_number) == 0 &&
  893. strcmp(old_snapshot->connected_name, new_snapshot->connected_name) == 0;
  894. }
  895. static struct ast_json *channel_blob_to_json(
  896. struct stasis_message *message,
  897. const char *type,
  898. const struct stasis_message_sanitizer *sanitize)
  899. {
  900. struct ast_json *to_json;
  901. struct ast_channel_blob *channel_blob = stasis_message_data(message);
  902. struct ast_json *blob = channel_blob->blob;
  903. struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
  904. const struct timeval *tv = stasis_message_timestamp(message);
  905. int res = 0;
  906. if (blob == NULL || ast_json_is_null(blob)) {
  907. to_json = ast_json_object_create();
  908. } else {
  909. /* blobs are immutable, so shallow copies are fine */
  910. to_json = ast_json_copy(blob);
  911. }
  912. if (!to_json) {
  913. return NULL;
  914. }
  915. res |= ast_json_object_set(to_json, "type", ast_json_string_create(type));
  916. res |= ast_json_object_set(to_json, "timestamp",
  917. ast_json_timeval(*tv, NULL));
  918. /* For global channel messages, the snapshot is optional */
  919. if (snapshot) {
  920. struct ast_json *json_channel;
  921. json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
  922. if (!json_channel) {
  923. ast_json_unref(to_json);
  924. return NULL;
  925. }
  926. res |= ast_json_object_set(to_json, "channel", json_channel);
  927. }
  928. if (res != 0) {
  929. ast_json_unref(to_json);
  930. return NULL;
  931. }
  932. return to_json;
  933. }
  934. static struct ast_json *dtmf_end_to_json(
  935. struct stasis_message *message,
  936. const struct stasis_message_sanitizer *sanitize)
  937. {
  938. struct ast_channel_blob *channel_blob = stasis_message_data(message);
  939. struct ast_json *blob = channel_blob->blob;
  940. struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
  941. const char *direction =
  942. ast_json_string_get(ast_json_object_get(blob, "direction"));
  943. const char *digit =
  944. ast_json_string_get(ast_json_object_get(blob, "digit"));
  945. long duration_ms =
  946. ast_json_integer_get(ast_json_object_get(blob, "duration_ms"));
  947. const struct timeval *tv = stasis_message_timestamp(message);
  948. struct ast_json *json_channel;
  949. /* Only present received DTMF end events as JSON */
  950. if (strcasecmp("Received", direction) != 0) {
  951. return NULL;
  952. }
  953. json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
  954. if (!json_channel) {
  955. return NULL;
  956. }
  957. return ast_json_pack("{s: s, s: o, s: s, s: i, s: o}",
  958. "type", "ChannelDtmfReceived",
  959. "timestamp", ast_json_timeval(*tv, NULL),
  960. "digit", digit,
  961. "duration_ms", duration_ms,
  962. "channel", json_channel);
  963. }
  964. static struct ast_json *varset_to_json(
  965. struct stasis_message *message,
  966. const struct stasis_message_sanitizer *sanitize)
  967. {
  968. return channel_blob_to_json(message, "ChannelVarset", sanitize);
  969. }
  970. static struct ast_json *hangup_request_to_json(
  971. struct stasis_message *message,
  972. const struct stasis_message_sanitizer *sanitize)
  973. {
  974. return channel_blob_to_json(message, "ChannelHangupRequest", sanitize);
  975. }
  976. static struct ast_json *dial_to_json(
  977. struct stasis_message *message,
  978. const struct stasis_message_sanitizer *sanitize)
  979. {
  980. struct ast_multi_channel_blob *payload = stasis_message_data(message);
  981. struct ast_json *blob = ast_multi_channel_blob_get_json(payload);
  982. const char *dialstatus =
  983. ast_json_string_get(ast_json_object_get(blob, "dialstatus"));
  984. const char *forward =
  985. ast_json_string_get(ast_json_object_get(blob, "forward"));
  986. const char *dialstring =
  987. ast_json_string_get(ast_json_object_get(blob, "dialstring"));
  988. struct ast_json *caller_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "caller"), sanitize);
  989. struct ast_json *peer_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "peer"), sanitize);
  990. struct ast_json *forwarded_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "forwarded"), sanitize);
  991. struct ast_json *json;
  992. const struct timeval *tv = stasis_message_timestamp(message);
  993. int res = 0;
  994. json = ast_json_pack("{s: s, s: o, s: s, s: s, s: s}",
  995. "type", "Dial",
  996. "timestamp", ast_json_timeval(*tv, NULL),
  997. "dialstatus", dialstatus,
  998. "forward", forward,
  999. "dialstring", dialstring);
  1000. if (!json) {
  1001. ast_json_unref(caller_json);
  1002. ast_json_unref(peer_json);
  1003. ast_json_unref(forwarded_json);
  1004. return NULL;
  1005. }
  1006. if (caller_json) {
  1007. res |= ast_json_object_set(json, "caller", caller_json);
  1008. }
  1009. if (peer_json) {
  1010. res |= ast_json_object_set(json, "peer", peer_json);
  1011. }
  1012. if (forwarded_json) {
  1013. res |= ast_json_object_set(json, "forwarded", forwarded_json);
  1014. }
  1015. if (res) {
  1016. ast_json_unref(json);
  1017. return NULL;
  1018. }
  1019. return json;
  1020. }
  1021. static struct ast_manager_event_blob *talking_start_to_ami(struct stasis_message *msg)
  1022. {
  1023. struct ast_str *channel_string;
  1024. struct ast_channel_blob *obj = stasis_message_data(msg);
  1025. struct ast_manager_event_blob *blob;
  1026. channel_string = ast_manager_build_channel_state_string(obj->snapshot);
  1027. if (!channel_string) {
  1028. return NULL;
  1029. }
  1030. blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStart",
  1031. "%s", ast_str_buffer(channel_string));
  1032. ast_free(channel_string);
  1033. return blob;
  1034. }
  1035. static struct ast_json *talking_start_to_json(struct stasis_message *message,
  1036. const struct stasis_message_sanitizer *sanitize)
  1037. {
  1038. return channel_blob_to_json(message, "ChannelTalkingStarted", sanitize);
  1039. }
  1040. static struct ast_manager_event_blob *talking_stop_to_ami(struct stasis_message *msg)
  1041. {
  1042. struct ast_str *channel_string;
  1043. struct ast_channel_blob *obj = stasis_message_data(msg);
  1044. int duration = ast_json_integer_get(ast_json_object_get(obj->blob, "duration"));
  1045. struct ast_manager_event_blob *blob;
  1046. channel_string = ast_manager_build_channel_state_string(obj->snapshot);
  1047. if (!channel_string) {
  1048. return NULL;
  1049. }
  1050. blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStop",
  1051. "%s"
  1052. "Duration: %d\r\n",
  1053. ast_str_buffer(channel_string),
  1054. duration);
  1055. ast_free(channel_string);
  1056. return blob;
  1057. }
  1058. static struct ast_json *talking_stop_to_json(struct stasis_message *message,
  1059. const struct stasis_message_sanitizer *sanitize)
  1060. {
  1061. return channel_blob_to_json(message, "ChannelTalkingFinished", sanitize);
  1062. }
  1063. static struct ast_json *hold_to_json(struct stasis_message *message,
  1064. const struct stasis_message_sanitizer *sanitize)
  1065. {
  1066. struct ast_channel_blob *channel_blob = stasis_message_data(message);
  1067. struct ast_json *blob = channel_blob->blob;
  1068. struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
  1069. const char *musicclass = ast_json_string_get(ast_json_object_get(blob, "musicclass"));
  1070. const struct timeval *tv = stasis_message_timestamp(message);
  1071. struct ast_json *json_channel;
  1072. json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
  1073. if (!json_channel) {
  1074. return NULL;
  1075. }
  1076. return ast_json_pack("{s: s, s: o, s: s, s: o}",
  1077. "type", "ChannelHold",
  1078. "timestamp", ast_json_timeval(*tv, NULL),
  1079. "musicclass", S_OR(musicclass, "N/A"),
  1080. "channel", json_channel);
  1081. }
  1082. static struct ast_json *unhold_to_json(struct stasis_message *message,
  1083. const struct stasis_message_sanitizer *sanitize)
  1084. {
  1085. struct ast_channel_blob *channel_blob = stasis_message_data(message);
  1086. struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
  1087. const struct timeval *tv = stasis_message_timestamp(message);
  1088. struct ast_json *json_channel;
  1089. json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
  1090. if (!json_channel) {
  1091. return NULL;
  1092. }
  1093. return ast_json_pack("{s: s, s: o, s: o}",
  1094. "type", "ChannelUnhold",
  1095. "timestamp", ast_json_timeval(*tv, NULL),
  1096. "channel", json_channel);
  1097. }
  1098. /*!
  1099. * @{ \brief Define channel message types.
  1100. */
  1101. STASIS_MESSAGE_TYPE_DEFN(ast_channel_snapshot_type);
  1102. STASIS_MESSAGE_TYPE_DEFN(ast_channel_dial_type,
  1103. .to_json = dial_to_json,
  1104. );
  1105. STASIS_MESSAGE_TYPE_DEFN(ast_channel_varset_type,
  1106. .to_ami = varset_to_ami,
  1107. .to_json = varset_to_json,
  1108. );
  1109. STASIS_MESSAGE_TYPE_DEFN(ast_channel_hangup_request_type,
  1110. .to_json = hangup_request_to_json,
  1111. );
  1112. STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_begin_type);
  1113. STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_end_type,
  1114. .to_json = dtmf_end_to_json,
  1115. );
  1116. STASIS_MESSAGE_TYPE_DEFN(ast_channel_hold_type,
  1117. .to_json = hold_to_json,
  1118. );
  1119. STASIS_MESSAGE_TYPE_DEFN(ast_channel_unhold_type,
  1120. .to_json = unhold_to_json,
  1121. );
  1122. STASIS_MESSAGE_TYPE_DEFN(ast_channel_chanspy_start_type);
  1123. STASIS_MESSAGE_TYPE_DEFN(ast_channel_chanspy_stop_type);
  1124. STASIS_MESSAGE_TYPE_DEFN(ast_channel_fax_type);
  1125. STASIS_MESSAGE_TYPE_DEFN(ast_channel_hangup_handler_type);
  1126. STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_start_type);
  1127. STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_stop_type);
  1128. STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_start_type);
  1129. STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_stop_type);
  1130. STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_login_type,
  1131. .to_ami = agent_login_to_ami,
  1132. );
  1133. STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_logoff_type,
  1134. .to_ami = agent_logoff_to_ami,
  1135. );
  1136. STASIS_MESSAGE_TYPE_DEFN(ast_channel_talking_start,
  1137. .to_ami = talking_start_to_ami,
  1138. .to_json = talking_start_to_json,
  1139. );
  1140. STASIS_MESSAGE_TYPE_DEFN(ast_channel_talking_stop,
  1141. .to_ami = talking_stop_to_ami,
  1142. .to_json = talking_stop_to_json,
  1143. );
  1144. /*! @} */
  1145. static void stasis_channels_cleanup(void)
  1146. {
  1147. stasis_caching_unsubscribe_and_join(channel_by_name_topic);
  1148. channel_by_name_topic = NULL;
  1149. ao2_cleanup(channel_cache_by_name);
  1150. channel_cache_by_name = NULL;
  1151. ao2_cleanup(channel_cache_all);
  1152. channel_cache_all = NULL;
  1153. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_snapshot_type);
  1154. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_dial_type);
  1155. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_varset_type);
  1156. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_hangup_request_type);
  1157. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_dtmf_begin_type);
  1158. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_dtmf_end_type);
  1159. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_hold_type);
  1160. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_unhold_type);
  1161. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_chanspy_start_type);
  1162. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_chanspy_stop_type);
  1163. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_fax_type);
  1164. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_hangup_handler_type);
  1165. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_moh_start_type);
  1166. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_moh_stop_type);
  1167. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_start_type);
  1168. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_stop_type);
  1169. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_login_type);
  1170. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_logoff_type);
  1171. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_talking_start);
  1172. STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_talking_stop);
  1173. }
  1174. int ast_stasis_channels_init(void)
  1175. {
  1176. int res = 0;
  1177. ast_register_cleanup(stasis_channels_cleanup);
  1178. channel_cache_all = stasis_cp_all_create("ast_channel_topic_all",
  1179. channel_snapshot_get_id);
  1180. if (!channel_cache_all) {
  1181. return -1;
  1182. }
  1183. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_agent_login_type);
  1184. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_agent_logoff_type);
  1185. channel_cache_by_name = stasis_cache_create(channel_snapshot_get_name);
  1186. if (!channel_cache_by_name) {
  1187. return -1;
  1188. }
  1189. /* This should be initialized before the caching topic */
  1190. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_snapshot_type);
  1191. channel_by_name_topic = stasis_caching_topic_create(
  1192. stasis_cp_all_topic(channel_cache_all),
  1193. channel_cache_by_name);
  1194. if (!channel_by_name_topic) {
  1195. return -1;
  1196. }
  1197. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_dial_type);
  1198. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_varset_type);
  1199. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_hangup_request_type);
  1200. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_dtmf_begin_type);
  1201. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_dtmf_end_type);
  1202. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_hold_type);
  1203. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_unhold_type);
  1204. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_chanspy_start_type);
  1205. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_chanspy_stop_type);
  1206. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_fax_type);
  1207. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_hangup_handler_type);
  1208. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_start_type);
  1209. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_stop_type);
  1210. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_start_type);
  1211. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_stop_type);
  1212. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_talking_start);
  1213. res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_talking_stop);
  1214. return res;
  1215. }
  1216. /*!
  1217. * \internal
  1218. * \brief A list element for the dial_masquerade_datastore -- stores data about a dialed peer
  1219. */
  1220. struct dial_target {
  1221. /*! Called party channel. */
  1222. struct ast_channel *peer;
  1223. /*! Dialstring used to call the peer. */
  1224. char *dialstring;
  1225. /*! Next entry in the list. */
  1226. AST_LIST_ENTRY(dial_target) list;
  1227. };
  1228. static void dial_target_free(struct dial_target *doomed)
  1229. {
  1230. if (!doomed) {
  1231. return;
  1232. }
  1233. ast_free(doomed->dialstring);
  1234. ast_channel_cleanup(doomed->peer);
  1235. ast_free(doomed);
  1236. }
  1237. /*!
  1238. * \internal
  1239. * \brief Datastore used for advancing dial state in the case of a masquerade
  1240. * against a channel in the process of dialing.
  1241. */
  1242. struct dial_masquerade_datastore {
  1243. /*! Calling party channel. */
  1244. struct ast_channel *caller;
  1245. /*! List of called peers. */
  1246. AST_LIST_HEAD_NOLOCK(, dial_target) dialed_peers;
  1247. };
  1248. static void dial_masquerade_datastore_cleanup(struct dial_masquerade_datastore *masq_data)
  1249. {
  1250. struct dial_target *cur;
  1251. while ((cur = AST_LIST_REMOVE_HEAD(&masq_data->dialed_peers, list))) {
  1252. dial_target_free(cur);
  1253. }
  1254. }
  1255. static void dial_masquerade_datastore_remove_chan(struct dial_masquerade_datastore *masq_data, struct ast_channel *chan)
  1256. {
  1257. struct dial_target *cur;
  1258. ao2_lock(masq_data);
  1259. if (masq_data->caller == chan) {
  1260. dial_masquerade_datastore_cleanup(masq_data);
  1261. } else {
  1262. AST_LIST_TRAVERSE_SAFE_BEGIN(&masq_data->dialed_peers, cur, list) {
  1263. if (cur->peer == chan) {
  1264. AST_LIST_REMOVE_CURRENT(list);
  1265. dial_target_free(cur);
  1266. break;
  1267. }
  1268. }
  1269. AST_LIST_TRAVERSE_SAFE_END;
  1270. }
  1271. ao2_unlock(masq_data);
  1272. }
  1273. static void dial_masquerade_datastore_dtor(void *vdoomed)
  1274. {
  1275. dial_masquerade_datastore_cleanup(vdoomed);
  1276. }
  1277. static struct dial_masquerade_datastore *dial_masquerade_datastore_alloc(void)
  1278. {
  1279. struct dial_masquerade_datastore *masq_data;
  1280. masq_data = ao2_alloc(sizeof(struct dial_masquerade_datastore),
  1281. dial_masquerade_datastore_dtor);
  1282. if (!masq_data) {
  1283. return NULL;
  1284. }
  1285. AST_LIST_HEAD_INIT_NOLOCK(&masq_data->dialed_peers);
  1286. return masq_data;
  1287. }
  1288. /*!
  1289. * \internal
  1290. * \brief Datastore destructor for dial_masquerade_datastore
  1291. */
  1292. static void dial_masquerade_datastore_destroy(void *data)
  1293. {
  1294. ao2_ref(data, -1);
  1295. }
  1296. /*!
  1297. * \internal
  1298. * \brief Datastore destructor for dial_masquerade_datastore
  1299. */
  1300. static void dial_masquerade_caller_datastore_destroy(void *data)
  1301. {
  1302. dial_masquerade_datastore_cleanup(data);
  1303. ao2_ref(data, -1);
  1304. }
  1305. static struct ast_datastore *dial_masquerade_datastore_find(struct ast_channel *chan);
  1306. static void dial_masquerade_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
  1307. {
  1308. struct dial_masquerade_datastore *masq_data = data;
  1309. struct dial_target *cur;
  1310. struct ast_datastore *datastore;
  1311. ao2_lock(masq_data);
  1312. if (!masq_data->caller) {
  1313. /* Nothing to do but remove the datastore */
  1314. } else if (masq_data->caller == old_chan) {
  1315. /* The caller channel is being masqueraded out. */
  1316. ast_debug(1, "Caller channel %s being masqueraded out to %s (is_empty:%d)\n",
  1317. ast_channel_name(new_chan), ast_channel_name(old_chan),
  1318. AST_LIST_EMPTY(&masq_data->dialed_peers));
  1319. AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
  1320. ast_channel_publish_dial_internal(new_chan, cur->peer, NULL,
  1321. cur->dialstring, "NOANSWER", NULL);
  1322. ast_channel_publish_dial_internal(old_chan, cur->peer, NULL,
  1323. cur->dialstring, NULL, NULL);
  1324. }
  1325. dial_masquerade_datastore_cleanup(masq_data);
  1326. } else {
  1327. /* One of the peer channels is being masqueraded out. */
  1328. AST_LIST_TRAVERSE_SAFE_BEGIN(&masq_data->dialed_peers, cur, list) {
  1329. if (cur->peer == old_chan) {
  1330. ast_debug(1, "Peer channel %s being masqueraded out to %s\n",
  1331. ast_channel_name(new_chan), ast_channel_name(old_chan));
  1332. ast_channel_publish_dial_internal(masq_data->caller, new_chan, NULL,
  1333. cur->dialstring, "CANCEL", NULL);
  1334. ast_channel_publish_dial_internal(masq_data->caller, old_chan, NULL,
  1335. cur->dialstring, NULL, NULL);
  1336. AST_LIST_REMOVE_CURRENT(list);
  1337. dial_target_free(cur);
  1338. break;
  1339. }
  1340. }
  1341. AST_LIST_TRAVERSE_SAFE_END;
  1342. }
  1343. ao2_unlock(masq_data);
  1344. /* Remove the datastore from the channel. */
  1345. datastore = dial_masquerade_datastore_find(old_chan);
  1346. if (!datastore) {
  1347. return;
  1348. }
  1349. ast_channel_datastore_remove(old_chan, datastore);
  1350. ast_datastore_free(datastore);
  1351. }
  1352. /*!
  1353. * \internal
  1354. * \brief Primary purpose for dial_masquerade_datastore, publishes
  1355. * the channel dial event needed to set the incoming channel into the
  1356. * dial state during a masquerade.
  1357. * \param data pointer to the dial_masquerade_datastore
  1358. * \param old_chan Channel being replaced
  1359. * \param new_chan Channel being pushed to dial mode
  1360. */
  1361. static void dial_masquerade_breakdown(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
  1362. {
  1363. struct dial_masquerade_datastore *masq_data = data;
  1364. struct dial_target *cur;
  1365. ao2_lock(masq_data);
  1366. if (!masq_data->caller) {
  1367. ao2_unlock(masq_data);
  1368. return;
  1369. }
  1370. if (masq_data->caller == new_chan) {
  1371. /*
  1372. * The caller channel is being masqueraded into.
  1373. * The masquerade is likely because of a blonde transfer.
  1374. */
  1375. ast_debug(1, "Caller channel %s being masqueraded into by %s (is_empty:%d)\n",
  1376. ast_channel_name(old_chan), ast_channel_name(new_chan),
  1377. AST_LIST_EMPTY(&masq_data->dialed_peers));
  1378. AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
  1379. ast_channel_publish_dial_internal(old_chan, cur->peer, NULL,
  1380. cur->dialstring, "NOANSWER", NULL);
  1381. ast_channel_publish_dial_internal(new_chan, cur->peer, NULL,
  1382. cur->dialstring, NULL, NULL);
  1383. }
  1384. ao2_unlock(masq_data);
  1385. return;
  1386. }
  1387. /*
  1388. * One of the peer channels is being masqueraded into.
  1389. * The masquerade is likely because of a call pickup.
  1390. */
  1391. AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
  1392. if (cur->peer == new_chan) {
  1393. ast_debug(1, "Peer channel %s being masqueraded into by %s\n",
  1394. ast_channel_name(old_chan), ast_channel_name(new_chan));
  1395. ast_channel_publish_dial_internal(masq_data->caller, old_chan, NULL,
  1396. cur->dialstring, "CANCEL", NULL);
  1397. ast_channel_publish_dial_internal(masq_data->caller, new_chan, NULL,
  1398. cur->dialstring, NULL, NULL);
  1399. break;
  1400. }
  1401. }
  1402. ao2_unlock(masq_data);
  1403. }
  1404. static const struct ast_datastore_info dial_masquerade_info = {
  1405. .type = "stasis-chan-dial-masq",
  1406. .destroy = dial_masquerade_datastore_destroy,
  1407. .chan_fixup = dial_masquerade_fixup,
  1408. .chan_breakdown = dial_masquerade_breakdown,
  1409. };
  1410. static const struct ast_datastore_info dial_masquerade_caller_info = {
  1411. .type = "stasis-chan-dial-masq",
  1412. .destroy = dial_masquerade_caller_datastore_destroy,
  1413. .chan_fixup = dial_masquerade_fixup,
  1414. .chan_breakdown = dial_masquerade_breakdown,
  1415. };
  1416. /*!
  1417. * \internal
  1418. * \brief Find the dial masquerade datastore on the given channel.
  1419. *
  1420. * \param chan Channel a datastore data is wanted from
  1421. *
  1422. * \return A pointer to the datastore if it exists.
  1423. */
  1424. static struct ast_datastore *dial_masquerade_datastore_find(struct ast_channel *chan)
  1425. {
  1426. struct ast_datastore *datastore;
  1427. datastore = ast_channel_datastore_find(chan, &dial_masquerade_info, NULL);
  1428. if (!datastore) {
  1429. datastore = ast_channel_datastore_find(chan, &dial_masquerade_caller_info, NULL);
  1430. }
  1431. return datastore;
  1432. }
  1433. /*!
  1434. * \internal
  1435. * \brief Add the dial masquerade datastore to a channel.
  1436. *
  1437. * \param chan Channel to setup dial masquerade datastore on.
  1438. * \param masq_data NULL to setup caller datastore otherwise steals the ref on success.
  1439. *
  1440. * \retval masq_data given or created on success.
  1441. * (A ref is not returned but can be obtained before chan is unlocked.)
  1442. * \retval NULL on error. masq_data ref is not stolen.
  1443. */
  1444. static struct dial_masquerade_datastore *dial_masquerade_datastore_add(
  1445. struct ast_channel *chan, struct dial_masquerade_datastore *masq_data)
  1446. {
  1447. struct ast_datastore *datastore;
  1448. datastore = ast_datastore_alloc(!masq_data ? &dial_masquerade_caller_info : &dial_masquerade_info, NULL);
  1449. if (!datastore) {
  1450. return NULL;
  1451. }
  1452. if (!masq_data) {
  1453. masq_data = dial_masquerade_datastore_alloc();
  1454. if (!masq_data) {
  1455. ast_datastore_free(datastore);
  1456. return NULL;
  1457. }
  1458. masq_data->caller = chan;
  1459. }
  1460. datastore->data = masq_data;
  1461. ast_channel_datastore_add(chan, datastore);
  1462. return masq_data;
  1463. }
  1464. static int set_dial_masquerade(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring)
  1465. {
  1466. struct ast_datastore *datastore;
  1467. struct dial_masquerade_datastore *masq_data;
  1468. struct dial_target *target;
  1469. /* Find or create caller datastore */
  1470. datastore = dial_masquerade_datastore_find(caller);
  1471. if (!datastore) {
  1472. masq_data = dial_masquerade_datastore_add(caller, NULL);
  1473. } else {
  1474. masq_data = datastore->data;
  1475. }
  1476. if (!masq_data) {
  1477. return -1;
  1478. }
  1479. ao2_ref(masq_data, +1);
  1480. /*
  1481. * Someone likely forgot to do an ast_channel_publish_dial()
  1482. * or ast_channel_publish_dial_forward() with a final dial
  1483. * status on the channel.
  1484. */
  1485. ast_assert(masq_data->caller == caller);
  1486. /* Create peer target to put into datastore */
  1487. target = ast_calloc(1, sizeof(*target));
  1488. if (!target) {
  1489. ao2_ref(masq_data, -1);
  1490. return -1;
  1491. }
  1492. if (dialstring) {
  1493. target->dialstring = ast_strdup(dialstring);
  1494. if (!target->dialstring) {
  1495. ast_free(target);
  1496. ao2_ref(masq_data, -1);
  1497. return -1;
  1498. }
  1499. }
  1500. target->peer = ast_channel_ref(peer);
  1501. /* Put peer target into datastore */
  1502. ao2_lock(masq_data);
  1503. dial_masquerade_datastore_remove_chan(masq_data, peer);
  1504. AST_LIST_INSERT_HEAD(&masq_data->dialed_peers, target, list);
  1505. ao2_unlock(masq_data);
  1506. datastore = dial_masquerade_datastore_find(peer);
  1507. if (datastore) {
  1508. if (datastore->data == masq_data) {
  1509. /*
  1510. * Peer already had the datastore for this dial masquerade.
  1511. * This was a redundant peer dial masquerade setup.
  1512. */
  1513. ao2_ref(masq_data, -1);
  1514. return 0;
  1515. }
  1516. /* Something is wrong. Try to fix if the assert doesn't abort. */
  1517. ast_assert(0);
  1518. /* Remove the stale dial masquerade datastore */
  1519. dial_masquerade_datastore_remove_chan(datastore->data, peer);
  1520. ast_channel_datastore_remove(peer, datastore);
  1521. ast_datastore_free(datastore);
  1522. }
  1523. /* Create the peer dial masquerade datastore */
  1524. if (dial_masquerade_datastore_add(peer, masq_data)) {
  1525. /* Success */
  1526. return 0;
  1527. }
  1528. /* Failed to create the peer datastore */
  1529. dial_masquerade_datastore_remove_chan(masq_data, peer);
  1530. ao2_ref(masq_data, -1);
  1531. return -1;
  1532. }
  1533. static void remove_dial_masquerade(struct ast_channel *peer)
  1534. {
  1535. struct ast_datastore *datastore;
  1536. struct dial_masquerade_datastore *masq_data;
  1537. datastore = dial_masquerade_datastore_find(peer);
  1538. if (!datastore) {
  1539. return;
  1540. }
  1541. masq_data = datastore->data;
  1542. if (masq_data) {
  1543. dial_masquerade_datastore_remove_chan(masq_data, peer);
  1544. }
  1545. ast_channel_datastore_remove(peer, datastore);
  1546. ast_datastore_free(datastore);
  1547. }
  1548. static void remove_dial_masquerade_caller(struct ast_channel *caller)
  1549. {
  1550. struct ast_datastore *datastore;
  1551. struct dial_masquerade_datastore *masq_data;
  1552. datastore = dial_masquerade_datastore_find(caller);
  1553. if (!datastore) {
  1554. return;
  1555. }
  1556. masq_data = datastore->data;
  1557. if (!masq_data || !AST_LIST_EMPTY(&masq_data->dialed_peers)) {
  1558. return;
  1559. }
  1560. dial_masquerade_datastore_remove_chan(masq_data, caller);
  1561. ast_channel_datastore_remove(caller, datastore);
  1562. ast_datastore_free(datastore);
  1563. }