core_unreal.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013 Digium, Inc.
  5. *
  6. * Richard Mudgett <rmudgett@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. /*!
  19. * \file
  20. * \brief Unreal channel derivatives framework for channel drivers like local channels.
  21. *
  22. * \author Richard Mudgett <rmudgett@digium.com>
  23. *
  24. * See Also:
  25. * \arg \ref AstCREDITS
  26. */
  27. /*** MODULEINFO
  28. <support_level>core</support_level>
  29. ***/
  30. #include "asterisk.h"
  31. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  32. #include "asterisk/causes.h"
  33. #include "asterisk/channel.h"
  34. #include "asterisk/stasis_channels.h"
  35. #include "asterisk/pbx.h"
  36. #include "asterisk/musiconhold.h"
  37. #include "asterisk/astobj2.h"
  38. #include "asterisk/bridge.h"
  39. #include "asterisk/core_unreal.h"
  40. static unsigned int name_sequence = 0;
  41. void ast_unreal_lock_all(struct ast_unreal_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
  42. {
  43. struct ast_channel *chan = NULL;
  44. struct ast_channel *owner = NULL;
  45. ao2_lock(p);
  46. for (;;) {
  47. if (p->chan) {
  48. chan = p->chan;
  49. ast_channel_ref(chan);
  50. }
  51. if (p->owner) {
  52. owner = p->owner;
  53. ast_channel_ref(owner);
  54. }
  55. ao2_unlock(p);
  56. /* if we don't have both channels, then this is very easy */
  57. if (!owner || !chan) {
  58. if (owner) {
  59. ast_channel_lock(owner);
  60. } else if(chan) {
  61. ast_channel_lock(chan);
  62. }
  63. } else {
  64. /* lock both channels first, then get the pvt lock */
  65. ast_channel_lock_both(chan, owner);
  66. }
  67. ao2_lock(p);
  68. /* Now that we have all the locks, validate that nothing changed */
  69. if (p->owner != owner || p->chan != chan) {
  70. if (owner) {
  71. ast_channel_unlock(owner);
  72. owner = ast_channel_unref(owner);
  73. }
  74. if (chan) {
  75. ast_channel_unlock(chan);
  76. chan = ast_channel_unref(chan);
  77. }
  78. continue;
  79. }
  80. break;
  81. }
  82. *outowner = p->owner;
  83. *outchan = p->chan;
  84. }
  85. /* Called with ast locked */
  86. int ast_unreal_setoption(struct ast_channel *ast, int option, void *data, int datalen)
  87. {
  88. int res = 0;
  89. struct ast_unreal_pvt *p;
  90. struct ast_channel *otherchan = NULL;
  91. ast_chan_write_info_t *write_info;
  92. if (option != AST_OPTION_CHANNEL_WRITE) {
  93. return -1;
  94. }
  95. write_info = data;
  96. if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
  97. ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
  98. return -1;
  99. }
  100. if (!strcmp(write_info->function, "CHANNEL")
  101. && !strncasecmp(write_info->data, "hangup_handler_", 15)) {
  102. /* Block CHANNEL(hangup_handler_xxx) writes to the other unreal channel. */
  103. return 0;
  104. }
  105. /* get the tech pvt */
  106. if (!(p = ast_channel_tech_pvt(ast))) {
  107. return -1;
  108. }
  109. ao2_ref(p, 1);
  110. ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
  111. /* get the channel we are supposed to write to */
  112. ao2_lock(p);
  113. otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
  114. if (!otherchan || otherchan == write_info->chan) {
  115. res = -1;
  116. otherchan = NULL;
  117. ao2_unlock(p);
  118. goto setoption_cleanup;
  119. }
  120. ast_channel_ref(otherchan);
  121. /* clear the pvt lock before grabbing the channel */
  122. ao2_unlock(p);
  123. ast_channel_lock(otherchan);
  124. res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
  125. ast_channel_unlock(otherchan);
  126. setoption_cleanup:
  127. ao2_ref(p, -1);
  128. if (otherchan) {
  129. ast_channel_unref(otherchan);
  130. }
  131. ast_channel_lock(ast); /* Lock back before we leave */
  132. return res;
  133. }
  134. /* Called with ast locked */
  135. int ast_unreal_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
  136. {
  137. struct ast_unreal_pvt *p;
  138. struct ast_channel *peer;
  139. struct ast_channel *other;
  140. int res = 0;
  141. if (option != AST_OPTION_T38_STATE) {
  142. /* AST_OPTION_T38_STATE is the only supported option at this time */
  143. return -1;
  144. }
  145. /* for some reason the channel is not locked in channel.c when this function is called */
  146. if (!(p = ast_channel_tech_pvt(ast))) {
  147. return -1;
  148. }
  149. ao2_lock(p);
  150. other = AST_UNREAL_IS_OUTBOUND(ast, p) ? p->owner : p->chan;
  151. if (!other) {
  152. ao2_unlock(p);
  153. return -1;
  154. }
  155. ast_channel_ref(other);
  156. ao2_unlock(p);
  157. ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
  158. peer = ast_channel_bridge_peer(other);
  159. if (peer) {
  160. res = ast_channel_queryoption(peer, option, data, datalen, 0);
  161. ast_channel_unref(peer);
  162. }
  163. ast_channel_unref(other);
  164. ast_channel_lock(ast); /* Lock back before we leave */
  165. return res;
  166. }
  167. /*!
  168. * \brief queue a frame onto either the p->owner or p->chan
  169. *
  170. * \note the ast_unreal_pvt MUST have it's ref count bumped before entering this function and
  171. * decremented after this function is called. This is a side effect of the deadlock
  172. * avoidance that is necessary to lock 2 channels and a tech_pvt. Without a ref counted
  173. * ast_unreal_pvt, it is impossible to guarantee it will not be destroyed by another thread
  174. * during deadlock avoidance.
  175. */
  176. static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f,
  177. struct ast_channel *us, int us_locked)
  178. {
  179. struct ast_channel *other;
  180. /* Recalculate outbound channel */
  181. other = isoutbound ? p->owner : p->chan;
  182. if (!other) {
  183. return 0;
  184. }
  185. /* do not queue media frames if a generator is on both unreal channels */
  186. if (us
  187. && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)
  188. && ast_channel_generator(us)
  189. && ast_channel_generator(other)) {
  190. return 0;
  191. }
  192. /* grab a ref on the channel before unlocking the pvt,
  193. * other can not go away from us now regardless of locking */
  194. ast_channel_ref(other);
  195. if (us && us_locked) {
  196. ast_channel_unlock(us);
  197. }
  198. ao2_unlock(p);
  199. if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
  200. ast_setstate(other, AST_STATE_RINGING);
  201. }
  202. ast_queue_frame(other, f);
  203. other = ast_channel_unref(other);
  204. if (us && us_locked) {
  205. ast_channel_lock(us);
  206. }
  207. ao2_lock(p);
  208. return 0;
  209. }
  210. int ast_unreal_answer(struct ast_channel *ast)
  211. {
  212. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  213. int isoutbound;
  214. int res = -1;
  215. if (!p) {
  216. return -1;
  217. }
  218. ao2_ref(p, 1);
  219. ao2_lock(p);
  220. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  221. if (isoutbound) {
  222. /* Pass along answer since somebody answered us */
  223. struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
  224. res = unreal_queue_frame(p, isoutbound, &answer, ast, 1);
  225. } else {
  226. ast_log(LOG_WARNING, "Huh? %s is being asked to answer?\n",
  227. ast_channel_name(ast));
  228. }
  229. ao2_unlock(p);
  230. ao2_ref(p, -1);
  231. return res;
  232. }
  233. /*!
  234. * \internal
  235. * \brief Check and optimize out the unreal channels between bridges.
  236. * \since 12.0.0
  237. *
  238. * \param ast Channel writing a frame into the unreal channels.
  239. * \param p Unreal channel private.
  240. *
  241. * \note It is assumed that ast is locked.
  242. * \note It is assumed that p is locked.
  243. *
  244. * \retval 0 if unreal channels were not optimized out.
  245. * \retval non-zero if unreal channels were optimized out.
  246. */
  247. static int got_optimized_out(struct ast_channel *ast, struct ast_unreal_pvt *p)
  248. {
  249. int res = 0;
  250. /* Do a few conditional checks early on just to see if this optimization is possible */
  251. if (ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION) || !p->chan || !p->owner) {
  252. return res;
  253. }
  254. if (ast == p->owner) {
  255. res = ast_bridge_unreal_optimize_out(p->owner, p->chan, p);
  256. } else if (ast == p->chan) {
  257. res = ast_bridge_unreal_optimize_out(p->chan, p->owner, p);
  258. }
  259. return res;
  260. }
  261. struct ast_frame *ast_unreal_read(struct ast_channel *ast)
  262. {
  263. return &ast_null_frame;
  264. }
  265. int ast_unreal_write(struct ast_channel *ast, struct ast_frame *f)
  266. {
  267. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  268. int res = -1;
  269. if (!p) {
  270. return -1;
  271. }
  272. /* Just queue for delivery to the other side */
  273. ao2_ref(p, 1);
  274. ao2_lock(p);
  275. switch (f->frametype) {
  276. case AST_FRAME_VOICE:
  277. case AST_FRAME_VIDEO:
  278. if (got_optimized_out(ast, p)) {
  279. break;
  280. }
  281. /* fall through */
  282. default:
  283. res = unreal_queue_frame(p, AST_UNREAL_IS_OUTBOUND(ast, p), f, ast, 1);
  284. break;
  285. }
  286. ao2_unlock(p);
  287. ao2_ref(p, -1);
  288. return res;
  289. }
  290. int ast_unreal_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  291. {
  292. struct ast_unreal_pvt *p = ast_channel_tech_pvt(newchan);
  293. struct ast_bridge *bridge_owner;
  294. struct ast_bridge *bridge_chan;
  295. if (!p) {
  296. return -1;
  297. }
  298. ao2_lock(p);
  299. if ((p->owner != oldchan) && (p->chan != oldchan)) {
  300. ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
  301. ao2_unlock(p);
  302. return -1;
  303. }
  304. if (p->owner == oldchan) {
  305. p->owner = newchan;
  306. } else {
  307. p->chan = newchan;
  308. }
  309. if (ast_check_hangup(newchan) || !p->owner || !p->chan) {
  310. ao2_unlock(p);
  311. return 0;
  312. }
  313. /* Do not let a masquerade cause an unreal channel to be bridged to itself! */
  314. bridge_owner = ast_channel_internal_bridge(p->owner);
  315. bridge_chan = ast_channel_internal_bridge(p->chan);
  316. if (bridge_owner && bridge_owner == bridge_chan) {
  317. ast_log(LOG_WARNING, "You can not bridge an unreal channel (%s) to itself!\n",
  318. ast_channel_name(newchan));
  319. ao2_unlock(p);
  320. ast_queue_hangup(newchan);
  321. return -1;
  322. }
  323. ao2_unlock(p);
  324. return 0;
  325. }
  326. /*!
  327. * \internal
  328. * \brief Queue up a frame representing the indication as a control frame.
  329. * \since 12.0.0
  330. *
  331. * \param p Unreal private structure.
  332. * \param ast Channel indicating the condition.
  333. * \param condition What is being indicated.
  334. * \param data Extra data.
  335. * \param datalen Length of extra data.
  336. *
  337. * \retval 0 on success.
  338. * \retval AST_T38_REQUEST_PARMS if successful and condition is AST_CONTROL_T38_PARAMETERS.
  339. * \retval -1 on error.
  340. */
  341. static int unreal_queue_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition, const void *data, size_t datalen)
  342. {
  343. int res = 0;
  344. int isoutbound;
  345. ao2_lock(p);
  346. /*
  347. * Block -1 stop tones events if we are to be optimized out. We
  348. * don't need a flurry of these events on an unreal channel chain
  349. * when initially connected to slow the optimization process.
  350. */
  351. if (0 <= condition || ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION)) {
  352. struct ast_frame f = {
  353. .frametype = AST_FRAME_CONTROL,
  354. .subclass.integer = condition,
  355. .data.ptr = (void *) data,
  356. .datalen = datalen,
  357. };
  358. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  359. res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
  360. if (!res
  361. && condition == AST_CONTROL_T38_PARAMETERS
  362. && datalen == sizeof(struct ast_control_t38_parameters)) {
  363. const struct ast_control_t38_parameters *parameters = data;
  364. if (parameters->request_response == AST_T38_REQUEST_PARMS) {
  365. res = AST_T38_REQUEST_PARMS;
  366. }
  367. }
  368. } else {
  369. ast_debug(4, "Blocked indication %d\n", condition);
  370. }
  371. ao2_unlock(p);
  372. return res;
  373. }
  374. /*!
  375. * \internal
  376. * \brief Handle COLP and redirecting conditions.
  377. * \since 12.0.0
  378. *
  379. * \param p Unreal private structure.
  380. * \param ast Channel indicating the condition.
  381. * \param condition What is being indicated.
  382. *
  383. * \retval 0 on success.
  384. * \retval -1 on error.
  385. */
  386. static int unreal_colp_redirect_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition)
  387. {
  388. struct ast_channel *my_chan;
  389. struct ast_channel *my_owner;
  390. struct ast_channel *this_channel;
  391. struct ast_channel *the_other_channel;
  392. int isoutbound;
  393. int res = 0;
  394. unsigned char frame_data[1024];
  395. struct ast_frame f = {
  396. .frametype = AST_FRAME_CONTROL,
  397. .subclass.integer = condition,
  398. .data.ptr = frame_data,
  399. };
  400. /*
  401. * A connected line update frame may only contain a partial
  402. * amount of data, such as just a source, or just a ton, and not
  403. * the full amount of information. However, the collected
  404. * information is all stored in the outgoing channel's
  405. * connectedline structure, so when receiving a connected line
  406. * update on an outgoing unreal channel, we need to transmit the
  407. * collected connected line information instead of whatever
  408. * happens to be in this control frame. The same applies for
  409. * redirecting information, which is why it is handled here as
  410. * well.
  411. */
  412. ast_channel_unlock(ast);
  413. ast_unreal_lock_all(p, &my_chan, &my_owner);
  414. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  415. if (isoutbound) {
  416. this_channel = p->chan;
  417. the_other_channel = p->owner;
  418. } else {
  419. this_channel = p->owner;
  420. the_other_channel = p->chan;
  421. }
  422. if (the_other_channel) {
  423. if (condition == AST_CONTROL_CONNECTED_LINE) {
  424. ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel),
  425. ast_channel_connected(this_channel));
  426. f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data),
  427. ast_channel_connected(this_channel), NULL);
  428. } else {
  429. f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data),
  430. ast_channel_redirecting(this_channel), NULL);
  431. }
  432. }
  433. if (my_chan) {
  434. ast_channel_unlock(my_chan);
  435. ast_channel_unref(my_chan);
  436. }
  437. if (my_owner) {
  438. ast_channel_unlock(my_owner);
  439. ast_channel_unref(my_owner);
  440. }
  441. if (the_other_channel) {
  442. res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
  443. }
  444. ao2_unlock(p);
  445. ast_channel_lock(ast);
  446. return res;
  447. }
  448. int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
  449. {
  450. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  451. int res = 0;
  452. if (!p) {
  453. return -1;
  454. }
  455. ao2_ref(p, 1); /* ref for unreal_queue_frame */
  456. switch (condition) {
  457. case AST_CONTROL_MASQUERADE_NOTIFY:
  458. /*
  459. * Always block this because this is the channel being
  460. * masqueraded; not anything down the chain.
  461. */
  462. break;
  463. case AST_CONTROL_CONNECTED_LINE:
  464. case AST_CONTROL_REDIRECTING:
  465. res = unreal_colp_redirect_indicate(p, ast, condition);
  466. break;
  467. case AST_CONTROL_HOLD:
  468. if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
  469. ast_moh_start(ast, data, NULL);
  470. break;
  471. }
  472. res = unreal_queue_indicate(p, ast, condition, data, datalen);
  473. break;
  474. case AST_CONTROL_UNHOLD:
  475. if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
  476. ast_moh_stop(ast);
  477. break;
  478. }
  479. res = unreal_queue_indicate(p, ast, condition, data, datalen);
  480. break;
  481. default:
  482. res = unreal_queue_indicate(p, ast, condition, data, datalen);
  483. break;
  484. }
  485. ao2_ref(p, -1);
  486. return res;
  487. }
  488. int ast_unreal_digit_begin(struct ast_channel *ast, char digit)
  489. {
  490. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  491. int res = -1;
  492. struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
  493. int isoutbound;
  494. if (!p) {
  495. return -1;
  496. }
  497. ao2_ref(p, 1); /* ref for unreal_queue_frame */
  498. ao2_lock(p);
  499. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  500. f.subclass.integer = digit;
  501. res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
  502. ao2_unlock(p);
  503. ao2_ref(p, -1);
  504. return res;
  505. }
  506. int ast_unreal_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
  507. {
  508. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  509. int res = -1;
  510. struct ast_frame f = { AST_FRAME_DTMF_END, };
  511. int isoutbound;
  512. if (!p) {
  513. return -1;
  514. }
  515. ao2_ref(p, 1); /* ref for unreal_queue_frame */
  516. ao2_lock(p);
  517. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  518. f.subclass.integer = digit;
  519. f.len = duration;
  520. res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
  521. ao2_unlock(p);
  522. ao2_ref(p, -1);
  523. return res;
  524. }
  525. int ast_unreal_sendtext(struct ast_channel *ast, const char *text)
  526. {
  527. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  528. int res = -1;
  529. struct ast_frame f = { AST_FRAME_TEXT, };
  530. int isoutbound;
  531. if (!p) {
  532. return -1;
  533. }
  534. ao2_ref(p, 1); /* ref for unreal_queue_frame */
  535. ao2_lock(p);
  536. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  537. f.data.ptr = (char *) text;
  538. f.datalen = strlen(text) + 1;
  539. res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
  540. ao2_unlock(p);
  541. ao2_ref(p, -1);
  542. return res;
  543. }
  544. int ast_unreal_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
  545. {
  546. struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
  547. int res = -1;
  548. struct ast_frame f = { AST_FRAME_HTML, };
  549. int isoutbound;
  550. if (!p) {
  551. return -1;
  552. }
  553. ao2_ref(p, 1); /* ref for unreal_queue_frame */
  554. ao2_lock(p);
  555. isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
  556. f.subclass.integer = subclass;
  557. f.data.ptr = (char *)data;
  558. f.datalen = datalen;
  559. res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
  560. ao2_unlock(p);
  561. ao2_ref(p, -1);
  562. return res;
  563. }
  564. void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
  565. {
  566. struct ast_var_t *varptr;
  567. struct ast_var_t *clone_var;
  568. /*
  569. * Note that cid_num and cid_name aren't passed in the
  570. * ast_channel_alloc calls in ast_unreal_new_channels(). It's
  571. * done here instead.
  572. */
  573. ast_party_redirecting_copy(ast_channel_redirecting(semi2), ast_channel_redirecting(semi1));
  574. ast_party_dialed_copy(ast_channel_dialed(semi2), ast_channel_dialed(semi1));
  575. ast_connected_line_copy_to_caller(ast_channel_caller(semi2), ast_channel_connected(semi1));
  576. ast_connected_line_copy_from_caller(ast_channel_connected(semi2), ast_channel_caller(semi1));
  577. ast_channel_language_set(semi2, ast_channel_language(semi1));
  578. ast_channel_accountcode_set(semi2, ast_channel_accountcode(semi1));
  579. ast_channel_musicclass_set(semi2, ast_channel_musicclass(semi1));
  580. ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1));
  581. /*
  582. * Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's
  583. * set on the queue/dial call request in the dialplan.
  584. */
  585. if (ast_channel_hangupcause(semi1) == AST_CAUSE_ANSWERED_ELSEWHERE) {
  586. ast_channel_hangupcause_set(semi2, AST_CAUSE_ANSWERED_ELSEWHERE);
  587. }
  588. /*
  589. * Copy the channel variables from the semi1 channel to the
  590. * outgoing channel.
  591. *
  592. * Note that due to certain assumptions, they MUST be in the
  593. * same order.
  594. */
  595. AST_LIST_TRAVERSE(ast_channel_varshead(semi1), varptr, entries) {
  596. clone_var = ast_var_assign(varptr->name, varptr->value);
  597. if (clone_var) {
  598. AST_LIST_INSERT_TAIL(ast_channel_varshead(semi2), clone_var, entries);
  599. ast_channel_publish_varset(semi2, ast_var_full_name(clone_var),
  600. ast_var_value(clone_var));
  601. }
  602. }
  603. ast_channel_datastore_inherit(semi1, semi2);
  604. }
  605. int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
  606. {
  607. struct ast_bridge_features *features;
  608. struct ast_channel *chan;
  609. struct ast_channel *owner;
  610. RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);
  611. RAII_VAR(struct ast_callid *, bridge_callid, NULL, ast_callid_cleanup);
  612. ast_bridge_lock(bridge);
  613. bridge_callid = bridge->callid ? ast_callid_ref(bridge->callid) : NULL;
  614. ast_bridge_unlock(bridge);
  615. {
  616. SCOPED_CHANNELLOCK(lock, ast);
  617. p = ast_channel_tech_pvt(ast);
  618. if (!p) {
  619. return -1;
  620. }
  621. ao2_ref(p, +1);
  622. }
  623. {
  624. SCOPED_AO2LOCK(lock, p);
  625. chan = p->chan;
  626. if (!chan) {
  627. return -1;
  628. }
  629. owner = p->owner;
  630. if (!owner) {
  631. return -1;
  632. }
  633. ast_channel_ref(chan);
  634. ast_channel_ref(owner);
  635. }
  636. if (bridge_callid) {
  637. struct ast_callid *chan_callid;
  638. struct ast_callid *owner_callid;
  639. /* chan side call ID setting */
  640. ast_channel_lock(chan);
  641. chan_callid = ast_channel_callid(chan);
  642. if (!chan_callid) {
  643. ast_channel_callid_set(chan, bridge_callid);
  644. }
  645. ast_channel_unlock(chan);
  646. ast_callid_cleanup(chan_callid);
  647. /* owner side call ID setting */
  648. ast_channel_lock(owner);
  649. owner_callid = ast_channel_callid(owner);
  650. if (!owner_callid) {
  651. ast_channel_callid_set(owner, bridge_callid);
  652. }
  653. ast_channel_unlock(owner);
  654. ast_callid_cleanup(owner_callid);
  655. }
  656. /* We are done with the owner now that its call ID matches the bridge */
  657. ast_channel_unref(owner);
  658. owner = NULL;
  659. features = ast_bridge_features_new();
  660. if (!features) {
  661. ast_channel_unref(chan);
  662. return -1;
  663. }
  664. ast_set_flag(&features->feature_flags, flags);
  665. /* Impart the semi2 channel into the bridge */
  666. if (ast_bridge_impart(bridge, chan, NULL, features,
  667. AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
  668. ast_bridge_features_destroy(features);
  669. ast_channel_unref(chan);
  670. return -1;
  671. }
  672. ao2_lock(p);
  673. ast_set_flag(p, AST_UNREAL_CARETAKER_THREAD);
  674. ao2_unlock(p);
  675. ast_channel_unref(chan);
  676. return 0;
  677. }
  678. int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
  679. {
  680. int hangup_chan = 0;
  681. int res = 0;
  682. int cause;
  683. struct ast_channel *owner = NULL;
  684. struct ast_channel *chan = NULL;
  685. /* the pvt isn't going anywhere, it has a ref */
  686. ast_channel_unlock(ast);
  687. /* lock everything */
  688. ast_unreal_lock_all(p, &chan, &owner);
  689. if (ast != chan && ast != owner) {
  690. res = -1;
  691. goto unreal_hangup_cleanup;
  692. }
  693. cause = ast_channel_hangupcause(ast);
  694. if (ast == p->chan) {
  695. /* Outgoing side is hanging up. */
  696. ast_clear_flag(p, AST_UNREAL_CARETAKER_THREAD);
  697. p->chan = NULL;
  698. if (p->owner) {
  699. const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
  700. if (status) {
  701. ast_channel_hangupcause_set(p->owner, cause);
  702. pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
  703. }
  704. ast_queue_hangup_with_cause(p->owner, cause);
  705. }
  706. } else {
  707. /* Owner side is hanging up. */
  708. p->owner = NULL;
  709. if (p->chan) {
  710. if (cause == AST_CAUSE_ANSWERED_ELSEWHERE) {
  711. ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
  712. ast_debug(2, "%s has AST_CAUSE_ANSWERED_ELSEWHERE set.\n",
  713. ast_channel_name(p->chan));
  714. }
  715. if (!ast_test_flag(p, AST_UNREAL_CARETAKER_THREAD)) {
  716. /*
  717. * Need to actually hangup p->chan since nothing else is taking
  718. * care of it.
  719. */
  720. hangup_chan = 1;
  721. } else {
  722. ast_queue_hangup_with_cause(p->chan, cause);
  723. }
  724. }
  725. }
  726. /* this is one of our locked channels, doesn't matter which */
  727. ast_channel_tech_pvt_set(ast, NULL);
  728. ao2_ref(p, -1);
  729. unreal_hangup_cleanup:
  730. ao2_unlock(p);
  731. if (owner) {
  732. ast_channel_unlock(owner);
  733. ast_channel_unref(owner);
  734. }
  735. if (chan) {
  736. ast_channel_unlock(chan);
  737. if (hangup_chan) {
  738. ast_hangup(chan);
  739. }
  740. ast_channel_unref(chan);
  741. }
  742. /* leave with the channel locked that came in */
  743. ast_channel_lock(ast);
  744. return res;
  745. }
  746. void ast_unreal_destructor(void *vdoomed)
  747. {
  748. struct ast_unreal_pvt *doomed = vdoomed;
  749. doomed->reqcap = ast_format_cap_destroy(doomed->reqcap);
  750. }
  751. struct ast_unreal_pvt *ast_unreal_alloc(size_t size, ao2_destructor_fn destructor, struct ast_format_cap *cap)
  752. {
  753. struct ast_unreal_pvt *unreal;
  754. static const struct ast_jb_conf jb_conf = {
  755. .flags = 0,
  756. .max_size = -1,
  757. .resync_threshold = -1,
  758. .impl = "",
  759. .target_extra = -1,
  760. };
  761. unreal = ao2_alloc(size, destructor);
  762. if (!unreal) {
  763. return NULL;
  764. }
  765. unreal->reqcap = ast_format_cap_dup(cap);
  766. if (!unreal->reqcap) {
  767. ao2_ref(unreal, -1);
  768. return NULL;
  769. }
  770. memcpy(&unreal->jb_conf, &jb_conf, sizeof(unreal->jb_conf));
  771. return unreal;
  772. }
  773. struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
  774. const struct ast_channel_tech *tech, int semi1_state, int semi2_state,
  775. const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
  776. const struct ast_channel *requestor, struct ast_callid *callid)
  777. {
  778. struct ast_channel *owner;
  779. struct ast_channel *chan;
  780. struct ast_format fmt;
  781. struct ast_assigned_ids id1 = {NULL, NULL};
  782. struct ast_assigned_ids id2 = {NULL, NULL};
  783. int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
  784. /* set unique ids for the two channels */
  785. if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
  786. id1.uniqueid = assignedids->uniqueid;
  787. id2.uniqueid = assignedids->uniqueid2;
  788. }
  789. /* if id1 given but not id2, use default of id1;2 */
  790. if (id1.uniqueid && ast_strlen_zero(id2.uniqueid)) {
  791. char *uniqueid2;
  792. uniqueid2 = ast_alloca(strlen(id1.uniqueid) + 3);
  793. strcpy(uniqueid2, id1.uniqueid);/* Safe */
  794. strcat(uniqueid2, ";2");/* Safe */
  795. id2.uniqueid = uniqueid2;
  796. }
  797. /*
  798. * Allocate two new Asterisk channels
  799. *
  800. * Make sure that the ;2 channel gets the same linkedid as ;1.
  801. * You can't pass linkedid to both allocations since if linkedid
  802. * isn't set, then each channel will generate its own linkedid.
  803. */
  804. owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
  805. exten, context, &id1, requestor, 0,
  806. "%s/%s-%08x;1", tech->type, p->name, (unsigned)generated_seqno);
  807. if (!owner) {
  808. ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n");
  809. return NULL;
  810. }
  811. if (callid) {
  812. ast_channel_callid_set(owner, callid);
  813. }
  814. ast_channel_tech_set(owner, tech);
  815. ao2_ref(p, +1);
  816. ast_channel_tech_pvt_set(owner, p);
  817. ast_format_cap_copy(ast_channel_nativeformats(owner), p->reqcap);
  818. /* Determine our read/write format and set it on each channel */
  819. ast_best_codec(p->reqcap, &fmt);
  820. ast_format_copy(ast_channel_writeformat(owner), &fmt);
  821. ast_format_copy(ast_channel_rawwriteformat(owner), &fmt);
  822. ast_format_copy(ast_channel_readformat(owner), &fmt);
  823. ast_format_copy(ast_channel_rawreadformat(owner), &fmt);
  824. ast_set_flag(ast_channel_flags(owner), AST_FLAG_DISABLE_DEVSTATE_CACHE);
  825. ast_jb_configure(owner, &p->jb_conf);
  826. if (ast_channel_cc_params_init(owner, requestor
  827. ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) {
  828. ao2_ref(p, -1);
  829. ast_channel_tech_pvt_set(owner, NULL);
  830. ast_channel_unlock(owner);
  831. ast_channel_release(owner);
  832. return NULL;
  833. }
  834. p->owner = owner;
  835. ast_channel_unlock(owner);
  836. chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
  837. exten, context, &id2, owner, 0,
  838. "%s/%s-%08x;2", tech->type, p->name, (unsigned)generated_seqno);
  839. if (!chan) {
  840. ast_log(LOG_WARNING, "Unable to allocate chan channel structure\n");
  841. ao2_ref(p, -1);
  842. ast_channel_tech_pvt_set(owner, NULL);
  843. ast_channel_release(owner);
  844. return NULL;
  845. }
  846. if (callid) {
  847. ast_channel_callid_set(chan, callid);
  848. }
  849. ast_channel_tech_set(chan, tech);
  850. ao2_ref(p, +1);
  851. ast_channel_tech_pvt_set(chan, p);
  852. ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
  853. /* Format was already determined when setting up owner */
  854. ast_format_copy(ast_channel_writeformat(chan), &fmt);
  855. ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
  856. ast_format_copy(ast_channel_readformat(chan), &fmt);
  857. ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
  858. ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
  859. p->chan = chan;
  860. ast_channel_unlock(chan);
  861. return owner;
  862. }