sdp.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. /*
  2. * SDP parser interface
  3. *
  4. * Copyright (C) 2008-2009 SOMA Networks, INC.
  5. * Copyright (C) 2010 VoIP Embedded, Inc
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  19. * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  20. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  21. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  23. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  24. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  25. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. *
  27. */
  28. #include "../../ut.h"
  29. #include "../../mem/mem.h"
  30. #include "../../mem/shm_mem.h"
  31. #include "../parser_f.h"
  32. #include "../parse_content.h"
  33. #include "sdp.h"
  34. #include "sdp_helpr_funcs.h"
  35. #define USE_PKG_MEM 0
  36. #define USE_SHM_MEM 1
  37. #define HOLD_IP_STR "0.0.0.0"
  38. #define HOLD_IP_LEN 7
  39. /**
  40. * Creates and initialize a new sdp_info structure
  41. */
  42. static inline int new_sdp(struct sip_msg* _m)
  43. {
  44. sdp_info_t* sdp;
  45. sdp = (sdp_info_t*)pkg_malloc(sizeof(sdp_info_t));
  46. if (sdp == NULL) {
  47. LM_ERR("No memory left\n");
  48. return -1;
  49. }
  50. memset( sdp, 0, sizeof(sdp_info_t));
  51. sdp->type = MSG_BODY_SDP;
  52. sdp->free = (free_msg_body_f)free_sdp;
  53. _m->body = (msg_body_t*)sdp;
  54. return 0;
  55. }
  56. /**
  57. * Alocate a new session cell.
  58. */
  59. static inline sdp_session_cell_t *add_sdp_session(sdp_info_t* _sdp, int session_num, str* cnt_disp)
  60. {
  61. sdp_session_cell_t *session;
  62. int len;
  63. len = sizeof(sdp_session_cell_t);
  64. session = (sdp_session_cell_t*)pkg_malloc(len);
  65. if (session == NULL) {
  66. LM_ERR("No memory left\n");
  67. return NULL;
  68. }
  69. memset( session, 0, len);
  70. session->session_num = session_num;
  71. if (cnt_disp != NULL) {
  72. session->cnt_disp.s = cnt_disp->s;
  73. session->cnt_disp.len = cnt_disp->len;
  74. }
  75. /* Insert the new session */
  76. session->next = _sdp->sessions;
  77. _sdp->sessions = session;
  78. _sdp->sessions_num++;
  79. return session;
  80. }
  81. /**
  82. * Allocate a new stream cell.
  83. */
  84. static inline sdp_stream_cell_t *add_sdp_stream(sdp_session_cell_t* _session, int stream_num,
  85. str* media, str* port, str* transport, str* payloads, int is_rtp, int pf, str* sdp_ip)
  86. {
  87. sdp_stream_cell_t *stream;
  88. int len;
  89. len = sizeof(sdp_stream_cell_t);
  90. stream = (sdp_stream_cell_t*)pkg_malloc(len);
  91. if (stream == NULL) {
  92. LM_ERR("No memory left\n");
  93. return NULL;
  94. }
  95. memset( stream, 0, len);
  96. stream->stream_num = stream_num;
  97. stream->media.s = media->s;
  98. stream->media.len = media->len;
  99. stream->port.s = port->s;
  100. stream->port.len = port->len;
  101. stream->transport.s = transport->s;
  102. stream->transport.len = transport->len;
  103. stream->payloads.s = payloads->s;
  104. stream->payloads.len = payloads->len;
  105. stream->is_rtp = is_rtp;
  106. stream->pf = pf;
  107. stream->ip_addr.s = sdp_ip->s;
  108. stream->ip_addr.len = sdp_ip->len;
  109. /* Insert the new stream */
  110. stream->next = _session->streams;
  111. _session->streams = stream;
  112. _session->streams_num++;
  113. return stream;
  114. }
  115. /**
  116. * Allocate a new payload.
  117. */
  118. static inline sdp_payload_attr_t *add_sdp_payload(sdp_stream_cell_t* _stream, int payload_num, str* payload)
  119. {
  120. sdp_payload_attr_t *payload_attr;
  121. int len;
  122. len = sizeof(sdp_payload_attr_t);
  123. payload_attr = (sdp_payload_attr_t*)pkg_malloc(len);
  124. if (payload_attr == NULL) {
  125. LM_ERR("No memory left\n");
  126. return NULL;
  127. }
  128. memset( payload_attr, 0, len);
  129. payload_attr->payload_num = payload_num;
  130. payload_attr->rtp_payload.s = payload->s;
  131. payload_attr->rtp_payload.len = payload->len;
  132. /* Insert the new payload */
  133. payload_attr->next = _stream->payload_attr;
  134. _stream->payload_attr = payload_attr;
  135. _stream->payloads_num++;
  136. return payload_attr;
  137. }
  138. /**
  139. * Initialize fast access pointers.
  140. */
  141. static inline sdp_payload_attr_t** init_p_payload_attr(sdp_stream_cell_t* _stream, int pkg)
  142. {
  143. int payloads_num, i;
  144. sdp_payload_attr_t *payload;
  145. if (_stream == NULL) {
  146. LM_ERR("Invalid stream\n");
  147. return NULL;
  148. }
  149. payloads_num = _stream->payloads_num;
  150. if (payloads_num == 0) {
  151. LM_ERR("Invalid number of payloads\n");
  152. return NULL;
  153. }
  154. if (pkg == USE_PKG_MEM) {
  155. _stream->p_payload_attr = (sdp_payload_attr_t**)pkg_malloc(payloads_num * sizeof(sdp_payload_attr_t*));
  156. } else if (pkg == USE_SHM_MEM) {
  157. _stream->p_payload_attr = (sdp_payload_attr_t**)shm_malloc(payloads_num * sizeof(sdp_payload_attr_t*));
  158. } else {
  159. LM_ERR("undefined memory type\n");
  160. return NULL;
  161. }
  162. if (_stream->p_payload_attr == NULL) {
  163. LM_ERR("No memory left\n");
  164. return NULL;
  165. }
  166. --payloads_num;
  167. payload = _stream->payload_attr;
  168. for (i=0;i<=payloads_num;i++) {
  169. _stream->p_payload_attr[payloads_num-i] = payload;
  170. payload = payload->next;
  171. }
  172. return _stream->p_payload_attr;
  173. }
  174. /*
  175. * Setters ...
  176. */
  177. void set_sdp_payload_attr(sdp_payload_attr_t *payload_attr, str *rtp_enc, str *rtp_clock, str *rtp_params)
  178. {
  179. if (payload_attr == NULL) {
  180. LM_ERR("Invalid payload location\n");
  181. return;
  182. }
  183. payload_attr->rtp_enc.s = rtp_enc->s;
  184. payload_attr->rtp_enc.len = rtp_enc->len;
  185. payload_attr->rtp_clock.s = rtp_clock->s;
  186. payload_attr->rtp_clock.len = rtp_clock->len;
  187. payload_attr->rtp_params.s = rtp_params->s;
  188. payload_attr->rtp_params.len = rtp_params->len;
  189. return;
  190. }
  191. void set_sdp_payload_fmtp(sdp_payload_attr_t *payload_attr, str *fmtp_string )
  192. {
  193. if (payload_attr == NULL) {
  194. LM_ERR("Invalid payload location\n");
  195. return;
  196. }
  197. payload_attr->fmtp_string.s = fmtp_string->s;
  198. payload_attr->fmtp_string.len = fmtp_string->len;
  199. return;
  200. }
  201. /*
  202. * Getters ....
  203. */
  204. int get_sdp_session_num(struct sip_msg* _m)
  205. {
  206. if (_m->body == NULL) return 0;
  207. if (_m->body->type != MSG_BODY_SDP) return 0;
  208. return ((sdp_info_t*)_m->body)->sessions_num;
  209. }
  210. int get_sdp_stream_num(struct sip_msg* _m)
  211. {
  212. if (_m->body == NULL) return 0;
  213. if (_m->body->type != MSG_BODY_SDP) return 0;
  214. return ((sdp_info_t*)_m->body)->streams_num;
  215. }
  216. sdp_session_cell_t* get_sdp_session_sdp(struct sdp_info* sdp, int session_num)
  217. {
  218. sdp_session_cell_t *session;
  219. session = sdp->sessions;
  220. if (session_num >= sdp->sessions_num) return NULL;
  221. while (session) {
  222. if (session->session_num == session_num) return session;
  223. session = session->next;
  224. }
  225. return NULL;
  226. }
  227. sdp_session_cell_t* get_sdp_session(struct sip_msg* _m, int session_num)
  228. {
  229. if (_m->body == NULL) return NULL;
  230. if (_m->body->type != MSG_BODY_SDP) return NULL;
  231. return get_sdp_session_sdp((sdp_info_t*)_m->body, session_num);
  232. }
  233. sdp_stream_cell_t* get_sdp_stream_sdp(struct sdp_info* sdp, int session_num, int stream_num)
  234. {
  235. sdp_session_cell_t *session;
  236. sdp_stream_cell_t *stream;
  237. if (sdp==NULL) return NULL;
  238. if (session_num >= sdp->sessions_num) return NULL;
  239. session = sdp->sessions;
  240. while (session) {
  241. if (session->session_num == session_num) {
  242. if (stream_num >= session->streams_num) return NULL;
  243. stream = session->streams;
  244. while (stream) {
  245. if (stream->stream_num == stream_num) return stream;
  246. stream = stream->next;
  247. }
  248. break;
  249. } else {
  250. session = session->next;
  251. }
  252. }
  253. return NULL;
  254. }
  255. sdp_stream_cell_t* get_sdp_stream(struct sip_msg* _m, int session_num, int stream_num)
  256. {
  257. if (_m->body == NULL) return NULL;
  258. if (_m->body->type != MSG_BODY_SDP) return NULL;
  259. return get_sdp_stream_sdp((sdp_info_t*)_m->body, session_num, stream_num);
  260. }
  261. sdp_payload_attr_t* get_sdp_payload4payload(sdp_stream_cell_t *stream, str *rtp_payload)
  262. {
  263. sdp_payload_attr_t *payload;
  264. int i;
  265. if (stream == NULL) {
  266. LM_ERR("Invalid stream location\n");
  267. return NULL;
  268. }
  269. if (stream->p_payload_attr == NULL) {
  270. LM_ERR("Invalid access pointer to payloads\n");
  271. return NULL;
  272. }
  273. for (i=0;i<stream->payloads_num;i++) {
  274. payload = stream->p_payload_attr[i];
  275. if (rtp_payload->len == payload->rtp_payload.len &&
  276. (strncmp(rtp_payload->s, payload->rtp_payload.s, rtp_payload->len)==0)) {
  277. return payload;
  278. }
  279. }
  280. return NULL;
  281. }
  282. sdp_payload_attr_t* get_sdp_payload4index(sdp_stream_cell_t *stream, int index)
  283. {
  284. if (stream == NULL) {
  285. LM_ERR("Invalid stream location\n");
  286. return NULL;
  287. }
  288. if (stream->p_payload_attr == NULL) {
  289. LM_ERR("Invalid access pointer to payloads\n");
  290. return NULL;
  291. }
  292. if (index >= stream->payloads_num) {
  293. LM_ERR("Out of range index [%d] for payload\n", index);
  294. return NULL;
  295. }
  296. return stream->p_payload_attr[index];
  297. }
  298. /**
  299. * SDP parser method.
  300. */
  301. static int parse_sdp_session(str *sdp_body, int session_num, str *cnt_disp, sdp_info_t* _sdp)
  302. {
  303. str body = *sdp_body;
  304. str sdp_ip = {NULL,0};
  305. str sdp_media, sdp_port, sdp_transport, sdp_payload;
  306. str payload;
  307. str rtp_payload, rtp_enc, rtp_clock, rtp_params;
  308. int is_rtp;
  309. char *bodylimit;
  310. char *v1p, *o1p, *m1p, *m2p, *c1p, *c2p, *a1p, *a2p, *b1p;
  311. str tmpstr1;
  312. int stream_num, payloadnum, pf;
  313. sdp_session_cell_t *session;
  314. sdp_stream_cell_t *stream;
  315. sdp_payload_attr_t *payload_attr;
  316. int parse_payload_attr;
  317. str fmtp_string;
  318. str remote_candidates = {"a:remote-candidates:", 20};
  319. /* hook the start and lenght of sdp body inside structure
  320. * - shorcut useful for multi-part bodies and sdp operations
  321. */
  322. _sdp->text = *sdp_body;
  323. /*
  324. * Parsing of SDP body.
  325. * Each session starts with v-line and each session may contain a few
  326. * media descriptions (each starts with m-line).
  327. * We have to change ports in m-lines, and also change IP addresses in
  328. * c-lines which can be placed either in session header (fallback for
  329. * all medias) or media description.
  330. * Ports should be allocated for any media. IPs all should be changed
  331. * to the same value (RTP proxy IP), so we can change all c-lines
  332. * unconditionally.
  333. */
  334. bodylimit = body.s + body.len;
  335. v1p = find_sdp_line(body.s, bodylimit, 'v');
  336. if (v1p == NULL) {
  337. LM_ERR("no sessions in SDP\n");
  338. return -1;
  339. }
  340. /* get session origin */
  341. o1p = find_sdp_line(v1p, bodylimit, 'o');
  342. if (o1p == NULL) {
  343. LM_ERR("no o= in session\n");
  344. return -1;
  345. }
  346. /* Have this session media description? */
  347. m1p = find_sdp_line(o1p, bodylimit, 'm');
  348. if (m1p == NULL) {
  349. LM_ERR("no m= in session\n");
  350. return -1;
  351. }
  352. /* Allocate a session cell */
  353. session = add_sdp_session(_sdp, session_num, cnt_disp);
  354. if (session == NULL) return -1;
  355. /* Get origin IP */
  356. tmpstr1.s = o1p;
  357. tmpstr1.len = bodylimit - tmpstr1.s; /* limit is session limit text */
  358. if (extract_mediaip(&tmpstr1, &session->o_ip_addr, &session->o_pf,"o=") == -1) {
  359. LM_ERR("can't extract origin media IP from the message\n");
  360. return -1;
  361. }
  362. /* Find c1p only between session begin and first media.
  363. * c1p will give common c= for all medias. */
  364. c1p = find_sdp_line(o1p, m1p, 'c');
  365. if (c1p) {
  366. /* Extract session address */
  367. tmpstr1.s = c1p;
  368. tmpstr1.len = bodylimit - tmpstr1.s; /* limit is session limit text */
  369. if (extract_mediaip(&tmpstr1, &session->ip_addr, &session->pf,"c=") == -1) {
  370. LM_ERR("can't extract common media IP from the message\n");
  371. return -1;
  372. }
  373. }
  374. /* Find b1p only between session begin and first media.
  375. * b1p will give common b= for all medias. */
  376. b1p = find_sdp_line(o1p, m1p, 'b');
  377. if (b1p) {
  378. tmpstr1.s = b1p;
  379. tmpstr1.len = m1p - b1p;
  380. extract_bwidth(&tmpstr1, &session->bw_type, &session->bw_width);
  381. }
  382. /* Have session. Iterate media descriptions in session */
  383. m2p = m1p;
  384. stream_num = 0;
  385. for (;;) {
  386. m1p = m2p;
  387. if (m1p == NULL || m1p >= bodylimit)
  388. break;
  389. m2p = find_next_sdp_line(m1p, bodylimit, 'm', bodylimit);
  390. /* c2p will point to per-media "c=" */
  391. c2p = find_sdp_line(m1p, m2p, 'c');
  392. sdp_ip.s = NULL;
  393. sdp_ip.len = 0;
  394. if (c2p) {
  395. /* Extract stream address */
  396. tmpstr1.s = c2p;
  397. tmpstr1.len = bodylimit - tmpstr1.s; /* limit is session limit text */
  398. if (extract_mediaip(&tmpstr1, &sdp_ip, &pf,"c=") == -1) {
  399. LM_ERR("can't extract media IP from the message\n");
  400. return -1;
  401. }
  402. } else {
  403. if (!c1p) {
  404. /* No "c=" */
  405. LM_ERR("can't find media IP in the message\n");
  406. return -1;
  407. }
  408. }
  409. /* Extract the port on sdp_port */
  410. tmpstr1.s = m1p;
  411. tmpstr1.len = m2p - m1p;
  412. if (extract_media_attr(&tmpstr1, &sdp_media, &sdp_port, &sdp_transport, &sdp_payload, &is_rtp) == -1) {
  413. LM_ERR("can't extract media attr from the message\n");
  414. return -1;
  415. }
  416. /* Allocate a stream cell */
  417. stream = add_sdp_stream(session, stream_num, &sdp_media, &sdp_port, &sdp_transport, &sdp_payload, is_rtp, pf, &sdp_ip);
  418. if (stream == 0) return -1;
  419. /* Store fast access ptr to raw stream */
  420. stream->raw_stream.s = tmpstr1.s;
  421. stream->raw_stream.len = tmpstr1.len;
  422. /* increment total number of streams */
  423. _sdp->streams_num++;
  424. /* b1p will point to per-media "b=" */
  425. b1p = find_sdp_line(m1p, m2p, 'b');
  426. if (b1p) {
  427. tmpstr1.s = b1p;
  428. tmpstr1.len = m2p - b1p;
  429. extract_bwidth(&tmpstr1, &stream->bw_type, &stream->bw_width);
  430. }
  431. /* Parsing the payloads */
  432. tmpstr1.s = sdp_payload.s;
  433. tmpstr1.len = sdp_payload.len;
  434. payloadnum = 0;
  435. if (tmpstr1.len != 0) {
  436. for (;;) {
  437. a1p = eat_token_end(tmpstr1.s, tmpstr1.s + tmpstr1.len);
  438. payload.s = tmpstr1.s;
  439. payload.len = a1p - tmpstr1.s;
  440. payload_attr = add_sdp_payload(stream, payloadnum, &payload);
  441. if (payload_attr == NULL) return -1;
  442. tmpstr1.len -= payload.len;
  443. tmpstr1.s = a1p;
  444. a2p = eat_space_end(tmpstr1.s, tmpstr1.s + tmpstr1.len);
  445. tmpstr1.len -= a2p - a1p;
  446. tmpstr1.s = a2p;
  447. if (a1p >= tmpstr1.s)
  448. break;
  449. payloadnum++;
  450. }
  451. /* Initialize fast access pointers */
  452. if (NULL == init_p_payload_attr(stream, USE_PKG_MEM)) {
  453. return -1;
  454. }
  455. parse_payload_attr = 1;
  456. } else {
  457. parse_payload_attr = 0;
  458. }
  459. payload_attr = 0;
  460. /* Let's figure out the atributes */
  461. a1p = find_sdp_line(m1p, m2p, 'a');
  462. a2p = a1p;
  463. for (;;) {
  464. a1p = a2p;
  465. if (a1p == NULL || a1p >= m2p)
  466. break;
  467. tmpstr1.s = a2p;
  468. tmpstr1.len = m2p - a2p;
  469. if (parse_payload_attr && extract_ptime(&tmpstr1, &stream->ptime) == 0) {
  470. a1p = stream->ptime.s + stream->ptime.len;
  471. } else if (parse_payload_attr && extract_sendrecv_mode(&tmpstr1,
  472. &stream->sendrecv_mode, &stream->is_on_hold) == 0) {
  473. a1p = stream->sendrecv_mode.s + stream->sendrecv_mode.len;
  474. } else if (parse_payload_attr && extract_rtpmap(&tmpstr1, &rtp_payload, &rtp_enc, &rtp_clock, &rtp_params) == 0) {
  475. if (rtp_params.len != 0 && rtp_params.s != NULL) {
  476. a1p = rtp_params.s + rtp_params.len;
  477. } else {
  478. a1p = rtp_clock.s + rtp_clock.len;
  479. }
  480. payload_attr = (sdp_payload_attr_t*)get_sdp_payload4payload(stream, &rtp_payload);
  481. set_sdp_payload_attr(payload_attr, &rtp_enc, &rtp_clock, &rtp_params);
  482. } else if (extract_rtcp(&tmpstr1, &stream->rtcp_port) == 0) {
  483. a1p = stream->rtcp_port.s + stream->rtcp_port.len;
  484. } else if (parse_payload_attr && extract_fmtp(&tmpstr1,&rtp_payload,&fmtp_string) == 0){
  485. a1p = fmtp_string.s + fmtp_string.len;
  486. payload_attr = (sdp_payload_attr_t*)get_sdp_payload4payload(stream, &rtp_payload);
  487. set_sdp_payload_fmtp(payload_attr, &fmtp_string);
  488. } else if (parse_payload_attr && extract_candidate(&tmpstr1, stream) == 0) {
  489. a1p += 2;
  490. } else if (parse_payload_attr && extract_field(&tmpstr1, &stream->remote_candidates,
  491. remote_candidates) == 0) {
  492. a1p += 2;
  493. } else if (extract_accept_types(&tmpstr1, &stream->accept_types) == 0) {
  494. a1p = stream->accept_types.s + stream->accept_types.len;
  495. } else if (extract_accept_wrapped_types(&tmpstr1, &stream->accept_wrapped_types) == 0) {
  496. a1p = stream->accept_wrapped_types.s + stream->accept_wrapped_types.len;
  497. } else if (extract_max_size(&tmpstr1, &stream->max_size) == 0) {
  498. a1p = stream->max_size.s + stream->max_size.len;
  499. } else if (extract_path(&tmpstr1, &stream->path) == 0) {
  500. a1p = stream->path.s + stream->path.len;
  501. } else {
  502. /* unknown a= line, ignore -- jump over it */
  503. LM_DBG("ignoring unknown type in a= line: `%.*s'\n", tmpstr1.len, tmpstr1.s);
  504. a1p += 2;
  505. }
  506. a2p = find_first_sdp_line(a1p, m2p, 'a', m2p);
  507. }
  508. /* Let's detect if the media is on hold by checking
  509. * the good old "0.0.0.0" connection address */
  510. if (!stream->is_on_hold) {
  511. if (stream->ip_addr.s && stream->ip_addr.len) {
  512. if (stream->ip_addr.len == HOLD_IP_LEN &&
  513. strncmp(stream->ip_addr.s, HOLD_IP_STR, HOLD_IP_LEN)==0)
  514. stream->is_on_hold = 1;
  515. } else if (session->ip_addr.s && session->ip_addr.len) {
  516. if (session->ip_addr.len == HOLD_IP_LEN &&
  517. strncmp(session->ip_addr.s, HOLD_IP_STR, HOLD_IP_LEN)==0)
  518. stream->is_on_hold = 1;
  519. }
  520. }
  521. ++stream_num;
  522. } /* Iterate medias/streams in session */
  523. return 0;
  524. }
  525. static int parse_mixed_content(str *mixed_body, str delimiter, sdp_info_t* _sdp)
  526. {
  527. int res, no_eoh_found, start_parsing;
  528. char *bodylimit, *rest;
  529. char *d1p, *d2p;
  530. char *ret, *end;
  531. unsigned int mime;
  532. str cnt_disp;
  533. int session_num;
  534. struct hdr_field hf;
  535. bodylimit = mixed_body->s + mixed_body->len;
  536. d1p = find_sdp_line_delimiter(mixed_body->s, bodylimit, delimiter);
  537. if (d1p == NULL) {
  538. LM_ERR("empty multipart content\n");
  539. return -1;
  540. }
  541. d2p = d1p;
  542. session_num = 0;
  543. for(;;) {
  544. /* Per-application iteration */
  545. d1p = d2p;
  546. if (d1p == NULL || d1p >= bodylimit)
  547. break; /* No applications left */
  548. d2p = find_next_sdp_line_delimiter(d1p, bodylimit, delimiter, bodylimit);
  549. /* d2p is text limit for application parsing */
  550. memset(&hf,0, sizeof(struct hdr_field));
  551. rest = eat_line(d1p + delimiter.len + 2, d2p - d1p - delimiter.len - 2);
  552. if ( rest > d2p ) {
  553. LM_ERR("Unparsable <%.*s>\n", (int)(d2p-d1p), d1p);
  554. return -1;
  555. }
  556. no_eoh_found = 1;
  557. start_parsing = 0;
  558. /*LM_DBG("we need to parse this: <%.*s>\n", d2p-rest, rest); */
  559. while( rest<d2p && no_eoh_found ) {
  560. rest = get_sdp_hdr_field(rest, d2p, &hf);
  561. switch (hf.type){
  562. case HDR_EOH_T:
  563. no_eoh_found = 0;
  564. break;
  565. case HDR_CONTENTTYPE_T:
  566. end = hf.body.s + hf.body.len;
  567. ret = decode_mime_type(hf.body.s, end , &mime);
  568. if (ret==0)
  569. return -1;
  570. if (ret!=end) {
  571. LM_ERR("the header CONTENT_TYPE contains "
  572. "more then one mime type :-(!\n");
  573. return -1;
  574. }
  575. if ((mime&0x00ff)==SUBTYPE_ALL || (mime>>16)==TYPE_ALL) {
  576. LM_ERR("invalid mime with wildcard '*' in Content-Type hdr!\n");
  577. return -1;
  578. }
  579. //LM_DBG("HDR_CONTENTTYPE_T: %d:%d %p-> <%.*s:%.*s>\n",mime&0x00ff,mime>>16,
  580. // hf.name.s,hf.name.len,hf.name.s,hf.body.len,hf.body.s);
  581. if (((((unsigned int)mime)>>16) == TYPE_APPLICATION) && ((mime&0x00ff) == SUBTYPE_SDP)) {
  582. /*LM_DBG("start_parsing: %d:%d\n",mime&0x00ff,mime>>16); */
  583. start_parsing = 1;
  584. }
  585. break;
  586. case HDR_CONTENTDISPOSITION_T:
  587. cnt_disp.s = hf.body.s;
  588. cnt_disp.len = hf.body.len;
  589. break;
  590. case HDR_ERROR_T:
  591. return -1;
  592. break;
  593. default:
  594. LM_DBG("unknown header: <%.*s:%.*s>\n",hf.name.len,hf.name.s,hf.body.len,hf.body.s);
  595. }
  596. } /* end of while */
  597. /* and now we need to parse the content */
  598. if (start_parsing) {
  599. while (('\n' == *rest) || ('\r' == *rest) || ('\t' == *rest)|| (' ' == *rest)) rest++; /* Skip any whitespace */
  600. _sdp->raw_sdp.s = rest;
  601. _sdp->raw_sdp.len = d2p-rest;
  602. /* LM_DBG("we need to check session %d: <%.*s>\n", session_num, _sdp.raw_sdp.len, _sdp.raw_sdp.s); */
  603. res = parse_sdp_session(&_sdp->raw_sdp, session_num, &cnt_disp, _sdp);
  604. if (res != 0) {
  605. /* _sdp is freed by the calling function */
  606. return -1;
  607. }
  608. session_num++;
  609. }
  610. }
  611. return 0;
  612. }
  613. /**
  614. * @brief Parse SIP SDP body and store in _m->body.
  615. *
  616. * @param _m the SIP message structure
  617. * @return 0 on success, < 0 on error and 1 if there is no message body
  618. */
  619. int parse_sdp(struct sip_msg* _m)
  620. {
  621. int res;
  622. str body, mp_delimiter;
  623. int mime;
  624. if (_m->body) {
  625. return 0; /* Already parsed */
  626. }
  627. body.s = get_body(_m);
  628. if (body.s==NULL) {
  629. LM_ERR("failed to get the message body\n");
  630. return -1;
  631. }
  632. body.len = _m->len -(int)(body.s - _m->buf);
  633. if (body.len==0) {
  634. LM_DBG("message body has length zero\n");
  635. return 1;
  636. }
  637. mime = parse_content_type_hdr(_m);
  638. if (mime <= 0) {
  639. return -1;
  640. }
  641. switch (((unsigned int)mime)>>16) {
  642. case TYPE_APPLICATION:
  643. /* LM_DBG("TYPE_APPLICATION: %d\n",((unsigned int)mime)>>16); */
  644. switch (mime&0x00ff) {
  645. case SUBTYPE_SDP:
  646. /* LM_DBG("SUBTYPE_SDP: %d\n",mime&0x00ff); */
  647. if (new_sdp(_m) < 0) {
  648. LM_ERR("Can't create sdp\n");
  649. return -1;
  650. }
  651. res = parse_sdp_session(&body, 0, NULL, (sdp_info_t*)_m->body);
  652. if (res != 0) {
  653. LM_DBG("failed to parse sdp session - freeing sdp\n");
  654. free_sdp((sdp_info_t**)(void*)&_m->body);
  655. return res;
  656. }
  657. /* The whole body is SDP */
  658. ((sdp_info_t*)_m->body)->raw_sdp.s = body.s;
  659. ((sdp_info_t*)_m->body)->raw_sdp.len = body.len;
  660. return res;
  661. break;
  662. default:
  663. LM_DBG("TYPE_APPLICATION: unknown %d\n",mime&0x00ff);
  664. return -1;
  665. }
  666. break;
  667. case TYPE_MULTIPART:
  668. /* LM_DBG("TYPE_MULTIPART: %d\n",((unsigned int)mime)>>16); */
  669. switch (mime&0x00ff) {
  670. case SUBTYPE_MIXED:
  671. /* LM_DBG("SUBTYPE_MIXED: %d <%.*s>\n",mime&0x00ff,_m->content_type->body.len,_m->content_type->body.s); */
  672. if(get_mixed_part_delimiter(&(_m->content_type->body),&mp_delimiter) > 0) {
  673. /*LM_DBG("got delimiter: <%.*s>\n",mp_delimiter.len,mp_delimiter.s); */
  674. if (new_sdp(_m) < 0) {
  675. LM_ERR("Can't create sdp\n");
  676. return -1;
  677. }
  678. res = parse_mixed_content(&body, mp_delimiter, (sdp_info_t*)_m->body);
  679. if (res != 0) {
  680. LM_DBG("free_sdp\n");
  681. free_sdp((sdp_info_t**)(void*)&_m->body);
  682. }
  683. return res;
  684. } else {
  685. return -1;
  686. }
  687. break;
  688. default:
  689. LM_DBG("TYPE_MULTIPART: unknown %d\n",mime&0x00ff);
  690. return -1;
  691. }
  692. break;
  693. default:
  694. LM_DBG("%d\n",((unsigned int)mime)>>16);
  695. return -1;
  696. }
  697. LM_CRIT("We should not see this!\n");
  698. return res;
  699. }
  700. /**
  701. * Free all memory.
  702. */
  703. void free_sdp(sdp_info_t** _sdp)
  704. {
  705. sdp_info_t *sdp = *_sdp;
  706. sdp_session_cell_t *session, *l_session;
  707. sdp_stream_cell_t *stream, *l_stream;
  708. sdp_payload_attr_t *payload, *l_payload;
  709. sdp_ice_attr_t *tmp;
  710. LM_DBG("_sdp = %p\n", _sdp);
  711. if (sdp == NULL) return;
  712. LM_DBG("sdp = %p\n", sdp);
  713. session = sdp->sessions;
  714. LM_DBG("session = %p\n", session);
  715. while (session) {
  716. l_session = session;
  717. session = session->next;
  718. stream = l_session->streams;
  719. while (stream) {
  720. l_stream = stream;
  721. stream = stream->next;
  722. payload = l_stream->payload_attr;
  723. while (payload) {
  724. l_payload = payload;
  725. payload = payload->next;
  726. pkg_free(l_payload);
  727. }
  728. if (l_stream->p_payload_attr) {
  729. pkg_free(l_stream->p_payload_attr);
  730. }
  731. while (l_stream->ice_attr) {
  732. tmp = l_stream->ice_attr->next;
  733. pkg_free(l_stream->ice_attr);
  734. l_stream->ice_attr = tmp;
  735. }
  736. pkg_free(l_stream);
  737. }
  738. pkg_free(l_session);
  739. }
  740. pkg_free(sdp);
  741. *_sdp = NULL;
  742. }
  743. void print_sdp_stream(sdp_stream_cell_t *stream, int log_level)
  744. {
  745. sdp_payload_attr_t *payload;
  746. sdp_ice_attr_t *ice_attr;
  747. LOG(log_level , "....stream[%d]:%p=>%p {%p} '%.*s' '%.*s:%.*s:%.*s' '%.*s' [%d] '%.*s' '%.*s:%.*s' (%d)=>%p (%d)=>%p '%.*s' '%.*s' '%.*s' '%.*s' '%.*s' '%.*s' '%.*s'\n",
  748. stream->stream_num, stream, stream->next,
  749. stream->p_payload_attr,
  750. stream->media.len, stream->media.s,
  751. stream->ip_addr.len, stream->ip_addr.s, stream->port.len, stream->port.s,
  752. stream->rtcp_port.len, stream->rtcp_port.s,
  753. stream->transport.len, stream->transport.s, stream->is_rtp,
  754. stream->payloads.len, stream->payloads.s,
  755. stream->bw_type.len, stream->bw_type.s, stream->bw_width.len, stream->bw_width.s,
  756. stream->payloads_num, stream->payload_attr,
  757. stream->ice_attrs_num, stream->ice_attr,
  758. stream->sendrecv_mode.len, stream->sendrecv_mode.s,
  759. stream->ptime.len, stream->ptime.s,
  760. stream->path.len, stream->path.s,
  761. stream->max_size.len, stream->max_size.s,
  762. stream->accept_types.len, stream->accept_types.s,
  763. stream->accept_wrapped_types.len, stream->accept_wrapped_types.s,
  764. stream->remote_candidates.len, stream->remote_candidates.s);
  765. payload = stream->payload_attr;
  766. while (payload) {
  767. LOG(log_level, "......payload[%d]:%p=>%p p_payload_attr[%d]:%p '%.*s' '%.*s' '%.*s' '%.*s' '%.*s'\n",
  768. payload->payload_num, payload, payload->next,
  769. payload->payload_num, stream->p_payload_attr[payload->payload_num],
  770. payload->rtp_payload.len, payload->rtp_payload.s,
  771. payload->rtp_enc.len, payload->rtp_enc.s,
  772. payload->rtp_clock.len, payload->rtp_clock.s,
  773. payload->rtp_params.len, payload->rtp_params.s,
  774. payload->fmtp_string.len, payload->fmtp_string.s);
  775. payload=payload->next;
  776. }
  777. ice_attr = stream->ice_attr;
  778. while (ice_attr) {
  779. LOG(log_level, "......'%.*s' %u\n",
  780. ice_attr->foundation.len, ice_attr->foundation.s,
  781. ice_attr->component_id);
  782. ice_attr = ice_attr->next;
  783. }
  784. }
  785. void print_sdp_session(sdp_session_cell_t *session, int log_level)
  786. {
  787. sdp_stream_cell_t *stream;
  788. if (session==NULL) {
  789. LM_ERR("NULL session\n");
  790. return;
  791. }
  792. stream = session->streams;
  793. LOG(log_level, "..session[%d]:%p=>%p '%.*s' '%.*s' '%.*s' '%.*s:%.*s' (%d)=>%p\n",
  794. session->session_num, session, session->next,
  795. session->cnt_disp.len, session->cnt_disp.s,
  796. session->ip_addr.len, session->ip_addr.s,
  797. session->o_ip_addr.len, session->o_ip_addr.s,
  798. session->bw_type.len, session->bw_type.s, session->bw_width.len, session->bw_width.s,
  799. session->streams_num, session->streams);
  800. while (stream) {
  801. print_sdp_stream(stream, log_level);
  802. stream=stream->next;
  803. }
  804. }
  805. void print_sdp(sdp_info_t* sdp, int log_level)
  806. {
  807. sdp_session_cell_t *session;
  808. if (!sdp)
  809. {
  810. LOG(log_level, "no sdp body\n");
  811. return;
  812. }
  813. LOG(log_level, "sdp:%p=>%p (%d:%d)\n", sdp, sdp->sessions, sdp->sessions_num, sdp->streams_num);
  814. session = sdp->sessions;
  815. while (session) {
  816. print_sdp_session(session, log_level);
  817. session = session->next;
  818. }
  819. }
  820. /*
  821. * Free cloned stream.
  822. */
  823. void free_cloned_sdp_stream(sdp_stream_cell_t *_stream)
  824. {
  825. sdp_stream_cell_t *stream, *l_stream;
  826. sdp_payload_attr_t *payload, *l_payload;
  827. stream = _stream;
  828. while (stream) {
  829. l_stream = stream;
  830. stream = stream->next;
  831. payload = l_stream->payload_attr;
  832. while (payload) {
  833. l_payload = payload;
  834. payload = payload->next;
  835. shm_free(l_payload);
  836. }
  837. if (l_stream->p_payload_attr) {
  838. shm_free(l_stream->p_payload_attr);
  839. }
  840. shm_free(l_stream);
  841. }
  842. }
  843. /*
  844. * Free cloned session.
  845. */
  846. void free_cloned_sdp_session(sdp_session_cell_t *_session)
  847. {
  848. sdp_session_cell_t *session, *l_session;
  849. session = _session;
  850. while (session) {
  851. l_session = session;
  852. session = l_session->next;
  853. free_cloned_sdp_stream(l_session->streams);
  854. shm_free(l_session);
  855. }
  856. }
  857. void free_cloned_sdp(sdp_info_t* sdp)
  858. {
  859. free_cloned_sdp_session(sdp->sessions);
  860. shm_free(sdp);
  861. }
  862. sdp_payload_attr_t * clone_sdp_payload_attr(sdp_payload_attr_t *attr)
  863. {
  864. sdp_payload_attr_t * clone_attr;
  865. int len;
  866. char *p;
  867. if (attr == NULL) {
  868. LM_ERR("arg:NULL\n");
  869. return NULL;
  870. }
  871. len = sizeof(sdp_payload_attr_t) +
  872. attr->rtp_payload.len +
  873. attr->rtp_enc.len +
  874. attr->rtp_clock.len +
  875. attr->rtp_params.len +
  876. attr->fmtp_string.len;
  877. clone_attr = (sdp_payload_attr_t*)shm_malloc(len);
  878. if (clone_attr == NULL) {
  879. LM_ERR("no more shm mem (%d)\n",len);
  880. return NULL;
  881. }
  882. memset( clone_attr, 0, len);
  883. p = (char*)(clone_attr+1);
  884. clone_attr->payload_num = attr->payload_num;
  885. if (attr->rtp_payload.len) {
  886. clone_attr->rtp_payload.s = p;
  887. clone_attr->rtp_payload.len = attr->rtp_payload.len;
  888. memcpy( p, attr->rtp_payload.s, attr->rtp_payload.len);
  889. p += attr->rtp_payload.len;
  890. }
  891. if (attr->rtp_enc.len) {
  892. clone_attr->rtp_enc.s = p;
  893. clone_attr->rtp_enc.len = attr->rtp_enc.len;
  894. memcpy( p, attr->rtp_enc.s, attr->rtp_enc.len);
  895. p += attr->rtp_enc.len;
  896. }
  897. if (attr->rtp_clock.len) {
  898. clone_attr->rtp_clock.s = p;
  899. clone_attr->rtp_clock.len = attr->rtp_clock.len;
  900. memcpy( p, attr->rtp_clock.s, attr->rtp_clock.len);
  901. p += attr->rtp_clock.len;
  902. }
  903. if (attr->rtp_params.len) {
  904. clone_attr->rtp_params.s = p;
  905. clone_attr->rtp_params.len = attr->rtp_params.len;
  906. memcpy( p, attr->rtp_params.s, attr->rtp_params.len);
  907. p += attr->rtp_params.len;
  908. }
  909. if (attr->fmtp_string.len) {
  910. clone_attr->fmtp_string.s = p;
  911. clone_attr->fmtp_string.len = attr->fmtp_string.len;
  912. memcpy( p, attr->fmtp_string.s, attr->fmtp_string.len);
  913. p += attr->fmtp_string.len;
  914. }
  915. return clone_attr;
  916. }
  917. sdp_stream_cell_t * clone_sdp_stream_cell(sdp_stream_cell_t *stream)
  918. {
  919. sdp_stream_cell_t *clone_stream;
  920. sdp_payload_attr_t *clone_payload_attr, *payload_attr;
  921. int len, i;
  922. char *p;
  923. if (stream == NULL) {
  924. LM_ERR("arg:NULL\n");
  925. return NULL;
  926. }
  927. /* NOTE: we are not cloning RFC4975 attributes */
  928. len = sizeof(sdp_stream_cell_t) +
  929. stream->ip_addr.len +
  930. stream->media.len +
  931. stream->port.len +
  932. stream->transport.len +
  933. stream->sendrecv_mode.len +
  934. stream->ptime.len +
  935. stream->payloads.len +
  936. stream->bw_type.len +
  937. stream->bw_width.len +
  938. stream->rtcp_port.len;
  939. clone_stream = (sdp_stream_cell_t*)shm_malloc(len);
  940. if (clone_stream == NULL) {
  941. LM_ERR("no more shm mem (%d)\n",len);
  942. return NULL;
  943. }
  944. memset( clone_stream, 0, len);
  945. p = (char*)(clone_stream+1);
  946. payload_attr = NULL;
  947. for (i=0;i<stream->payloads_num;i++) {
  948. clone_payload_attr = clone_sdp_payload_attr(stream->p_payload_attr[i]);
  949. if (clone_payload_attr == NULL) {
  950. LM_ERR("unable to clone attributes for payload[%d]\n", i);
  951. goto error;
  952. }
  953. clone_payload_attr->next = payload_attr;
  954. payload_attr = clone_payload_attr;
  955. }
  956. clone_stream->payload_attr = payload_attr;
  957. clone_stream->payloads_num = stream->payloads_num;
  958. if (clone_stream->payloads_num) {
  959. if (NULL == init_p_payload_attr(clone_stream, USE_SHM_MEM)) {
  960. goto error;
  961. }
  962. }
  963. clone_stream->stream_num = stream->stream_num;
  964. clone_stream->pf = stream->pf;
  965. if (stream->ip_addr.len) {
  966. clone_stream->ip_addr.s = p;
  967. clone_stream->ip_addr.len = stream->ip_addr.len;
  968. memcpy( p, stream->ip_addr.s, stream->ip_addr.len);
  969. p += stream->ip_addr.len;
  970. }
  971. clone_stream->is_rtp = stream->is_rtp;
  972. if (stream->media.len) {
  973. clone_stream->media.s = p;
  974. clone_stream->media.len = stream->media.len;
  975. memcpy( p, stream->media.s, stream->media.len);
  976. p += stream->media.len;
  977. }
  978. if (stream->port.len) {
  979. clone_stream->port.s = p;
  980. clone_stream->port.len = stream->port.len;
  981. memcpy( p, stream->port.s, stream->port.len);
  982. p += stream->port.len;
  983. }
  984. if (stream->transport.len) {
  985. clone_stream->transport.s = p;
  986. clone_stream->transport.len = stream->transport.len;
  987. memcpy( p, stream->transport.s, stream->transport.len);
  988. p += stream->transport.len;
  989. }
  990. if (stream->sendrecv_mode.len) {
  991. clone_stream->sendrecv_mode.s = p;
  992. clone_stream->sendrecv_mode.len = stream->sendrecv_mode.len;
  993. memcpy( p, stream->sendrecv_mode.s, stream->sendrecv_mode.len);
  994. p += stream->sendrecv_mode.len;
  995. }
  996. if (stream->ptime.len) {
  997. clone_stream->ptime.s = p;
  998. clone_stream->ptime.len = stream->ptime.len;
  999. memcpy( p, stream->ptime.s, stream->ptime.len);
  1000. p += stream->ptime.len;
  1001. }
  1002. if (stream->payloads.len) {
  1003. clone_stream->payloads.s = p;
  1004. clone_stream->payloads.len = stream->payloads.len;
  1005. memcpy( p, stream->payloads.s, stream->payloads.len);
  1006. p += stream->payloads.len;
  1007. }
  1008. if (stream->bw_type.len) {
  1009. clone_stream->bw_type.s = p;
  1010. clone_stream->bw_type.len = stream->bw_type.len;
  1011. p += stream->bw_type.len;
  1012. }
  1013. if (stream->bw_width.len) {
  1014. clone_stream->bw_width.s = p;
  1015. clone_stream->bw_width.len = stream->bw_width.len;
  1016. p += stream->bw_width.len;
  1017. }
  1018. if (stream->rtcp_port.len) {
  1019. clone_stream->rtcp_port.s = p;
  1020. clone_stream->rtcp_port.len = stream->rtcp_port.len;
  1021. memcpy( p, stream->rtcp_port.s, stream->rtcp_port.len);
  1022. p += stream->rtcp_port.len;
  1023. }
  1024. /* NOTE: we are not cloning RFC4975 attributes:
  1025. * - path
  1026. * - max_size
  1027. * - accept_types
  1028. * - accept_wrapped_types
  1029. */
  1030. return clone_stream;
  1031. error:
  1032. free_cloned_sdp_stream(clone_stream);
  1033. return NULL;
  1034. }
  1035. sdp_session_cell_t * clone_sdp_session_cell(sdp_session_cell_t *session)
  1036. {
  1037. sdp_session_cell_t *clone_session;
  1038. sdp_stream_cell_t *clone_stream, *prev_clone_stream, *stream;
  1039. int len, i;
  1040. char *p;
  1041. if (session == NULL) {
  1042. LM_ERR("arg:NULL\n");
  1043. return NULL;
  1044. }
  1045. len = sizeof(sdp_session_cell_t) +
  1046. session->cnt_disp.len +
  1047. session->ip_addr.len +
  1048. session->o_ip_addr.len +
  1049. session->bw_type.len +
  1050. session->bw_width.len;
  1051. clone_session = (sdp_session_cell_t*)shm_malloc(len);
  1052. if (clone_session == NULL) {
  1053. LM_ERR("no more shm mem (%d)\n",len);
  1054. return NULL;
  1055. }
  1056. memset( clone_session, 0, len);
  1057. p = (char*)(clone_session+1);
  1058. if (session->streams_num) {
  1059. stream=session->streams;
  1060. clone_stream=clone_sdp_stream_cell(stream);
  1061. if (clone_stream==NULL) {
  1062. goto error;
  1063. }
  1064. clone_session->streams=clone_stream;
  1065. prev_clone_stream=clone_stream;
  1066. stream=stream->next;
  1067. for (i=1;i<session->streams_num;i++) {
  1068. clone_stream=clone_sdp_stream_cell(stream);
  1069. if (clone_stream==NULL) {
  1070. goto error;
  1071. }
  1072. prev_clone_stream->next=clone_stream;
  1073. prev_clone_stream=clone_stream;
  1074. stream=stream->next;
  1075. }
  1076. }
  1077. clone_session->session_num = session->session_num;
  1078. clone_session->pf = session->pf;
  1079. clone_session->o_pf = session->o_pf;
  1080. clone_session->streams_num = session->streams_num;
  1081. if (session->cnt_disp.len) {
  1082. clone_session->cnt_disp.s = p;
  1083. clone_session->cnt_disp.len = session->cnt_disp.len;
  1084. memcpy( p, session->cnt_disp.s, session->cnt_disp.len);
  1085. p += session->cnt_disp.len;
  1086. }
  1087. if (session->ip_addr.len) {
  1088. clone_session->ip_addr.s = p;
  1089. clone_session->ip_addr.len = session->ip_addr.len;
  1090. memcpy( p, session->ip_addr.s, session->ip_addr.len);
  1091. p += session->ip_addr.len;
  1092. }
  1093. if (session->o_ip_addr.len) {
  1094. clone_session->o_ip_addr.s = p;
  1095. clone_session->o_ip_addr.len = session->o_ip_addr.len;
  1096. memcpy( p, session->o_ip_addr.s, session->o_ip_addr.len);
  1097. p += session->o_ip_addr.len;
  1098. }
  1099. if (session->bw_type.len) {
  1100. clone_session->bw_type.s = p;
  1101. clone_session->bw_type.len = session->bw_type.len;
  1102. memcpy( p, session->bw_type.s, session->bw_type.len);
  1103. p += session->bw_type.len;
  1104. }
  1105. if (session->bw_width.len) {
  1106. clone_session->bw_width.s = p;
  1107. clone_session->bw_width.len = session->bw_width.len;
  1108. memcpy( p, session->bw_width.s, session->bw_width.len);
  1109. p += session->bw_width.len;
  1110. }
  1111. return clone_session;
  1112. error:
  1113. free_cloned_sdp_session(clone_session);
  1114. return NULL;
  1115. }
  1116. sdp_info_t * clone_sdp_info(struct sip_msg* _m)
  1117. {
  1118. sdp_info_t *clone_sdp_info, *sdp_info=(sdp_info_t*)_m->body;
  1119. sdp_session_cell_t *clone_session, *prev_clone_session, *session;
  1120. int i, len;
  1121. if (sdp_info==NULL) {
  1122. LM_ERR("no sdp to clone\n");
  1123. return NULL;
  1124. }
  1125. if (sdp_info->type != MSG_BODY_SDP) {
  1126. LM_ERR("Unsupported body type\n");
  1127. return NULL;
  1128. }
  1129. if (sdp_info->sessions_num == 0) {
  1130. LM_ERR("no sessions to clone\n");
  1131. return NULL;
  1132. }
  1133. len = sizeof(sdp_info_t);
  1134. clone_sdp_info = (sdp_info_t*)shm_malloc(len);
  1135. if (clone_sdp_info == NULL) {
  1136. LM_ERR("no more shm mem (%d)\n",len);
  1137. return NULL;
  1138. }
  1139. LM_DBG("clone_sdp_info: %p\n", clone_sdp_info);
  1140. memset( clone_sdp_info, 0, len);
  1141. LM_DBG("we have %d sessions\n", sdp_info->sessions_num);
  1142. clone_sdp_info->sessions_num = sdp_info->sessions_num;
  1143. clone_sdp_info->streams_num = sdp_info->streams_num;
  1144. session=sdp_info->sessions;
  1145. clone_session=clone_sdp_session_cell(session);
  1146. if (clone_session==NULL) {
  1147. goto error;
  1148. }
  1149. clone_sdp_info->sessions=clone_session;
  1150. prev_clone_session=clone_session;
  1151. session=session->next;
  1152. for (i=1;i<sdp_info->sessions_num;i++) {
  1153. clone_session=clone_sdp_session_cell(session);
  1154. if (clone_session==NULL) {
  1155. goto error;
  1156. }
  1157. prev_clone_session->next=clone_session;
  1158. prev_clone_session=clone_session;
  1159. session=session->next;
  1160. }
  1161. return clone_sdp_info;
  1162. error:
  1163. free_cloned_sdp(clone_sdp_info);
  1164. return NULL;
  1165. }