pickup.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2013, Digium, Inc.
  5. * Copyright (C) 2012, Russell Bryant
  6. *
  7. * Matt Jordan <mjordan@digium.com>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*! \file
  20. *
  21. * \brief Routines implementing call pickup
  22. *
  23. * \author Matt Jordan <mjordan@digium.com>
  24. */
  25. /*!
  26. * \li Call pickup uses the configuration file \ref features.conf
  27. * \addtogroup configuration_file Configuration Files
  28. */
  29. /*** MODULEINFO
  30. <support_level>core</support_level>
  31. ***/
  32. /*** DOCUMENTATION
  33. <managerEvent language="en_US" name="Pickup">
  34. <managerEventInstance class="EVENT_FLAG_CALL">
  35. <synopsis>Raised when a call pickup occurs.</synopsis>
  36. <syntax>
  37. <channel_snapshot/>
  38. <channel_snapshot prefix="Target"/>
  39. </syntax>
  40. </managerEventInstance>
  41. </managerEvent>
  42. ***/
  43. #include "asterisk.h"
  44. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  45. #include "asterisk/pickup.h"
  46. #include "asterisk/channel.h"
  47. #include "asterisk/pbx.h"
  48. #include "asterisk/app.h"
  49. #include "asterisk/callerid.h"
  50. #include "asterisk/causes.h"
  51. #include "asterisk/stasis.h"
  52. #include "asterisk/stasis_channels.h"
  53. #include "asterisk/features_config.h"
  54. static struct ast_manager_event_blob *call_pickup_to_ami(struct stasis_message *message);
  55. STASIS_MESSAGE_TYPE_DEFN(
  56. ast_call_pickup_type,
  57. .to_ami = call_pickup_to_ami);
  58. /*!
  59. * The presence of this datastore on the channel indicates that
  60. * someone is attemting to pickup or has picked up the channel.
  61. * The purpose is to prevent a race between two channels
  62. * attempting to pickup the same channel.
  63. */
  64. static const struct ast_datastore_info pickup_active = {
  65. .type = "pickup-active",
  66. };
  67. int ast_can_pickup(struct ast_channel *chan)
  68. {
  69. if (!ast_channel_pbx(chan) && !ast_channel_masq(chan) && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
  70. && (ast_channel_state(chan) == AST_STATE_RINGING
  71. || ast_channel_state(chan) == AST_STATE_RING
  72. /*
  73. * Check the down state as well because some SIP devices do not
  74. * give 180 ringing when they can just give 183 session progress
  75. * instead. Issue 14005. (Some ISDN switches as well for that
  76. * matter.)
  77. */
  78. || ast_channel_state(chan) == AST_STATE_DOWN)
  79. && !ast_channel_datastore_find(chan, &pickup_active, NULL)) {
  80. return 1;
  81. }
  82. return 0;
  83. }
  84. static int find_channel_by_group(void *obj, void *arg, void *data, int flags)
  85. {
  86. struct ast_channel *target = obj; /*!< Potential pickup target */
  87. struct ast_channel *chan = arg; /*!< Channel wanting to pickup call */
  88. if (chan == target) {
  89. return 0;
  90. }
  91. ast_channel_lock(target);
  92. if (ast_can_pickup(target)) {
  93. /* Lock both channels. */
  94. while (ast_channel_trylock(chan)) {
  95. ast_channel_unlock(target);
  96. sched_yield();
  97. ast_channel_lock(target);
  98. }
  99. /*
  100. * Both callgroup and namedcallgroup pickup variants are
  101. * matched independently. Checking for named group match is
  102. * done last since it's a more expensive operation.
  103. */
  104. if ((ast_channel_pickupgroup(chan) & ast_channel_callgroup(target))
  105. || (ast_namedgroups_intersect(ast_channel_named_pickupgroups(chan),
  106. ast_channel_named_callgroups(target)))) {
  107. struct ao2_container *candidates = data;/*!< Candidate channels found. */
  108. /* This is a candidate to pickup */
  109. ao2_link(candidates, target);
  110. }
  111. ast_channel_unlock(chan);
  112. }
  113. ast_channel_unlock(target);
  114. return 0;
  115. }
  116. struct ast_channel *ast_pickup_find_by_group(struct ast_channel *chan)
  117. {
  118. struct ao2_container *candidates;/*!< Candidate channels found to pickup. */
  119. struct ast_channel *target;/*!< Potential pickup target */
  120. candidates = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL, NULL);
  121. if (!candidates) {
  122. return NULL;
  123. }
  124. /* Find all candidate targets by group. */
  125. ast_channel_callback(find_channel_by_group, chan, candidates, 0);
  126. /* Find the oldest pickup target candidate */
  127. target = NULL;
  128. for (;;) {
  129. struct ast_channel *candidate;/*!< Potential new older target */
  130. struct ao2_iterator iter;
  131. iter = ao2_iterator_init(candidates, 0);
  132. while ((candidate = ao2_iterator_next(&iter))) {
  133. if (!target) {
  134. /* First target. */
  135. target = candidate;
  136. continue;
  137. }
  138. if (ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) {
  139. /* We have a new target. */
  140. ast_channel_unref(target);
  141. target = candidate;
  142. continue;
  143. }
  144. ast_channel_unref(candidate);
  145. }
  146. ao2_iterator_destroy(&iter);
  147. if (!target) {
  148. /* No candidates found. */
  149. break;
  150. }
  151. /* The found channel must be locked and ref'd. */
  152. ast_channel_lock(target);
  153. /* Recheck pickup ability */
  154. if (ast_can_pickup(target)) {
  155. /* This is the channel to pickup. */
  156. break;
  157. }
  158. /* Someone else picked it up or the call went away. */
  159. ast_channel_unlock(target);
  160. ao2_unlink(candidates, target);
  161. target = ast_channel_unref(target);
  162. }
  163. ao2_ref(candidates, -1);
  164. return target;
  165. }
  166. /*!
  167. * \brief Pickup a call
  168. * \param chan channel that initiated pickup.
  169. *
  170. * Walk list of channels, checking it is not itself, channel is pbx one,
  171. * check that the callgroup for both channels are the same and the channel is ringing.
  172. * Answer calling channel, flag channel as answered on queue, masq channels together.
  173. */
  174. int ast_pickup_call(struct ast_channel *chan)
  175. {
  176. struct ast_channel *target;/*!< Potential pickup target */
  177. int res = -1;
  178. RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
  179. const char *pickup_sound;
  180. const char *fail_sound;
  181. ast_debug(1, "Pickup attempt by %s\n", ast_channel_name(chan));
  182. ast_channel_lock(chan);
  183. pickup_cfg = ast_get_chan_features_pickup_config(chan);
  184. if (!pickup_cfg) {
  185. ast_log(LOG_ERROR, "Unable to retrieve pickup configuration. Unable to play pickup sounds\n");
  186. }
  187. pickup_sound = ast_strdupa(pickup_cfg ? pickup_cfg->pickupsound : "");
  188. fail_sound = ast_strdupa(pickup_cfg ? pickup_cfg->pickupfailsound : "");
  189. ast_channel_unlock(chan);
  190. /* The found channel is already locked. */
  191. target = ast_pickup_find_by_group(chan);
  192. if (target) {
  193. ast_log(LOG_NOTICE, "Pickup %s attempt by %s\n", ast_channel_name(target), ast_channel_name(chan));
  194. res = ast_do_pickup(chan, target);
  195. ast_channel_unlock(target);
  196. if (!res) {
  197. if (!ast_strlen_zero(pickup_sound)) {
  198. pbx_builtin_setvar_helper(target, "BRIDGE_PLAY_SOUND", pickup_sound);
  199. }
  200. } else {
  201. ast_log(LOG_WARNING, "Pickup %s failed by %s\n", ast_channel_name(target), ast_channel_name(chan));
  202. }
  203. target = ast_channel_unref(target);
  204. }
  205. if (res < 0) {
  206. ast_debug(1, "No call pickup possible... for %s\n", ast_channel_name(chan));
  207. if (!ast_strlen_zero(fail_sound)) {
  208. ast_answer(chan);
  209. ast_stream_and_wait(chan, fail_sound, "");
  210. }
  211. }
  212. return res;
  213. }
  214. static struct ast_manager_event_blob *call_pickup_to_ami(struct stasis_message *message)
  215. {
  216. struct ast_multi_channel_blob *contents = stasis_message_data(message);
  217. struct ast_channel_snapshot *chan;
  218. struct ast_channel_snapshot *target;
  219. struct ast_manager_event_blob *res;
  220. RAII_VAR(struct ast_str *, channel_str, NULL, ast_free);
  221. RAII_VAR(struct ast_str *, target_str, NULL, ast_free);
  222. chan = ast_multi_channel_blob_get_channel(contents, "channel");
  223. target = ast_multi_channel_blob_get_channel(contents, "target");
  224. ast_assert(chan != NULL && target != NULL);
  225. if (!(channel_str = ast_manager_build_channel_state_string(chan))) {
  226. return NULL;
  227. }
  228. if (!(target_str = ast_manager_build_channel_state_string_prefix(target, "Target"))) {
  229. return NULL;
  230. }
  231. res = ast_manager_event_blob_create(EVENT_FLAG_CALL, "Pickup",
  232. "%s"
  233. "%s",
  234. ast_str_buffer(channel_str),
  235. ast_str_buffer(target_str));
  236. return res;
  237. }
  238. static int send_call_pickup_stasis_message(struct ast_channel *picking_up, struct ast_channel_snapshot *chan, struct ast_channel_snapshot *target)
  239. {
  240. RAII_VAR(struct ast_multi_channel_blob *, pickup_payload, NULL, ao2_cleanup);
  241. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  242. if (!ast_call_pickup_type()) {
  243. return -1;
  244. }
  245. if (!(pickup_payload = ast_multi_channel_blob_create(ast_json_null()))) {
  246. return -1;
  247. }
  248. ast_multi_channel_blob_add_channel(pickup_payload, "channel", chan);
  249. ast_multi_channel_blob_add_channel(pickup_payload, "target", target);
  250. if (!(msg = stasis_message_create(ast_call_pickup_type(), pickup_payload))) {
  251. return -1;
  252. }
  253. stasis_publish(ast_channel_topic(picking_up), msg);
  254. return 0;
  255. }
  256. int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
  257. {
  258. struct ast_party_connected_line connected_caller;
  259. struct ast_datastore *ds_pickup;
  260. const char *chan_name;/*!< A masquerade changes channel names. */
  261. const char *target_name;/*!< A masquerade changes channel names. */
  262. int res = -1;
  263. RAII_VAR(struct ast_channel_snapshot *, chan_snapshot, NULL, ao2_cleanup);
  264. RAII_VAR(struct ast_channel_snapshot *, target_snapshot, NULL, ao2_cleanup);
  265. target_name = ast_strdupa(ast_channel_name(target));
  266. ast_debug(1, "Call pickup on '%s' by '%s'\n", target_name, ast_channel_name(chan));
  267. /* Mark the target to block any call pickup race. */
  268. ds_pickup = ast_datastore_alloc(&pickup_active, NULL);
  269. if (!ds_pickup) {
  270. ast_log(LOG_WARNING,
  271. "Unable to create channel datastore on '%s' for call pickup\n", target_name);
  272. return -1;
  273. }
  274. ast_channel_datastore_add(target, ds_pickup);
  275. ast_party_connected_line_init(&connected_caller);
  276. ast_party_connected_line_copy(&connected_caller, ast_channel_connected(target));
  277. ast_channel_unlock(target);/* The pickup race is avoided so we do not need the lock anymore. */
  278. /* Reset any earlier private connected id representation */
  279. ast_party_id_reset(&connected_caller.priv);
  280. connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
  281. if (ast_channel_connected_line_sub(NULL, chan, &connected_caller, 0) &&
  282. ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {
  283. ast_channel_update_connected_line(chan, &connected_caller, NULL);
  284. }
  285. ast_party_connected_line_free(&connected_caller);
  286. ast_channel_lock(chan);
  287. chan_name = ast_strdupa(ast_channel_name(chan));
  288. ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(chan));
  289. ast_channel_unlock(chan);
  290. connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
  291. if (ast_answer(chan)) {
  292. ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan_name);
  293. goto pickup_failed;
  294. }
  295. if (ast_queue_control(chan, AST_CONTROL_ANSWER)) {
  296. ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan_name);
  297. goto pickup_failed;
  298. }
  299. ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
  300. /* setting the HANGUPCAUSE so the ringing channel knows this call was not a missed call */
  301. ast_channel_hangupcause_set(chan, AST_CAUSE_ANSWERED_ELSEWHERE);
  302. ast_channel_lock(chan);
  303. chan_snapshot = ast_channel_snapshot_create(chan);
  304. ast_channel_unlock(chan);
  305. if (!chan_snapshot) {
  306. goto pickup_failed;
  307. }
  308. target_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(target));
  309. if (!target_snapshot) {
  310. goto pickup_failed;
  311. }
  312. if (ast_channel_move(target, chan)) {
  313. ast_log(LOG_WARNING, "Unable to complete call pickup of '%s' with '%s'\n",
  314. chan_name, target_name);
  315. goto pickup_failed;
  316. }
  317. /* target points to the channel that did the pickup at this point, so use that channel's topic instead of chan */
  318. send_call_pickup_stasis_message(target, chan_snapshot, target_snapshot);
  319. res = 0;
  320. pickup_failed:
  321. ast_channel_lock(target);
  322. if (!ast_channel_datastore_remove(target, ds_pickup)) {
  323. ast_datastore_free(ds_pickup);
  324. }
  325. ast_party_connected_line_free(&connected_caller);
  326. return res;
  327. }
  328. /*!
  329. * \internal
  330. * \brief Clean up resources on Asterisk shutdown
  331. */
  332. static void pickup_shutdown(void)
  333. {
  334. STASIS_MESSAGE_TYPE_CLEANUP(ast_call_pickup_type);
  335. }
  336. int ast_pickup_init(void)
  337. {
  338. STASIS_MESSAGE_TYPE_INIT(ast_call_pickup_type);
  339. ast_register_cleanup(pickup_shutdown);
  340. return 0;
  341. }