chan_bridge.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2008, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@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. * \author Joshua Colp <jcolp@digium.com>
  21. *
  22. * \brief Bridge Interaction Channel
  23. *
  24. * \ingroup channel_drivers
  25. */
  26. /*** MODULEINFO
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  31. #include <fcntl.h>
  32. #include <sys/signal.h>
  33. #include "asterisk/lock.h"
  34. #include "asterisk/channel.h"
  35. #include "asterisk/config.h"
  36. #include "asterisk/module.h"
  37. #include "asterisk/pbx.h"
  38. #include "asterisk/sched.h"
  39. #include "asterisk/io.h"
  40. #include "asterisk/acl.h"
  41. #include "asterisk/callerid.h"
  42. #include "asterisk/file.h"
  43. #include "asterisk/cli.h"
  44. #include "asterisk/app.h"
  45. #include "asterisk/bridging.h"
  46. #include "asterisk/astobj2.h"
  47. static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
  48. static int bridge_call(struct ast_channel *ast, char *dest, int timeout);
  49. static int bridge_hangup(struct ast_channel *ast);
  50. static struct ast_frame *bridge_read(struct ast_channel *ast);
  51. static int bridge_write(struct ast_channel *ast, struct ast_frame *f);
  52. static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
  53. static struct ast_channel_tech bridge_tech = {
  54. .type = "Bridge",
  55. .description = "Bridge Interaction Channel",
  56. .requester = bridge_request,
  57. .call = bridge_call,
  58. .hangup = bridge_hangup,
  59. .read = bridge_read,
  60. .write = bridge_write,
  61. .write_video = bridge_write,
  62. .exception = bridge_read,
  63. .bridged_channel = bridge_bridgedchannel,
  64. };
  65. struct bridge_pvt {
  66. struct ast_channel *input; /*!< Input channel - talking to source */
  67. struct ast_channel *output; /*!< Output channel - talking to bridge */
  68. };
  69. /*! \brief Called when the user of this channel wants to get the actual channel in the bridge */
  70. static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
  71. {
  72. struct bridge_pvt *p = chan->tech_pvt;
  73. return (chan == p->input) ? p->output : bridge;
  74. }
  75. /*! \brief Called when a frame should be read from the channel */
  76. static struct ast_frame *bridge_read(struct ast_channel *ast)
  77. {
  78. return &ast_null_frame;
  79. }
  80. /*! \brief Called when a frame should be written out to a channel */
  81. static int bridge_write(struct ast_channel *ast, struct ast_frame *f)
  82. {
  83. struct bridge_pvt *p = ast->tech_pvt;
  84. struct ast_channel *other = NULL;
  85. ao2_lock(p);
  86. /* only write frames to output. */
  87. if (p->input == ast) {
  88. other = p->output;
  89. if (other) {
  90. ast_channel_ref(other);
  91. }
  92. }
  93. ao2_unlock(p);
  94. if (other) {
  95. ast_channel_unlock(ast);
  96. ast_queue_frame(other, f);
  97. ast_channel_lock(ast);
  98. other = ast_channel_unref(other);
  99. }
  100. return 0;
  101. }
  102. /*! \brief Called when the channel should actually be dialed */
  103. static int bridge_call(struct ast_channel *ast, char *dest, int timeout)
  104. {
  105. struct bridge_pvt *p = ast->tech_pvt;
  106. /* If no bridge has been provided on the input channel, bail out */
  107. if (!ast->bridge) {
  108. return -1;
  109. }
  110. /* Impart the output channel upon the given bridge of the input channel */
  111. ast_bridge_impart(p->input->bridge, p->output, NULL, NULL, 0);
  112. return 0;
  113. }
  114. /*! \brief Called when a channel should be hung up */
  115. static int bridge_hangup(struct ast_channel *ast)
  116. {
  117. struct bridge_pvt *p = ast->tech_pvt;
  118. if (!p) {
  119. return 0;
  120. }
  121. ao2_lock(p);
  122. if (p->input == ast) {
  123. p->input = NULL;
  124. } else if (p->output == ast) {
  125. p->output = NULL;
  126. }
  127. ao2_unlock(p);
  128. ast->tech_pvt = NULL;
  129. ao2_ref(p, -1);
  130. return 0;
  131. }
  132. /*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
  133. static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
  134. {
  135. struct bridge_pvt *p = NULL;
  136. struct ast_format slin;
  137. /* Try to allocate memory for our very minimal pvt structure */
  138. if (!(p = ao2_alloc(sizeof(*p), NULL))) {
  139. return NULL;
  140. }
  141. /* Try to grab two Asterisk channels to use as input and output channels */
  142. if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) {
  143. ao2_ref(p, -1);
  144. return NULL;
  145. }
  146. if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) {
  147. p->input = ast_channel_release(p->input);
  148. ao2_ref(p, -1);
  149. return NULL;
  150. }
  151. /* Setup parameters on both new channels */
  152. p->input->tech = p->output->tech = &bridge_tech;
  153. ao2_ref(p, 2);
  154. p->input->tech_pvt = p->output->tech_pvt = p;
  155. ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
  156. ast_format_cap_add(p->input->nativeformats, &slin);
  157. ast_format_cap_add(p->output->nativeformats, &slin);
  158. ast_format_copy(&p->input->readformat, &slin);
  159. ast_format_copy(&p->output->readformat, &slin);
  160. ast_format_copy(&p->input->rawreadformat, &slin);
  161. ast_format_copy(&p->output->rawreadformat, &slin);
  162. ast_format_copy(&p->input->writeformat, &slin);
  163. ast_format_copy(&p->output->writeformat, &slin);
  164. ast_format_copy(&p->input->rawwriteformat, &slin);
  165. ast_format_copy(&p->output->rawwriteformat, &slin);
  166. ast_answer(p->output);
  167. ast_answer(p->input);
  168. /* remove the reference from the alloc. The channels now own the pvt. */
  169. ao2_ref(p, -1);
  170. return p->input;
  171. }
  172. /*! \brief Load module into PBX, register channel */
  173. static int load_module(void)
  174. {
  175. if (!(bridge_tech.capabilities = ast_format_cap_alloc())) {
  176. return AST_MODULE_LOAD_FAILURE;
  177. }
  178. ast_format_cap_add_all(bridge_tech.capabilities);
  179. /* Make sure we can register our channel type */
  180. if (ast_channel_register(&bridge_tech)) {
  181. ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
  182. return AST_MODULE_LOAD_FAILURE;
  183. }
  184. return AST_MODULE_LOAD_SUCCESS;
  185. }
  186. /*! \brief Unload the bridge interaction channel from Asterisk */
  187. static int unload_module(void)
  188. {
  189. ast_channel_unregister(&bridge_tech);
  190. bridge_tech.capabilities = ast_format_cap_destroy(bridge_tech.capabilities);
  191. return 0;
  192. }
  193. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Bridge Interaction Channel",
  194. .load = load_module,
  195. .unload = unload_module,
  196. .load_pri = AST_MODPRI_CHANNEL_DRIVER,
  197. );