2
0

dlg_transfer.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /*
  2. * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
  3. *
  4. * This file is part of kamailio, a free SIP server.
  5. *
  6. * kamailio is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * kamailio is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. /*!
  21. * \file
  22. * \brief Call transfer
  23. * \ingroup dialog
  24. * Module: \ref dialog
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include "../../dprint.h"
  30. #include "../../ut.h"
  31. #include "../../trim.h"
  32. #include "../../mem/mem.h"
  33. #include "../../mem/shm_mem.h"
  34. #include "../../parser/parse_from.h"
  35. #include "../../parser/msg_parser.h"
  36. #include "../../modules/tm/tm_load.h"
  37. #include "dlg_req_within.h"
  38. #include "dlg_handlers.h"
  39. #include "dlg_transfer.h"
  40. #define DLG_HOLD_SDP "v=0\r\no=kamailio-bridge 0 0 IN IP4 0.0.0.0\r\ns=kamailio\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 9 RTP/AVP 8 0\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:0 PCMU/8000\r\n"
  41. #define DLG_HOLD_SDP_LEN (sizeof(DLG_HOLD_SDP)-1)
  42. /*
  43. #define DLG_HOLD_CT_HDR "Contact: <sip:kamailio.org:5060>\r\nContent-Type: application/sdp\r\n"
  44. #define DLG_HOLD_CT_HDR_LEN (sizeof(DLG_HOLD_CT_HDR)-1)
  45. */
  46. extern str dlg_bridge_controller;
  47. extern str dlg_bridge_contact;
  48. static char *dlg_bridge_hdrs_buf = NULL;
  49. static str dlg_bridge_inv_hdrs = {0};
  50. static str dlg_bridge_ref_hdrs = {0};
  51. int dlg_bridge_init_hdrs(void)
  52. {
  53. if(dlg_bridge_hdrs_buf!=NULL)
  54. return 0;
  55. dlg_bridge_hdrs_buf = (char*)pkg_malloc((dlg_bridge_contact.len + 46)
  56. * sizeof(char));
  57. if(dlg_bridge_hdrs_buf==NULL) {
  58. LM_ERR("no more pkg memory\n");
  59. return -1;
  60. }
  61. strncpy(dlg_bridge_hdrs_buf,
  62. "Contact: <", 10);
  63. strncpy(dlg_bridge_hdrs_buf + 10,
  64. dlg_bridge_contact.s, dlg_bridge_contact.len);
  65. strncpy(dlg_bridge_hdrs_buf + 10 + dlg_bridge_contact.len,
  66. ">\r\nContent-Type: application/sdp\r\n", 34);
  67. dlg_bridge_hdrs_buf[dlg_bridge_contact.len+44] = '\0';
  68. dlg_bridge_inv_hdrs.s = dlg_bridge_hdrs_buf;
  69. dlg_bridge_inv_hdrs.len = dlg_bridge_contact.len + 44;
  70. dlg_bridge_ref_hdrs.s = dlg_bridge_hdrs_buf;
  71. dlg_bridge_ref_hdrs.len = dlg_bridge_contact.len + 13;
  72. return 0;
  73. }
  74. void dlg_bridge_destroy_hdrs(void)
  75. {
  76. if(dlg_bridge_hdrs_buf!=NULL)
  77. pkg_free(dlg_bridge_hdrs_buf);
  78. }
  79. void dlg_transfer_ctx_free(dlg_transfer_ctx_t *dtc)
  80. {
  81. struct dlg_cell *dlg;
  82. if(dtc==NULL)
  83. return;
  84. if(dtc->from.s!=NULL)
  85. shm_free(dtc->from.s);
  86. if(dtc->to.s!=NULL)
  87. shm_free(dtc->to.s);
  88. dlg = dtc->dlg;
  89. if(dlg!=NULL)
  90. {
  91. if (dlg->tag[DLG_CALLER_LEG].s)
  92. shm_free(dlg->tag[DLG_CALLER_LEG].s);
  93. if (dlg->tag[DLG_CALLEE_LEG].s)
  94. shm_free(dlg->tag[DLG_CALLEE_LEG].s);
  95. if (dlg->cseq[DLG_CALLER_LEG].s)
  96. shm_free(dlg->cseq[DLG_CALLER_LEG].s);
  97. if (dlg->cseq[DLG_CALLEE_LEG].s)
  98. shm_free(dlg->cseq[DLG_CALLEE_LEG].s);
  99. shm_free(dlg);
  100. }
  101. shm_free(dtc);
  102. }
  103. void dlg_refer_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
  104. {
  105. dlg_transfer_ctx_t *dtc = NULL;
  106. dlg_t* dialog_info = NULL;
  107. str met = {"BYE", 3};
  108. int result;
  109. struct dlg_cell *dlg;
  110. uac_req_t uac_r;
  111. if(ps->param==NULL || *ps->param==0)
  112. {
  113. LM_DBG("message id not received\n");
  114. return;
  115. }
  116. dtc = *((dlg_transfer_ctx_t**)ps->param);
  117. if(dtc==NULL)
  118. return;
  119. LM_DBG("REFER completed with status %d\n", ps->code);
  120. /* we send the BYE anyhow */
  121. dlg = dtc->dlg;
  122. if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){
  123. LM_ERR("failed to create dlg_t\n");
  124. goto error;
  125. }
  126. /* after REFER, the CSeq must be increased */
  127. dialog_info->loc_seq.value++;
  128. set_uac_req(&uac_r, &met, NULL, NULL, dialog_info, 0, NULL, NULL);
  129. result = d_tmb.t_request_within(&uac_r);
  130. if(result < 0) {
  131. LM_ERR("failed to send the REFER request\n");
  132. /* todo: clean-up dtc */
  133. goto error;
  134. }
  135. free_tm_dlg(dialog_info);
  136. dlg_transfer_ctx_free(dtc);
  137. LM_DBG("BYE sent\n");
  138. return;
  139. error:
  140. dlg_transfer_ctx_free(dtc);
  141. if(dialog_info)
  142. free_tm_dlg(dialog_info);
  143. return;
  144. }
  145. static int dlg_refer_callee(dlg_transfer_ctx_t *dtc)
  146. {
  147. /*verify direction*/
  148. dlg_t* dialog_info = NULL;
  149. str met = {"REFER", 5};
  150. int result;
  151. str hdrs;
  152. struct dlg_cell *dlg;
  153. uac_req_t uac_r;
  154. dlg = dtc->dlg;
  155. if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){
  156. LM_ERR("failed to create dlg_t\n");
  157. goto error;
  158. }
  159. hdrs.len = 23 + 2*CRLF_LEN + dlg_bridge_controller.len
  160. + dtc->to.len + dlg_bridge_ref_hdrs.len;
  161. LM_DBG("sending REFER [%d] <%.*s>\n", hdrs.len, dtc->to.len, dtc->to.s);
  162. hdrs.s = (char*)pkg_malloc(hdrs.len*sizeof(char));
  163. if(hdrs.s == NULL)
  164. goto error;
  165. memcpy(hdrs.s, "Referred-By: ", 13);
  166. memcpy(hdrs.s+13, dlg_bridge_controller.s, dlg_bridge_controller.len);
  167. memcpy(hdrs.s+13+dlg_bridge_controller.len, CRLF, CRLF_LEN);
  168. memcpy(hdrs.s+13+dlg_bridge_controller.len+CRLF_LEN, "Refer-To: ", 10);
  169. memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN, dtc->to.s,
  170. dtc->to.len);
  171. memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len,
  172. CRLF, CRLF_LEN);
  173. memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len+CRLF_LEN,
  174. dlg_bridge_ref_hdrs.s, dlg_bridge_ref_hdrs.len);
  175. set_uac_req(&uac_r, &met, &hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
  176. dlg_refer_tm_callback, (void*)dtc);
  177. result = d_tmb.t_request_within(&uac_r);
  178. pkg_free(hdrs.s);
  179. if(result < 0) {
  180. LM_ERR("failed to send the REFER request\n");
  181. /* todo: clean-up dtc */
  182. goto error;
  183. }
  184. free_tm_dlg(dialog_info);
  185. LM_DBG("REFER sent\n");
  186. return 0;
  187. error:
  188. if(dialog_info)
  189. free_tm_dlg(dialog_info);
  190. return -1;
  191. }
  192. void dlg_bridge_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
  193. {
  194. struct sip_msg *msg = NULL;
  195. dlg_transfer_ctx_t *dtc = NULL;
  196. struct dlg_cell *dlg = NULL;
  197. str s;
  198. str cseq;
  199. str empty = {"", 0};
  200. if(ps->param==NULL || *ps->param==0)
  201. {
  202. LM_DBG("message id not received\n");
  203. return;
  204. }
  205. dtc = *((dlg_transfer_ctx_t**)ps->param);
  206. if(dtc==NULL)
  207. return;
  208. LM_DBG("completed with status %d\n", ps->code);
  209. if(ps->code>=300)
  210. goto error;
  211. /* 2xx - build dialog/send refer */
  212. msg = ps->rpl;
  213. if((msg->cseq==NULL || parse_headers(msg,HDR_CSEQ_F,0)<0)
  214. || msg->cseq==NULL || msg->cseq->parsed==NULL)
  215. {
  216. LM_ERR("bad sip message or missing CSeq hdr :-/\n");
  217. goto error;
  218. }
  219. cseq = (get_cseq(msg))->number;
  220. if((msg->to==NULL && parse_headers(msg, HDR_TO_F,0)<0) || msg->to==NULL)
  221. {
  222. LM_ERR("bad request or missing TO hdr\n");
  223. goto error;
  224. }
  225. if(parse_from_header(msg))
  226. {
  227. LM_ERR("bad request or missing FROM hdr\n");
  228. goto error;
  229. }
  230. if((msg->callid==NULL && parse_headers(msg,HDR_CALLID_F,0)<0)
  231. || msg->callid==NULL){
  232. LM_ERR("bad request or missing CALLID hdr\n");
  233. goto error;
  234. }
  235. s = msg->callid->body;
  236. trim(&s);
  237. /* some sanity checks */
  238. if (s.len==0 || get_from(msg)->tag_value.len==0) {
  239. LM_ERR("invalid request -> callid (%d) or from TAG (%d) empty\n",
  240. s.len, get_from(msg)->tag_value.len);
  241. goto error;
  242. }
  243. dlg = build_new_dlg(&s /*callid*/, &(get_from(msg)->uri) /*from uri*/,
  244. &(get_to(msg)->uri) /*to uri*/,
  245. &(get_from(msg)->tag_value)/*from_tag*/,
  246. &(get_to(msg)->uri) /*use to as r-uri*/ );
  247. if (dlg==0) {
  248. LM_ERR("failed to create new dialog\n");
  249. goto error;
  250. }
  251. dtc->dlg = dlg;
  252. if (dlg_set_leg_info(dlg, &(get_from(msg)->tag_value),
  253. &empty, &dlg_bridge_controller, &cseq, DLG_CALLER_LEG)!=0) {
  254. LM_ERR("dlg_set_leg_info failed\n");
  255. goto error;
  256. }
  257. if (populate_leg_info(dlg, msg, t, DLG_CALLEE_LEG,
  258. &(get_to(msg)->tag_value)) !=0)
  259. {
  260. LM_ERR("could not add further info to the dialog\n");
  261. shm_free(dlg);
  262. goto error;
  263. }
  264. if(dlg_refer_callee(dtc)!=0)
  265. goto error;
  266. return;
  267. error:
  268. dlg_transfer_ctx_free(dtc);
  269. return;
  270. }
  271. int dlg_bridge(str *from, str *to, str *op, str *bd)
  272. {
  273. dlg_transfer_ctx_t *dtc;
  274. int ret;
  275. str s_method = {"INVITE", 6};
  276. str s_body;
  277. uac_req_t uac_r;
  278. dtc = (dlg_transfer_ctx_t*)shm_malloc(sizeof(dlg_transfer_ctx_t));
  279. if(dtc==NULL)
  280. {
  281. LM_ERR("no shm\n");
  282. return -1;
  283. }
  284. memset(dtc, 0, sizeof(dlg_transfer_ctx_t));
  285. dtc->from.s = (char*)shm_malloc((from->len+1)*sizeof(char));
  286. if(dtc->from.s==NULL)
  287. {
  288. LM_ERR("no shm\n");
  289. shm_free(dtc);
  290. return -1;
  291. }
  292. dtc->to.s = (char*)shm_malloc((to->len+1)*sizeof(char));
  293. if(dtc->to.s==NULL)
  294. {
  295. LM_ERR("no shm\n");
  296. shm_free(dtc->from.s);
  297. shm_free(dtc);
  298. return -1;
  299. }
  300. memcpy(dtc->from.s, from->s, from->len);
  301. dtc->from.len = from->len;
  302. dtc->from.s[dtc->from.len] = '\0';
  303. memcpy(dtc->to.s, to->s, to->len);
  304. dtc->to.len = to->len;
  305. dtc->to.s[dtc->to.len] = '\0';
  306. LM_DBG("bridge <%.*s> to <%.*s>\n", dtc->from.len, dtc->from.s,
  307. dtc->to.len, dtc->to.s);
  308. if(bd!=NULL && bd->s!=NULL && bd->len>0) {
  309. s_body.s = bd->s;
  310. s_body.len = bd->len;
  311. } else {
  312. s_body.s = DLG_HOLD_SDP;
  313. s_body.len = DLG_HOLD_SDP_LEN;
  314. }
  315. memset(&uac_r, '\0', sizeof(uac_req_t));
  316. uac_r.method = &s_method;
  317. uac_r.headers = &dlg_bridge_inv_hdrs;
  318. uac_r.body = &s_body;
  319. uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
  320. uac_r.cb = dlg_bridge_tm_callback;
  321. uac_r.cbp = (void*)(long)dtc;
  322. ret = d_tmb.t_request(&uac_r, /* UAC Req */
  323. &dtc->from, /* Request-URI (To) */
  324. &dtc->from, /* To */
  325. &dlg_bridge_controller, /* From */
  326. (op != NULL && op->len>0)?op:NULL /* Outbound-URI */
  327. );
  328. if(ret<0)
  329. {
  330. dlg_transfer_ctx_free(dtc);
  331. return -1;
  332. }
  333. return 0;
  334. }
  335. int dlg_transfer(struct dlg_cell *dlg, str *to, int side)
  336. {
  337. dlg_transfer_ctx_t *dtc = NULL;
  338. struct dlg_cell *ndlg = NULL;
  339. str from;
  340. str empty = {"", 0};
  341. dtc = (dlg_transfer_ctx_t*)shm_malloc(sizeof(dlg_transfer_ctx_t));
  342. if(dtc==NULL)
  343. {
  344. LM_ERR("no shm\n");
  345. return -1;
  346. }
  347. if(side==DLG_CALLEE_LEG)
  348. {
  349. from = dlg->from_uri;
  350. } else {
  351. from = dlg->to_uri;
  352. }
  353. memset(dtc, 0, sizeof(dlg_transfer_ctx_t));
  354. dtc->from.s = (char*)shm_malloc((from.len+1)*sizeof(char));
  355. if(dtc->from.s==NULL)
  356. {
  357. LM_ERR("no shm\n");
  358. shm_free(dtc);
  359. return -1;
  360. }
  361. dtc->to.s = (char*)shm_malloc((to->len+1)*sizeof(char));
  362. if(dtc->to.s==NULL)
  363. {
  364. LM_ERR("no shm\n");
  365. shm_free(dtc->from.s);
  366. shm_free(dtc);
  367. return -1;
  368. }
  369. memcpy(dtc->from.s, from.s, from.len);
  370. dtc->from.len = from.len;
  371. dtc->from.s[dtc->from.len] = '\0';
  372. memcpy(dtc->to.s, to->s, to->len);
  373. dtc->to.len = to->len;
  374. dtc->to.s[dtc->to.len] = '\0';
  375. if(side==DLG_CALLER_LEG)
  376. ndlg = build_new_dlg(&dlg->callid /*callid*/,
  377. &dlg->to_uri /*from uri*/, &dlg->from_uri /*to uri*/,
  378. &dlg->tag[side]/*from_tag*/, &dlg->req_uri /*req uri */ );
  379. else
  380. ndlg = build_new_dlg(&dlg->callid /*callid*/,
  381. &dlg->from_uri /*from uri*/, &dlg->to_uri /*to uri*/,
  382. &dlg->tag[side]/*from_tag*/, &dlg->req_uri /*req uri */ );
  383. if (ndlg==0) {
  384. LM_ERR("failed to create new dialog\n");
  385. goto error;
  386. }
  387. dtc->dlg = ndlg;
  388. if (dlg_set_leg_info(ndlg, &dlg->tag[side], &empty,
  389. &dlg->contact[side], &dlg->cseq[side], DLG_CALLER_LEG)!=0)
  390. {
  391. LM_ERR("dlg_set_leg_info failed for caller\n");
  392. goto error;
  393. }
  394. if(side==DLG_CALLEE_LEG)
  395. side = DLG_CALLER_LEG;
  396. else
  397. side = DLG_CALLEE_LEG;
  398. if (dlg_set_leg_info(ndlg, &dlg->tag[side], &dlg->route_set[side],
  399. &dlg->contact[side], &dlg->cseq[side], DLG_CALLEE_LEG)!=0)
  400. {
  401. LM_ERR("dlg_set_leg_info failed for caller\n");
  402. goto error;
  403. }
  404. if(dlg_refer_callee(dtc)!=0)
  405. goto error;
  406. return 0;
  407. error:
  408. dlg_transfer_ctx_free(dtc);
  409. return -1;
  410. }