chan_rtp.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2009 - 2014, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@digium.com>
  7. * Andreas 'MacBrody' Brodmann <andreas.brodmann@gmail.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. * \author Joshua Colp <jcolp@digium.com>
  22. * \author Andreas 'MacBrody' Broadmann <andreas.brodmann@gmail.com>
  23. *
  24. * \brief RTP (Multicast and Unicast) Media Channel
  25. *
  26. * \ingroup channel_drivers
  27. */
  28. /*** MODULEINFO
  29. <depend>res_rtp_multicast</depend>
  30. <support_level>core</support_level>
  31. ***/
  32. #include "asterisk.h"
  33. ASTERISK_REGISTER_FILE()
  34. #include "asterisk/channel.h"
  35. #include "asterisk/module.h"
  36. #include "asterisk/pbx.h"
  37. #include "asterisk/acl.h"
  38. #include "asterisk/app.h"
  39. #include "asterisk/rtp_engine.h"
  40. #include "asterisk/causes.h"
  41. #include "asterisk/format_cache.h"
  42. #include "asterisk/multicast_rtp.h"
  43. /* Forward declarations */
  44. static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
  45. static struct ast_channel *unicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
  46. static int rtp_call(struct ast_channel *ast, const char *dest, int timeout);
  47. static int rtp_hangup(struct ast_channel *ast);
  48. static struct ast_frame *rtp_read(struct ast_channel *ast);
  49. static int rtp_write(struct ast_channel *ast, struct ast_frame *f);
  50. /* Multicast channel driver declaration */
  51. static struct ast_channel_tech multicast_rtp_tech = {
  52. .type = "MulticastRTP",
  53. .description = "Multicast RTP Paging Channel Driver",
  54. .requester = multicast_rtp_request,
  55. .call = rtp_call,
  56. .hangup = rtp_hangup,
  57. .read = rtp_read,
  58. .write = rtp_write,
  59. };
  60. /* Unicast channel driver declaration */
  61. static struct ast_channel_tech unicast_rtp_tech = {
  62. .type = "UnicastRTP",
  63. .description = "Unicast RTP Media Channel Driver",
  64. .requester = unicast_rtp_request,
  65. .call = rtp_call,
  66. .hangup = rtp_hangup,
  67. .read = rtp_read,
  68. .write = rtp_write,
  69. };
  70. /*! \brief Function called when we should read a frame from the channel */
  71. static struct ast_frame *rtp_read(struct ast_channel *ast)
  72. {
  73. struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
  74. int fdno = ast_channel_fdno(ast);
  75. switch (fdno) {
  76. case 0:
  77. return ast_rtp_instance_read(instance, 0);
  78. default:
  79. return &ast_null_frame;
  80. }
  81. }
  82. /*! \brief Function called when we should write a frame to the channel */
  83. static int rtp_write(struct ast_channel *ast, struct ast_frame *f)
  84. {
  85. struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
  86. return ast_rtp_instance_write(instance, f);
  87. }
  88. /*! \brief Function called when we should actually call the destination */
  89. static int rtp_call(struct ast_channel *ast, const char *dest, int timeout)
  90. {
  91. struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
  92. ast_queue_control(ast, AST_CONTROL_ANSWER);
  93. return ast_rtp_instance_activate(instance);
  94. }
  95. /*! \brief Function called when we should hang the channel up */
  96. static int rtp_hangup(struct ast_channel *ast)
  97. {
  98. struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
  99. ast_rtp_instance_destroy(instance);
  100. ast_channel_tech_pvt_set(ast, NULL);
  101. return 0;
  102. }
  103. static struct ast_format *derive_format_from_cap(struct ast_format_cap *cap)
  104. {
  105. struct ast_format *fmt = ast_format_cap_get_format(cap, 0);
  106. if (ast_format_cap_count(cap) == 1 && fmt == ast_format_slin) {
  107. /*
  108. * Because we have no SDP, we must use one of the static RTP payload
  109. * assignments. Signed linear @ 8kHz does not map, so if that is our
  110. * only capability, we force μ-law instead.
  111. */
  112. fmt = ast_format_ulaw;
  113. }
  114. return fmt;
  115. }
  116. /*! \brief Function called when we should prepare to call the multicast destination */
  117. static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
  118. {
  119. char *parse;
  120. struct ast_rtp_instance *instance;
  121. struct ast_sockaddr control_address;
  122. struct ast_sockaddr destination_address;
  123. struct ast_channel *chan;
  124. struct ast_format_cap *caps = NULL;
  125. struct ast_format *fmt = NULL;
  126. AST_DECLARE_APP_ARGS(args,
  127. AST_APP_ARG(type);
  128. AST_APP_ARG(destination);
  129. AST_APP_ARG(control);
  130. AST_APP_ARG(options);
  131. );
  132. struct ast_multicast_rtp_options *mcast_options = NULL;
  133. if (ast_strlen_zero(data)) {
  134. ast_log(LOG_ERROR, "A multicast type and destination must be given to the 'MulticastRTP' channel\n");
  135. goto failure;
  136. }
  137. parse = ast_strdupa(data);
  138. AST_NONSTANDARD_APP_ARGS(args, parse, '/');
  139. if (ast_strlen_zero(args.type)) {
  140. ast_log(LOG_ERROR, "Type is required for the 'MulticastRTP' channel\n");
  141. goto failure;
  142. }
  143. if (ast_strlen_zero(args.destination)) {
  144. ast_log(LOG_ERROR, "Destination is required for the 'MulticastRTP' channel\n");
  145. goto failure;
  146. }
  147. if (!ast_sockaddr_parse(&destination_address, args.destination, PARSE_PORT_REQUIRE)) {
  148. ast_log(LOG_ERROR, "Destination address '%s' could not be parsed\n",
  149. args.destination);
  150. goto failure;
  151. }
  152. ast_sockaddr_setnull(&control_address);
  153. if (!ast_strlen_zero(args.control)
  154. && !ast_sockaddr_parse(&control_address, args.control, PARSE_PORT_REQUIRE)) {
  155. ast_log(LOG_ERROR, "Control address '%s' could not be parsed\n", args.control);
  156. goto failure;
  157. }
  158. mcast_options = ast_multicast_rtp_create_options(args.type, args.options);
  159. if (!mcast_options) {
  160. goto failure;
  161. }
  162. fmt = ast_multicast_rtp_options_get_format(mcast_options);
  163. if (!fmt) {
  164. fmt = derive_format_from_cap(cap);
  165. }
  166. if (!fmt) {
  167. ast_log(LOG_ERROR, "No codec available for sending RTP to '%s'\n",
  168. args.destination);
  169. goto failure;
  170. }
  171. caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
  172. if (!caps) {
  173. goto failure;
  174. }
  175. instance = ast_rtp_instance_new("multicast", NULL, &control_address, mcast_options);
  176. if (!instance) {
  177. ast_log(LOG_ERROR,
  178. "Could not create '%s' multicast RTP instance for sending media to '%s'\n",
  179. args.type, args.destination);
  180. goto failure;
  181. }
  182. chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
  183. requestor, 0, "MulticastRTP/%p", instance);
  184. if (!chan) {
  185. ast_rtp_instance_destroy(instance);
  186. goto failure;
  187. }
  188. ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(chan));
  189. ast_rtp_instance_set_remote_address(instance, &destination_address);
  190. ast_channel_tech_set(chan, &multicast_rtp_tech);
  191. ast_format_cap_append(caps, fmt, 0);
  192. ast_channel_nativeformats_set(chan, caps);
  193. ast_channel_set_writeformat(chan, fmt);
  194. ast_channel_set_rawwriteformat(chan, fmt);
  195. ast_channel_set_readformat(chan, fmt);
  196. ast_channel_set_rawreadformat(chan, fmt);
  197. ast_channel_tech_pvt_set(chan, instance);
  198. ast_channel_unlock(chan);
  199. ao2_ref(fmt, -1);
  200. ao2_ref(caps, -1);
  201. ast_multicast_rtp_free_options(mcast_options);
  202. return chan;
  203. failure:
  204. ao2_cleanup(fmt);
  205. ao2_cleanup(caps);
  206. ast_multicast_rtp_free_options(mcast_options);
  207. *cause = AST_CAUSE_FAILURE;
  208. return NULL;
  209. }
  210. enum {
  211. OPT_RTP_CODEC = (1 << 0),
  212. OPT_RTP_ENGINE = (1 << 1),
  213. };
  214. enum {
  215. OPT_ARG_RTP_CODEC,
  216. OPT_ARG_RTP_ENGINE,
  217. /* note: this entry _MUST_ be the last one in the enum */
  218. OPT_ARG_ARRAY_SIZE
  219. };
  220. AST_APP_OPTIONS(unicast_rtp_options, BEGIN_OPTIONS
  221. /*! Set the codec to be used for unicast RTP */
  222. AST_APP_OPTION_ARG('c', OPT_RTP_CODEC, OPT_ARG_RTP_CODEC),
  223. /*! Set the RTP engine to use for unicast RTP */
  224. AST_APP_OPTION_ARG('e', OPT_RTP_ENGINE, OPT_ARG_RTP_ENGINE),
  225. END_OPTIONS );
  226. /*! \brief Function called when we should prepare to call the unicast destination */
  227. static struct ast_channel *unicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
  228. {
  229. char *parse;
  230. struct ast_rtp_instance *instance;
  231. struct ast_sockaddr address;
  232. struct ast_sockaddr local_address;
  233. struct ast_channel *chan;
  234. struct ast_format_cap *caps = NULL;
  235. struct ast_format *fmt = NULL;
  236. const char *engine_name;
  237. AST_DECLARE_APP_ARGS(args,
  238. AST_APP_ARG(destination);
  239. AST_APP_ARG(options);
  240. );
  241. struct ast_flags opts = { 0, };
  242. char *opt_args[OPT_ARG_ARRAY_SIZE];
  243. if (ast_strlen_zero(data)) {
  244. ast_log(LOG_ERROR, "Destination is required for the 'UnicastRTP' channel\n");
  245. goto failure;
  246. }
  247. parse = ast_strdupa(data);
  248. AST_NONSTANDARD_APP_ARGS(args, parse, '/');
  249. if (ast_strlen_zero(args.destination)) {
  250. ast_log(LOG_ERROR, "Destination is required for the 'UnicastRTP' channel\n");
  251. goto failure;
  252. }
  253. if (!ast_sockaddr_parse(&address, args.destination, PARSE_PORT_REQUIRE)) {
  254. ast_log(LOG_ERROR, "Destination '%s' could not be parsed\n", args.destination);
  255. goto failure;
  256. }
  257. if (!ast_strlen_zero(args.options)
  258. && ast_app_parse_options(unicast_rtp_options, &opts, opt_args,
  259. ast_strdupa(args.options))) {
  260. ast_log(LOG_ERROR, "'UnicastRTP' channel options '%s' parse error\n",
  261. args.options);
  262. goto failure;
  263. }
  264. if (ast_test_flag(&opts, OPT_RTP_CODEC)
  265. && !ast_strlen_zero(opt_args[OPT_ARG_RTP_CODEC])) {
  266. fmt = ast_format_cache_get(opt_args[OPT_ARG_RTP_CODEC]);
  267. if (!fmt) {
  268. ast_log(LOG_ERROR, "Codec '%s' not found for sending RTP to '%s'\n",
  269. opt_args[OPT_ARG_RTP_CODEC], args.destination);
  270. goto failure;
  271. }
  272. } else {
  273. fmt = derive_format_from_cap(cap);
  274. if (!fmt) {
  275. ast_log(LOG_ERROR, "No codec available for sending RTP to '%s'\n",
  276. args.destination);
  277. goto failure;
  278. }
  279. }
  280. caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
  281. if (!caps) {
  282. goto failure;
  283. }
  284. engine_name = S_COR(ast_test_flag(&opts, OPT_RTP_ENGINE),
  285. opt_args[OPT_ARG_RTP_ENGINE], "asterisk");
  286. ast_sockaddr_copy(&local_address, &address);
  287. if (ast_ouraddrfor(&address, &local_address)) {
  288. ast_log(LOG_ERROR, "Could not get our address for sending media to '%s'\n",
  289. args.destination);
  290. goto failure;
  291. }
  292. instance = ast_rtp_instance_new(engine_name, NULL, &local_address, NULL);
  293. if (!instance) {
  294. ast_log(LOG_ERROR,
  295. "Could not create %s RTP instance for sending media to '%s'\n",
  296. S_OR(engine_name, "default"), args.destination);
  297. goto failure;
  298. }
  299. chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
  300. requestor, 0, "UnicastRTP/%s-%p", args.destination, instance);
  301. if (!chan) {
  302. ast_rtp_instance_destroy(instance);
  303. goto failure;
  304. }
  305. ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(chan));
  306. ast_rtp_instance_set_remote_address(instance, &address);
  307. ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(instance, 0));
  308. ast_channel_tech_set(chan, &unicast_rtp_tech);
  309. ast_format_cap_append(caps, fmt, 0);
  310. ast_channel_nativeformats_set(chan, caps);
  311. ast_channel_set_writeformat(chan, fmt);
  312. ast_channel_set_rawwriteformat(chan, fmt);
  313. ast_channel_set_readformat(chan, fmt);
  314. ast_channel_set_rawreadformat(chan, fmt);
  315. ast_channel_tech_pvt_set(chan, instance);
  316. pbx_builtin_setvar_helper(chan, "UNICASTRTP_LOCAL_ADDRESS",
  317. ast_sockaddr_stringify_addr(&local_address));
  318. ast_rtp_instance_get_local_address(instance, &local_address);
  319. pbx_builtin_setvar_helper(chan, "UNICASTRTP_LOCAL_PORT",
  320. ast_sockaddr_stringify_port(&local_address));
  321. ast_channel_unlock(chan);
  322. ao2_ref(fmt, -1);
  323. ao2_ref(caps, -1);
  324. return chan;
  325. failure:
  326. ao2_cleanup(fmt);
  327. ao2_cleanup(caps);
  328. *cause = AST_CAUSE_FAILURE;
  329. return NULL;
  330. }
  331. /*! \brief Function called when our module is unloaded */
  332. static int unload_module(void)
  333. {
  334. ast_channel_unregister(&multicast_rtp_tech);
  335. ao2_cleanup(multicast_rtp_tech.capabilities);
  336. multicast_rtp_tech.capabilities = NULL;
  337. ast_channel_unregister(&unicast_rtp_tech);
  338. ao2_cleanup(unicast_rtp_tech.capabilities);
  339. unicast_rtp_tech.capabilities = NULL;
  340. return 0;
  341. }
  342. /*! \brief Function called when our module is loaded */
  343. static int load_module(void)
  344. {
  345. if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
  346. return AST_MODULE_LOAD_DECLINE;
  347. }
  348. ast_format_cap_append_by_type(multicast_rtp_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
  349. if (ast_channel_register(&multicast_rtp_tech)) {
  350. ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
  351. unload_module();
  352. return AST_MODULE_LOAD_DECLINE;
  353. }
  354. if (!(unicast_rtp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
  355. unload_module();
  356. return AST_MODULE_LOAD_DECLINE;
  357. }
  358. ast_format_cap_append_by_type(unicast_rtp_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
  359. if (ast_channel_register(&unicast_rtp_tech)) {
  360. ast_log(LOG_ERROR, "Unable to register channel class 'UnicastRTP'\n");
  361. unload_module();
  362. return AST_MODULE_LOAD_DECLINE;
  363. }
  364. return AST_MODULE_LOAD_SUCCESS;
  365. }
  366. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RTP Media Channel",
  367. .support_level = AST_MODULE_SUPPORT_CORE,
  368. .load = load_module,
  369. .unload = unload_module,
  370. .load_pri = AST_MODPRI_CHANNEL_DRIVER,
  371. );