control.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  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 Stasis application control support.
  21. *
  22. * \author David M. Lee, II <dlee@digium.com>
  23. */
  24. #include "asterisk.h"
  25. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  26. #include "asterisk/stasis_channels.h"
  27. #include "command.h"
  28. #include "control.h"
  29. #include "app.h"
  30. #include "asterisk/dial.h"
  31. #include "asterisk/bridge.h"
  32. #include "asterisk/bridge_after.h"
  33. #include "asterisk/bridge_basic.h"
  34. #include "asterisk/frame.h"
  35. #include "asterisk/pbx.h"
  36. #include "asterisk/musiconhold.h"
  37. #include "asterisk/app.h"
  38. AST_LIST_HEAD(app_control_rules, stasis_app_control_rule);
  39. struct stasis_app_control {
  40. ast_cond_t wait_cond;
  41. /*! Queue of commands to dispatch on the channel */
  42. struct ao2_container *command_queue;
  43. /*!
  44. * The associated channel.
  45. * Be very careful with the threading associated w/ manipulating
  46. * the channel.
  47. */
  48. struct ast_channel *channel;
  49. /*!
  50. * When a channel is in a bridge, the bridge that it is in.
  51. */
  52. struct ast_bridge *bridge;
  53. /*!
  54. * Holding place for channel's PBX while imparted to a bridge.
  55. */
  56. struct ast_pbx *pbx;
  57. /*!
  58. * A list of rules to check before adding a channel to a bridge.
  59. */
  60. struct app_control_rules add_rules;
  61. /*!
  62. * A list of rules to check before removing a channel from a bridge.
  63. */
  64. struct app_control_rules remove_rules;
  65. /*!
  66. * Silence generator, when silence is being generated.
  67. */
  68. struct ast_silence_generator *silgen;
  69. /*!
  70. * The app for which this control was created
  71. */
  72. struct stasis_app *app;
  73. /*!
  74. * When set, /c app_stasis should exit and continue in the dialplan.
  75. */
  76. int is_done:1;
  77. };
  78. static void control_dtor(void *obj)
  79. {
  80. struct stasis_app_control *control = obj;
  81. AST_LIST_HEAD_DESTROY(&control->add_rules);
  82. AST_LIST_HEAD_DESTROY(&control->remove_rules);
  83. /* We may have a lingering silence generator; free it */
  84. ast_channel_stop_silence_generator(control->channel, control->silgen);
  85. control->silgen = NULL;
  86. ao2_cleanup(control->command_queue);
  87. ast_cond_destroy(&control->wait_cond);
  88. ao2_cleanup(control->app);
  89. }
  90. struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
  91. {
  92. RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
  93. int res;
  94. control = ao2_alloc(sizeof(*control), control_dtor);
  95. if (!control) {
  96. return NULL;
  97. }
  98. control->app = ao2_bump(app);
  99. res = ast_cond_init(&control->wait_cond, NULL);
  100. if (res != 0) {
  101. ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
  102. strerror(errno));
  103. return NULL;
  104. }
  105. control->command_queue = ao2_container_alloc_list(
  106. AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
  107. if (!control->command_queue) {
  108. return NULL;
  109. }
  110. control->channel = channel;
  111. AST_LIST_HEAD_INIT(&control->add_rules);
  112. AST_LIST_HEAD_INIT(&control->remove_rules);
  113. ao2_ref(control, +1);
  114. return control;
  115. }
  116. static void app_control_register_rule(
  117. const struct stasis_app_control *control,
  118. struct app_control_rules *list, struct stasis_app_control_rule *obj)
  119. {
  120. SCOPED_AO2LOCK(lock, control->command_queue);
  121. AST_LIST_INSERT_TAIL(list, obj, next);
  122. }
  123. static void app_control_unregister_rule(
  124. const struct stasis_app_control *control,
  125. struct app_control_rules *list, struct stasis_app_control_rule *obj)
  126. {
  127. struct stasis_app_control_rule *rule;
  128. SCOPED_AO2LOCK(lock, control->command_queue);
  129. AST_RWLIST_TRAVERSE_SAFE_BEGIN(list, rule, next) {
  130. if (rule == obj) {
  131. AST_RWLIST_REMOVE_CURRENT(next);
  132. break;
  133. }
  134. }
  135. AST_RWLIST_TRAVERSE_SAFE_END;
  136. }
  137. /*!
  138. * \internal
  139. * \brief Checks to make sure each rule in the given list passes.
  140. *
  141. * \details Loops over a list of rules checking for rejections or failures.
  142. * If one rule fails its resulting error code is returned.
  143. *
  144. * \note Command queue should be locked before calling this function.
  145. *
  146. * \param control The stasis application control
  147. * \param list The list of rules to check
  148. *
  149. * \retval 0 if all rules pass
  150. * \retval non-zero error code if a rule fails
  151. */
  152. static enum stasis_app_control_channel_result app_control_check_rules(
  153. const struct stasis_app_control *control,
  154. struct app_control_rules *list)
  155. {
  156. int res = 0;
  157. struct stasis_app_control_rule *rule;
  158. AST_LIST_TRAVERSE(list, rule, next) {
  159. if ((res = rule->check_rule(control))) {
  160. return res;
  161. }
  162. }
  163. return res;
  164. }
  165. void stasis_app_control_register_add_rule(
  166. struct stasis_app_control *control,
  167. struct stasis_app_control_rule *rule)
  168. {
  169. return app_control_register_rule(control, &control->add_rules, rule);
  170. }
  171. void stasis_app_control_unregister_add_rule(
  172. struct stasis_app_control *control,
  173. struct stasis_app_control_rule *rule)
  174. {
  175. app_control_unregister_rule(control, &control->add_rules, rule);
  176. }
  177. void stasis_app_control_register_remove_rule(
  178. struct stasis_app_control *control,
  179. struct stasis_app_control_rule *rule)
  180. {
  181. return app_control_register_rule(control, &control->remove_rules, rule);
  182. }
  183. void stasis_app_control_unregister_remove_rule(
  184. struct stasis_app_control *control,
  185. struct stasis_app_control_rule *rule)
  186. {
  187. app_control_unregister_rule(control, &control->remove_rules, rule);
  188. }
  189. static int app_control_can_add_channel_to_bridge(
  190. struct stasis_app_control *control)
  191. {
  192. return app_control_check_rules(control, &control->add_rules);
  193. }
  194. static int app_control_can_remove_channel_from_bridge(
  195. struct stasis_app_control *control)
  196. {
  197. return app_control_check_rules(control, &control->remove_rules);
  198. }
  199. static int noop_cb(struct stasis_app_control *control,
  200. struct ast_channel *chan, void *data)
  201. {
  202. return 0;
  203. }
  204. /*! Callback type to see if the command can execute
  205. note: command_queue is locked during callback */
  206. typedef int (*app_command_can_exec_cb)(struct stasis_app_control *control);
  207. static struct stasis_app_command *exec_command_on_condition(
  208. struct stasis_app_control *control, stasis_app_command_cb command_fn,
  209. void *data, command_data_destructor_fn data_destructor,
  210. app_command_can_exec_cb can_exec_fn)
  211. {
  212. int retval;
  213. struct stasis_app_command *command;
  214. command_fn = command_fn ? : noop_cb;
  215. command = command_create(command_fn, data, data_destructor);
  216. if (!command) {
  217. return NULL;
  218. }
  219. ao2_lock(control->command_queue);
  220. if (can_exec_fn && (retval = can_exec_fn(control))) {
  221. ao2_unlock(control->command_queue);
  222. command_complete(command, retval);
  223. return command;
  224. }
  225. ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
  226. ast_cond_signal(&control->wait_cond);
  227. ao2_unlock(control->command_queue);
  228. return command;
  229. }
  230. static struct stasis_app_command *exec_command(
  231. struct stasis_app_control *control, stasis_app_command_cb command_fn,
  232. void *data, command_data_destructor_fn data_destructor)
  233. {
  234. return exec_command_on_condition(control, command_fn, data, data_destructor, NULL);
  235. }
  236. struct stasis_app_control_dial_data {
  237. char endpoint[AST_CHANNEL_NAME];
  238. int timeout;
  239. };
  240. static int app_control_dial(struct stasis_app_control *control,
  241. struct ast_channel *chan, void *data)
  242. {
  243. RAII_VAR(struct ast_dial *, dial, ast_dial_create(), ast_dial_destroy);
  244. struct stasis_app_control_dial_data *dial_data = data;
  245. enum ast_dial_result res;
  246. char *tech, *resource;
  247. struct ast_channel *new_chan;
  248. RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
  249. tech = dial_data->endpoint;
  250. if (!(resource = strchr(tech, '/'))) {
  251. return -1;
  252. }
  253. *resource++ = '\0';
  254. if (!dial) {
  255. ast_log(LOG_ERROR, "Failed to create dialing structure.\n");
  256. return -1;
  257. }
  258. if (ast_dial_append(dial, tech, resource, NULL) < 0) {
  259. ast_log(LOG_ERROR, "Failed to add %s/%s to dialing structure.\n", tech, resource);
  260. return -1;
  261. }
  262. ast_dial_set_global_timeout(dial, dial_data->timeout);
  263. res = ast_dial_run(dial, NULL, 0);
  264. if (res != AST_DIAL_RESULT_ANSWERED || !(new_chan = ast_dial_answered_steal(dial))) {
  265. return -1;
  266. }
  267. if (!(bridge = ast_bridge_basic_new())) {
  268. ast_log(LOG_ERROR, "Failed to create basic bridge.\n");
  269. return -1;
  270. }
  271. if (ast_bridge_impart(bridge, new_chan, NULL, NULL,
  272. AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
  273. ast_hangup(new_chan);
  274. } else {
  275. control_add_channel_to_bridge(control, chan, bridge);
  276. }
  277. return 0;
  278. }
  279. int stasis_app_control_dial(struct stasis_app_control *control, const char *endpoint, const char *exten, const char *context,
  280. int timeout)
  281. {
  282. struct stasis_app_control_dial_data *dial_data;
  283. if (!(dial_data = ast_calloc(1, sizeof(*dial_data)))) {
  284. return -1;
  285. }
  286. if (!ast_strlen_zero(endpoint)) {
  287. ast_copy_string(dial_data->endpoint, endpoint, sizeof(dial_data->endpoint));
  288. } else if (!ast_strlen_zero(exten) && !ast_strlen_zero(context)) {
  289. snprintf(dial_data->endpoint, sizeof(dial_data->endpoint), "Local/%s@%s", exten, context);
  290. } else {
  291. return -1;
  292. }
  293. if (timeout > 0) {
  294. dial_data->timeout = timeout * 1000;
  295. } else if (timeout == -1) {
  296. dial_data->timeout = -1;
  297. } else {
  298. dial_data->timeout = 30000;
  299. }
  300. stasis_app_send_command_async(control, app_control_dial, dial_data, ast_free_ptr);
  301. return 0;
  302. }
  303. int stasis_app_control_add_role(struct stasis_app_control *control, const char *role)
  304. {
  305. return ast_channel_add_bridge_role(control->channel, role);
  306. }
  307. void stasis_app_control_clear_roles(struct stasis_app_control *control)
  308. {
  309. ast_channel_clear_bridge_roles(control->channel);
  310. }
  311. int control_command_count(struct stasis_app_control *control)
  312. {
  313. return ao2_container_count(control->command_queue);
  314. }
  315. int control_is_done(struct stasis_app_control *control)
  316. {
  317. /* Called from stasis_app_exec thread; no lock needed */
  318. return control->is_done;
  319. }
  320. void control_mark_done(struct stasis_app_control *control)
  321. {
  322. control->is_done = 1;
  323. }
  324. struct stasis_app_control_continue_data {
  325. char context[AST_MAX_CONTEXT];
  326. char extension[AST_MAX_EXTENSION];
  327. int priority;
  328. };
  329. static int app_control_continue(struct stasis_app_control *control,
  330. struct ast_channel *chan, void *data)
  331. {
  332. struct stasis_app_control_continue_data *continue_data = data;
  333. ast_assert(control->channel != NULL);
  334. /* If we're in a Stasis bridge, depart it before going back to the
  335. * dialplan */
  336. if (stasis_app_get_bridge(control)) {
  337. ast_bridge_depart(control->channel);
  338. }
  339. /* Called from stasis_app_exec thread; no lock needed */
  340. ast_explicit_goto(control->channel, continue_data->context, continue_data->extension, continue_data->priority);
  341. control->is_done = 1;
  342. return 0;
  343. }
  344. int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority)
  345. {
  346. struct stasis_app_control_continue_data *continue_data;
  347. if (!(continue_data = ast_calloc(1, sizeof(*continue_data)))) {
  348. return -1;
  349. }
  350. ast_copy_string(continue_data->context, S_OR(context, ""), sizeof(continue_data->context));
  351. ast_copy_string(continue_data->extension, S_OR(extension, ""), sizeof(continue_data->extension));
  352. if (priority > 0) {
  353. continue_data->priority = priority;
  354. } else {
  355. continue_data->priority = -1;
  356. }
  357. stasis_app_send_command_async(control, app_control_continue, continue_data, ast_free_ptr);
  358. return 0;
  359. }
  360. static int app_control_redirect(struct stasis_app_control *control,
  361. struct ast_channel *chan, void *data)
  362. {
  363. char *endpoint = data;
  364. int res;
  365. ast_assert(control->channel != NULL);
  366. ast_assert(endpoint != NULL);
  367. res = ast_transfer(control->channel, endpoint);
  368. if (!res) {
  369. ast_log(LOG_NOTICE, "Unsupported transfer requested on channel '%s'\n",
  370. ast_channel_name(control->channel));
  371. return 0;
  372. }
  373. return 0;
  374. }
  375. int stasis_app_control_redirect(struct stasis_app_control *control, const char *endpoint)
  376. {
  377. char *endpoint_data = ast_strdup(endpoint);
  378. if (!endpoint_data) {
  379. return -1;
  380. }
  381. stasis_app_send_command_async(control, app_control_redirect, endpoint_data, ast_free_ptr);
  382. return 0;
  383. }
  384. struct stasis_app_control_dtmf_data {
  385. int before;
  386. int between;
  387. unsigned int duration;
  388. int after;
  389. char dtmf[];
  390. };
  391. static int app_control_dtmf(struct stasis_app_control *control,
  392. struct ast_channel *chan, void *data)
  393. {
  394. struct stasis_app_control_dtmf_data *dtmf_data = data;
  395. if (ast_channel_state(chan) != AST_STATE_UP) {
  396. ast_indicate(chan, AST_CONTROL_PROGRESS);
  397. }
  398. if (dtmf_data->before) {
  399. ast_safe_sleep(chan, dtmf_data->before);
  400. }
  401. ast_dtmf_stream(chan, NULL, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
  402. if (dtmf_data->after) {
  403. ast_safe_sleep(chan, dtmf_data->after);
  404. }
  405. return 0;
  406. }
  407. int stasis_app_control_dtmf(struct stasis_app_control *control, const char *dtmf, int before, int between, unsigned int duration, int after)
  408. {
  409. struct stasis_app_control_dtmf_data *dtmf_data;
  410. if (!(dtmf_data = ast_calloc(1, sizeof(*dtmf_data) + strlen(dtmf) + 1))) {
  411. return -1;
  412. }
  413. dtmf_data->before = before;
  414. dtmf_data->between = between;
  415. dtmf_data->duration = duration;
  416. dtmf_data->after = after;
  417. strcpy(dtmf_data->dtmf, dtmf);
  418. stasis_app_send_command_async(control, app_control_dtmf, dtmf_data, ast_free_ptr);
  419. return 0;
  420. }
  421. static int app_control_ring(struct stasis_app_control *control,
  422. struct ast_channel *chan, void *data)
  423. {
  424. ast_indicate(control->channel, AST_CONTROL_RINGING);
  425. return 0;
  426. }
  427. int stasis_app_control_ring(struct stasis_app_control *control)
  428. {
  429. stasis_app_send_command_async(control, app_control_ring, NULL, NULL);
  430. return 0;
  431. }
  432. static int app_control_ring_stop(struct stasis_app_control *control,
  433. struct ast_channel *chan, void *data)
  434. {
  435. ast_indicate(control->channel, -1);
  436. return 0;
  437. }
  438. int stasis_app_control_ring_stop(struct stasis_app_control *control)
  439. {
  440. stasis_app_send_command_async(control, app_control_ring_stop, NULL, NULL);
  441. return 0;
  442. }
  443. struct stasis_app_control_mute_data {
  444. enum ast_frame_type frametype;
  445. unsigned int direction;
  446. };
  447. static int app_control_mute(struct stasis_app_control *control,
  448. struct ast_channel *chan, void *data)
  449. {
  450. struct stasis_app_control_mute_data *mute_data = data;
  451. SCOPED_CHANNELLOCK(lockvar, chan);
  452. ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);
  453. return 0;
  454. }
  455. int stasis_app_control_mute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
  456. {
  457. struct stasis_app_control_mute_data *mute_data;
  458. if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
  459. return -1;
  460. }
  461. mute_data->direction = direction;
  462. mute_data->frametype = frametype;
  463. stasis_app_send_command_async(control, app_control_mute, mute_data, ast_free_ptr);
  464. return 0;
  465. }
  466. static int app_control_unmute(struct stasis_app_control *control,
  467. struct ast_channel *chan, void *data)
  468. {
  469. struct stasis_app_control_mute_data *mute_data = data;
  470. SCOPED_CHANNELLOCK(lockvar, chan);
  471. ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);
  472. return 0;
  473. }
  474. int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
  475. {
  476. struct stasis_app_control_mute_data *mute_data;
  477. if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
  478. return -1;
  479. }
  480. mute_data->direction = direction;
  481. mute_data->frametype = frametype;
  482. stasis_app_send_command_async(control, app_control_unmute, mute_data, ast_free_ptr);
  483. return 0;
  484. }
  485. int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value)
  486. {
  487. return pbx_builtin_setvar_helper(control->channel, variable, value);
  488. }
  489. static int app_control_hold(struct stasis_app_control *control,
  490. struct ast_channel *chan, void *data)
  491. {
  492. ast_indicate(control->channel, AST_CONTROL_HOLD);
  493. return 0;
  494. }
  495. void stasis_app_control_hold(struct stasis_app_control *control)
  496. {
  497. stasis_app_send_command_async(control, app_control_hold, NULL, NULL);
  498. }
  499. static int app_control_unhold(struct stasis_app_control *control,
  500. struct ast_channel *chan, void *data)
  501. {
  502. ast_indicate(control->channel, AST_CONTROL_UNHOLD);
  503. return 0;
  504. }
  505. void stasis_app_control_unhold(struct stasis_app_control *control)
  506. {
  507. stasis_app_send_command_async(control, app_control_unhold, NULL, NULL);
  508. }
  509. static int app_control_moh_start(struct stasis_app_control *control,
  510. struct ast_channel *chan, void *data)
  511. {
  512. char *moh_class = data;
  513. if (ast_channel_state(chan) != AST_STATE_UP) {
  514. ast_indicate(chan, AST_CONTROL_PROGRESS);
  515. }
  516. ast_moh_start(chan, moh_class, NULL);
  517. return 0;
  518. }
  519. void stasis_app_control_moh_start(struct stasis_app_control *control, const char *moh_class)
  520. {
  521. char *data = NULL;
  522. if (!ast_strlen_zero(moh_class)) {
  523. data = ast_strdup(moh_class);
  524. }
  525. stasis_app_send_command_async(control, app_control_moh_start, data, ast_free_ptr);
  526. }
  527. static int app_control_moh_stop(struct stasis_app_control *control,
  528. struct ast_channel *chan, void *data)
  529. {
  530. ast_moh_stop(chan);
  531. return 0;
  532. }
  533. void stasis_app_control_moh_stop(struct stasis_app_control *control)
  534. {
  535. stasis_app_send_command_async(control, app_control_moh_stop, NULL, NULL);
  536. }
  537. static int app_control_silence_start(struct stasis_app_control *control,
  538. struct ast_channel *chan, void *data)
  539. {
  540. if (ast_channel_state(chan) != AST_STATE_UP) {
  541. ast_indicate(chan, AST_CONTROL_PROGRESS);
  542. }
  543. if (control->silgen) {
  544. /* We have a silence generator, but it may have been implicitly
  545. * disabled by media actions (music on hold, playing media,
  546. * etc.) Just stop it and restart a new one.
  547. */
  548. ast_channel_stop_silence_generator(
  549. control->channel, control->silgen);
  550. }
  551. ast_debug(3, "%s: Starting silence generator\n",
  552. stasis_app_control_get_channel_id(control));
  553. control->silgen = ast_channel_start_silence_generator(control->channel);
  554. if (!control->silgen) {
  555. ast_log(LOG_WARNING,
  556. "%s: Failed to start silence generator.\n",
  557. stasis_app_control_get_channel_id(control));
  558. }
  559. return 0;
  560. }
  561. void stasis_app_control_silence_start(struct stasis_app_control *control)
  562. {
  563. stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
  564. }
  565. static int app_control_silence_stop(struct stasis_app_control *control,
  566. struct ast_channel *chan, void *data)
  567. {
  568. if (control->silgen) {
  569. ast_debug(3, "%s: Stopping silence generator\n",
  570. stasis_app_control_get_channel_id(control));
  571. ast_channel_stop_silence_generator(
  572. control->channel, control->silgen);
  573. control->silgen = NULL;
  574. }
  575. return 0;
  576. }
  577. void stasis_app_control_silence_stop(struct stasis_app_control *control)
  578. {
  579. stasis_app_send_command_async(control, app_control_silence_stop, NULL, NULL);
  580. }
  581. struct ast_channel_snapshot *stasis_app_control_get_snapshot(
  582. const struct stasis_app_control *control)
  583. {
  584. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  585. struct ast_channel_snapshot *snapshot;
  586. msg = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(),
  587. stasis_app_control_get_channel_id(control));
  588. if (!msg) {
  589. return NULL;
  590. }
  591. snapshot = stasis_message_data(msg);
  592. ast_assert(snapshot != NULL);
  593. ao2_ref(snapshot, +1);
  594. return snapshot;
  595. }
  596. static int app_send_command_on_condition(struct stasis_app_control *control,
  597. stasis_app_command_cb command_fn, void *data,
  598. command_data_destructor_fn data_destructor,
  599. app_command_can_exec_cb can_exec_fn)
  600. {
  601. RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
  602. if (control == NULL) {
  603. return -1;
  604. }
  605. command = exec_command_on_condition(
  606. control, command_fn, data, data_destructor, can_exec_fn);
  607. if (!command) {
  608. return -1;
  609. }
  610. return command_join(command);
  611. }
  612. int stasis_app_send_command(struct stasis_app_control *control,
  613. stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
  614. {
  615. return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
  616. }
  617. int stasis_app_send_command_async(struct stasis_app_control *control,
  618. stasis_app_command_cb command_fn, void *data,
  619. command_data_destructor_fn data_destructor)
  620. {
  621. RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
  622. if (control == NULL) {
  623. return -1;
  624. }
  625. command = exec_command(control, command_fn, data, data_destructor);
  626. if (!command) {
  627. return -1;
  628. }
  629. return 0;
  630. }
  631. struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
  632. {
  633. if (!control) {
  634. return NULL;
  635. } else {
  636. SCOPED_AO2LOCK(lock, control);
  637. return control->bridge;
  638. }
  639. }
  640. static int bridge_channel_depart(struct stasis_app_control *control,
  641. struct ast_channel *chan, void *data)
  642. {
  643. struct ast_bridge_channel *bridge_channel = data;
  644. {
  645. SCOPED_CHANNELLOCK(lock, chan);
  646. if (bridge_channel != ast_channel_internal_bridge_channel(chan)) {
  647. ast_debug(3, "%s: Channel is no longer in departable state\n",
  648. ast_channel_uniqueid(chan));
  649. return -1;
  650. }
  651. }
  652. ast_debug(3, "%s: Channel departing bridge\n",
  653. ast_channel_uniqueid(chan));
  654. ast_bridge_depart(chan);
  655. return 0;
  656. }
  657. static void bridge_after_cb(struct ast_channel *chan, void *data)
  658. {
  659. struct stasis_app_control *control = data;
  660. SCOPED_AO2LOCK(lock, control);
  661. struct ast_bridge_channel *bridge_channel;
  662. ast_debug(3, "%s, %s: Channel leaving bridge\n",
  663. ast_channel_uniqueid(chan), control->bridge->uniqueid);
  664. ast_assert(chan == control->channel);
  665. /* Restore the channel's PBX */
  666. ast_channel_pbx_set(control->channel, control->pbx);
  667. control->pbx = NULL;
  668. app_unsubscribe_bridge(control->app, control->bridge);
  669. /* No longer in the bridge */
  670. control->bridge = NULL;
  671. /* Get the bridge channel so we don't depart from the wrong bridge */
  672. ast_channel_lock(chan);
  673. bridge_channel = ast_channel_get_bridge_channel(chan);
  674. ast_channel_unlock(chan);
  675. /* Depart this channel from the bridge using the command queue if possible */
  676. stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup);
  677. if (stasis_app_channel_is_stasis_end_published(chan)) {
  678. /* The channel has had a StasisEnd published on it, but until now had remained in
  679. * the bridging system. This means that the channel moved from a Stasis bridge to a
  680. * non-Stasis bridge and is now exiting the bridging system. Because of this, the
  681. * channel needs to exit the Stasis application and go to wherever the non-Stasis
  682. * bridge has directed it to go. If the non-Stasis bridge has not set up an after
  683. * bridge destination, then the channel should be hung up.
  684. */
  685. int hangup_flag;
  686. hangup_flag = ast_bridge_setup_after_goto(chan) ? AST_SOFTHANGUP_DEV : AST_SOFTHANGUP_ASYNCGOTO;
  687. ast_channel_lock(chan);
  688. ast_softhangup_nolock(chan, hangup_flag);
  689. ast_channel_unlock(chan);
  690. }
  691. }
  692. static void bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason,
  693. void *data)
  694. {
  695. struct stasis_app_control *control = data;
  696. bridge_after_cb(control->channel, data);
  697. ast_debug(3, " reason: %s\n",
  698. ast_bridge_after_cb_reason_string(reason));
  699. }
  700. int control_add_channel_to_bridge(
  701. struct stasis_app_control *control,
  702. struct ast_channel *chan, void *data)
  703. {
  704. struct ast_bridge *bridge = data;
  705. int res;
  706. if (!control || !bridge) {
  707. return -1;
  708. }
  709. ast_debug(3, "%s: Adding to bridge %s\n",
  710. stasis_app_control_get_channel_id(control),
  711. bridge->uniqueid);
  712. ast_assert(chan != NULL);
  713. /* Depart whatever Stasis bridge we're currently in. */
  714. if (stasis_app_get_bridge(control)) {
  715. /* Note that it looks like there's a race condition here, since
  716. * we don't have control locked. But this happens from the
  717. * control callback thread, so there won't be any other
  718. * concurrent attempts to bridge.
  719. */
  720. ast_bridge_depart(chan);
  721. }
  722. res = ast_bridge_set_after_callback(chan, bridge_after_cb,
  723. bridge_after_cb_failed, control);
  724. if (res != 0) {
  725. ast_log(LOG_ERROR, "Error setting after-bridge callback\n");
  726. return -1;
  727. }
  728. {
  729. /* pbx and bridge are modified by the bridging impart thread.
  730. * It shouldn't happen concurrently, but we still need to lock
  731. * for the memory fence.
  732. */
  733. SCOPED_AO2LOCK(lock, control);
  734. /* Ensure the controlling application is subscribed early enough
  735. * to receive the ChannelEnteredBridge message. This works in concert
  736. * with the subscription handled in the Stasis application execution
  737. * loop */
  738. app_subscribe_bridge(control->app, bridge);
  739. /* Save off the channel's PBX */
  740. ast_assert(control->pbx == NULL);
  741. if (!control->pbx) {
  742. control->pbx = ast_channel_pbx(chan);
  743. ast_channel_pbx_set(chan, NULL);
  744. }
  745. res = ast_bridge_impart(bridge,
  746. chan,
  747. NULL, /* swap channel */
  748. NULL, /* features */
  749. AST_BRIDGE_IMPART_CHAN_DEPARTABLE);
  750. if (res != 0) {
  751. ast_log(LOG_ERROR, "Error adding channel to bridge\n");
  752. ast_channel_pbx_set(chan, control->pbx);
  753. control->pbx = NULL;
  754. return -1;
  755. }
  756. ast_assert(stasis_app_get_bridge(control) == NULL);
  757. control->bridge = bridge;
  758. }
  759. return 0;
  760. }
  761. int stasis_app_control_add_channel_to_bridge(
  762. struct stasis_app_control *control, struct ast_bridge *bridge)
  763. {
  764. ast_debug(3, "%s: Sending channel add_to_bridge command\n",
  765. stasis_app_control_get_channel_id(control));
  766. return app_send_command_on_condition(
  767. control, control_add_channel_to_bridge, bridge, NULL,
  768. app_control_can_add_channel_to_bridge);
  769. }
  770. static int app_control_remove_channel_from_bridge(
  771. struct stasis_app_control *control,
  772. struct ast_channel *chan, void *data)
  773. {
  774. struct ast_bridge *bridge = data;
  775. if (!control) {
  776. return -1;
  777. }
  778. /* We should only depart from our own bridge */
  779. ast_debug(3, "%s: Departing bridge %s\n",
  780. stasis_app_control_get_channel_id(control),
  781. bridge->uniqueid);
  782. if (bridge != stasis_app_get_bridge(control)) {
  783. ast_log(LOG_WARNING, "%s: Not in bridge %s; not removing\n",
  784. stasis_app_control_get_channel_id(control),
  785. bridge->uniqueid);
  786. return -1;
  787. }
  788. ast_bridge_depart(chan);
  789. return 0;
  790. }
  791. int stasis_app_control_remove_channel_from_bridge(
  792. struct stasis_app_control *control, struct ast_bridge *bridge)
  793. {
  794. ast_debug(3, "%s: Sending channel remove_from_bridge command\n",
  795. stasis_app_control_get_channel_id(control));
  796. return app_send_command_on_condition(
  797. control, app_control_remove_channel_from_bridge, bridge, NULL,
  798. app_control_can_remove_channel_from_bridge);
  799. }
  800. const char *stasis_app_control_get_channel_id(
  801. const struct stasis_app_control *control)
  802. {
  803. return ast_channel_uniqueid(control->channel);
  804. }
  805. void stasis_app_control_publish(
  806. struct stasis_app_control *control, struct stasis_message *message)
  807. {
  808. if (!control || !control->channel || !message) {
  809. return;
  810. }
  811. stasis_publish(ast_channel_topic(control->channel), message);
  812. }
  813. int stasis_app_control_queue_control(struct stasis_app_control *control,
  814. enum ast_control_frame_type frame_type)
  815. {
  816. return ast_queue_control(control->channel, frame_type);
  817. }
  818. int control_dispatch_all(struct stasis_app_control *control,
  819. struct ast_channel *chan)
  820. {
  821. int count = 0;
  822. struct ao2_iterator i;
  823. void *obj;
  824. ast_assert(control->channel == chan);
  825. i = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
  826. while ((obj = ao2_iterator_next(&i))) {
  827. RAII_VAR(struct stasis_app_command *, command, obj, ao2_cleanup);
  828. command_invoke(command, control, chan);
  829. ++count;
  830. }
  831. ao2_iterator_destroy(&i);
  832. return count;
  833. }
  834. void control_wait(struct stasis_app_control *control)
  835. {
  836. if (!control) {
  837. return;
  838. }
  839. ast_assert(control->command_queue != NULL);
  840. ao2_lock(control->command_queue);
  841. while (ao2_container_count(control->command_queue) == 0) {
  842. int res = ast_cond_wait(&control->wait_cond,
  843. ao2_object_get_lockaddr(control->command_queue));
  844. if (res < 0) {
  845. ast_log(LOG_ERROR, "Error waiting on command queue\n");
  846. break;
  847. }
  848. }
  849. ao2_unlock(control->command_queue);
  850. }
  851. int control_prestart_dispatch_all(struct stasis_app_control *control,
  852. struct ast_channel *chan)
  853. {
  854. struct ao2_container *command_queue;
  855. int count = 0;
  856. struct ao2_iterator iter;
  857. struct stasis_app_command *command;
  858. ast_channel_lock(chan);
  859. command_queue = command_prestart_get_container(chan);
  860. ast_channel_unlock(chan);
  861. if (!command_queue) {
  862. return 0;
  863. }
  864. iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK);
  865. while ((command = ao2_iterator_next(&iter))) {
  866. command_invoke(command, control, chan);
  867. ao2_cleanup(command);
  868. ++count;
  869. }
  870. ao2_iterator_destroy(&iter);
  871. ao2_cleanup(command_queue);
  872. return count;
  873. }
  874. struct stasis_app *control_app(struct stasis_app_control *control)
  875. {
  876. return control->app;
  877. }