rtpproxy_stream.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /* $Id: rtpproxy_stream.c,v 1.2 2008/11/04 22:28:04 sobomax Exp $
  2. *
  3. * Copyright (C) 2008 Sippy Software, Inc., http://www.sippysoft.com
  4. *
  5. * This file is part of ser, a free SIP server.
  6. *
  7. * ser is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version
  11. *
  12. * For a license to use the ser software under conditions
  13. * other than those described here, or to purchase support for this
  14. * software, please contact iptel.org by e-mail at the following addresses:
  15. * [email protected]
  16. *
  17. * ser is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. *
  26. */
  27. #include <stdio.h>
  28. #include <sys/uio.h>
  29. #include "../../ip_addr.h"
  30. #include "../../parser/msg_parser.h"
  31. #include "../../sr_module.h"
  32. #include "../../ut.h"
  33. #include "rtpproxy.h"
  34. #include "rtpproxy_funcs.h"
  35. int
  36. fixup_var_str_int(void **param, int param_no)
  37. {
  38. int ret;
  39. pv_elem_t *model;
  40. str s;
  41. if (param_no == 1) {
  42. model = NULL;
  43. s.s = (char *)(*param);
  44. s.len = strlen(s.s);
  45. if (pv_parse_format(&s, &model) < 0) {
  46. LM_ERR("wrong format[%s]!\n", (char *)(*param));
  47. return E_UNSPEC;
  48. }
  49. if (model == NULL) {
  50. LM_ERR("empty parameter!\n");
  51. return E_UNSPEC;
  52. }
  53. *param = (void *)model;
  54. } else if (param_no == 2) {
  55. /* According to
  56. * http://www.kamailio.org/docs/modules/1.5.x/nathelper.html#rtpproxy_stream2xxx
  57. * this could be -1 */
  58. s.s = (char *)(*param);
  59. s.len = strlen(s.s);
  60. if (str2sint(&s, &ret)==0) {
  61. pkg_free(*param);
  62. *param = (void *)(long)ret;
  63. } else {
  64. LM_ERR("bad number <%s>\n", (char *)(*param));
  65. return E_CFG;
  66. }
  67. }
  68. return 0;
  69. }
  70. static int
  71. rtpproxy_stream(struct sip_msg* msg, str *pname, int count, int stream2uac)
  72. {
  73. int nitems;
  74. str callid, from_tag, to_tag;
  75. struct rtpp_node *node;
  76. char cbuf[16];
  77. struct iovec v[] = {
  78. {NULL, 0},
  79. {cbuf, 0}, /* 1 P<count> */
  80. {" ", 1},
  81. {NULL, 0}, /* 3 callid */
  82. {" ", 1},
  83. {NULL, 0}, /* 5 pname */
  84. {" session ", 9},
  85. {NULL, 0}, /* 7 from tag */
  86. {";1 ", 3},
  87. {NULL, 0}, /* 9 to tag */
  88. {";1", 2}
  89. };
  90. if (get_callid(msg, &callid) == -1 || callid.len == 0) {
  91. LM_ERR("can't get Call-Id field\n");
  92. return -1;
  93. }
  94. if (get_to_tag(msg, &to_tag) == -1) {
  95. LM_ERR("can't get To tag\n");
  96. return -1;
  97. }
  98. if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
  99. LM_ERR("can't get From tag\n");
  100. return -1;
  101. }
  102. v[1].iov_len = sprintf(cbuf, "P%d", count);
  103. STR2IOVEC(callid, v[3]);
  104. STR2IOVEC(*pname, v[5]);
  105. node = select_rtpp_node(callid, 1);
  106. if (!node) {
  107. LM_ERR("no available proxies\n");
  108. return -1;
  109. }
  110. if (node->rn_ptl_supported == 0) {
  111. LM_ERR("required functionality is not "
  112. "supported by the version of the RTPproxy running on the selected "
  113. "node. Please upgrade the RTPproxy and try again.\n");
  114. return -1;
  115. }
  116. set_rtp_inst_pvar(msg, &node->rn_url);
  117. nitems = 11;
  118. if (stream2uac == 0) {
  119. if (to_tag.len == 0)
  120. return -1;
  121. STR2IOVEC(to_tag, v[7]);
  122. STR2IOVEC(from_tag, v[9]);
  123. } else {
  124. STR2IOVEC(from_tag, v[7]);
  125. STR2IOVEC(to_tag, v[9]);
  126. if (to_tag.len <= 0)
  127. nitems -= 2;
  128. }
  129. send_rtpp_command(node, v, nitems);
  130. return 1;
  131. }
  132. static int
  133. rtpproxy_stream2_f(struct sip_msg *msg, char *str1, int count, int stream2uac)
  134. {
  135. str pname;
  136. if (str1 == NULL || pv_printf_s(msg, (pv_elem_p)str1, &pname) != 0)
  137. return -1;
  138. return rtpproxy_stream(msg, &pname, count, stream2uac);
  139. }
  140. int
  141. rtpproxy_stream2uac2_f(struct sip_msg* msg, char* str1, char* str2)
  142. {
  143. return rtpproxy_stream2_f(msg, str1, (int)(long)str2, 1);
  144. }
  145. int
  146. rtpproxy_stream2uas2_f(struct sip_msg* msg, char* str1, char* str2)
  147. {
  148. return rtpproxy_stream2_f(msg, str1, (int)(long)str2, 0);
  149. }
  150. static int
  151. rtpproxy_stop_stream(struct sip_msg* msg, int stream2uac)
  152. {
  153. int nitems;
  154. str callid, from_tag, to_tag;
  155. struct rtpp_node *node;
  156. struct iovec v[] = {
  157. {NULL, 0},
  158. {"S", 1}, /* 1 */
  159. {" ", 1},
  160. {NULL, 0}, /* 3 callid */
  161. {" ", 1},
  162. {NULL, 0}, /* 5 from tag */
  163. {";1 ", 3},
  164. {NULL, 0}, /* 7 to tag */
  165. {";1", 2}
  166. };
  167. if (get_callid(msg, &callid) == -1 || callid.len == 0) {
  168. LM_ERR("can't get Call-Id field\n");
  169. return -1;
  170. }
  171. if (get_to_tag(msg, &to_tag) == -1) {
  172. LM_ERR("can't get To tag\n");
  173. return -1;
  174. }
  175. if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
  176. LM_ERR("can't get From tag\n");
  177. return -1;
  178. }
  179. STR2IOVEC(callid, v[3]);
  180. node = select_rtpp_node(callid, 1);
  181. if (!node) {
  182. LM_ERR("no available proxies\n");
  183. return -1;
  184. }
  185. if (node->rn_ptl_supported == 0) {
  186. LM_ERR("required functionality is not "
  187. "supported by the version of the RTPproxy running on the selected "
  188. "node. Please upgrade the RTPproxy and try again.\n");
  189. return -1;
  190. }
  191. set_rtp_inst_pvar(msg, &node->rn_url);
  192. nitems = 9;
  193. if (stream2uac == 0) {
  194. if (to_tag.len == 0)
  195. return -1;
  196. STR2IOVEC(to_tag, v[5]);
  197. STR2IOVEC(from_tag, v[7]);
  198. } else {
  199. STR2IOVEC(from_tag, v[5]);
  200. STR2IOVEC(to_tag, v[7]);
  201. if (to_tag.len <= 0)
  202. nitems -= 2;
  203. }
  204. send_rtpp_command(node, v, nitems);
  205. return 1;
  206. }
  207. int
  208. rtpproxy_stop_stream2uac2_f(struct sip_msg* msg, char* str1, char* str2)
  209. {
  210. return rtpproxy_stop_stream(msg, 1);
  211. }
  212. int
  213. rtpproxy_stop_stream2uas2_f(struct sip_msg* msg, char* str1, char* str2)
  214. {
  215. return rtpproxy_stop_stream(msg, 0);
  216. }