sdpops_data.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2011 Daniel-Constantin Mierla (asipto.com)
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. */
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include "../../dprint.h"
  27. #include "../../trim.h"
  28. #include "sdpops_data.h"
  29. /*
  30. http://www.iana.org/assignments/rtp-parameters
  31. Registry Name: RTP Payload types (PT) for standard audio and video encodings - Closed
  32. Reference: [RFC3551]
  33. Registration Procedures: Registry closed; see [RFC3551], Section 3
  34. Note:
  35. The RFC "RTP Profile for Audio and Video Conferences with Minimal
  36. Control" [RFC3551] specifies an initial set "payload types". This
  37. list maintains and extends that list.
  38. Registry:
  39. PT encoding name audio/video (A/V) clock rate (Hz) channels (audio) Reference
  40. -------- -------------- ----------------- --------------- ---------------- ---------
  41. 0 PCMU A 8000 1 [RFC3551]
  42. 1 Reserved
  43. 2 Reserved
  44. 3 GSM A 8000 1 [RFC3551]
  45. 4 G723 A 8000 1 [Kumar][RFC3551]
  46. 5 DVI4 A 8000 1 [RFC3551]
  47. 6 DVI4 A 16000 1 [RFC3551]
  48. 7 LPC A 8000 1 [RFC3551]
  49. 8 PCMA A 8000 1 [RFC3551]
  50. 9 G722 A 8000 1 [RFC3551]
  51. 10 L16 A 44100 2 [RFC3551]
  52. 11 L16 A 44100 1 [RFC3551]
  53. 12 QCELP A 8000 1 [RFC3551]
  54. 13 CN A 8000 1 [RFC3389]
  55. 14 MPA A 90000 [RFC3551][RFC2250]
  56. 15 G728 A 8000 1 [RFC3551]
  57. 16 DVI4 A 11025 1 [DiPol]
  58. 17 DVI4 A 22050 1 [DiPol]
  59. 18 G729 A 8000 1 [RFC3551]
  60. 19 Reserved A
  61. 20 Unassigned A
  62. 21 Unassigned A
  63. 22 Unassigned A
  64. 23 Unassigned A
  65. 24 Unassigned V
  66. 25 CelB V 90000 [RFC2029]
  67. 26 JPEG V 90000 [RFC2435]
  68. 27 Unassigned V
  69. 28 nv V 90000 [RFC3551]
  70. 29 Unassigned V
  71. 30 Unassigned V
  72. 31 H261 V 90000 [RFC4587]
  73. 32 MPV V 90000 [RFC2250]
  74. 33 MP2T AV 90000 [RFC2250]
  75. 34 H263 V 90000 [Zhu]
  76. 35-71 Unassigned ?
  77. 72-76 Reserved for RTCP conflict avoidance [RFC3551]
  78. 77-95 Unassigned ?
  79. 96-127 dynamic ? [RFC3551]
  80. Registry Name: RTP Payload Format media types
  81. Reference: [RFC4855]
  82. Registration Procedures: Standards Action Process or expert approval
  83. */
  84. typedef struct _codecsmap {
  85. str name;
  86. str ids;
  87. } codecsmap_t;
  88. codecsmap_t sdpops_codecsmap_table[] = {
  89. { {"PCMU", 4}, {"0", 1} },
  90. { {"GSM", 3}, {"3", 1} },
  91. { {"G723", 4}, {"4", 1} },
  92. { {"DVI4", 4}, {"5,6,16,17", 9} },
  93. { {"LPC", 3}, {"7", 1} },
  94. { {"PCMA", 4}, {"8", 1} },
  95. { {"G722", 4}, {"9", 1} },
  96. { {"L16", 3}, {"10,11", 5} },
  97. { {"QCELP", 5}, {"12", 2} },
  98. { {"CN", 2}, {"13", 5} },
  99. { {"MPA", 3}, {"14", 2} },
  100. { {"G728", 4}, {"15", 2} },
  101. { {"G729", 4}, {"18", 2} },
  102. { {0, 0}, {0, 0} }
  103. };
  104. /**
  105. * set the string with the IDs mapped to codec name
  106. * - return 0 if found, -1 if not found
  107. */
  108. int sdpops_get_ids_by_name(str *name, str *ids)
  109. {
  110. int i;
  111. for(i=0; sdpops_codecsmap_table[i].name.s!=0; i++)
  112. {
  113. if(name->len==sdpops_codecsmap_table[i].name.len
  114. && strncasecmp(sdpops_codecsmap_table[i].name.s, name->s,
  115. name->len)==0)
  116. {
  117. *ids = sdpops_codecsmap_table[i].ids;
  118. return 0;
  119. }
  120. }
  121. ids->s = NULL;
  122. ids->len = 0;
  123. return -1;
  124. }
  125. /**
  126. * get codec IDs from a= lines based on name
  127. */
  128. int sdpops_sdp_get_ids_by_name(sdp_info_t *sdp, str *cname, str *cids, int n)
  129. {
  130. int sdp_session_num;
  131. int sdp_stream_num;
  132. sdp_session_cell_t *sdp_session;
  133. sdp_stream_cell_t *sdp_stream;
  134. sdp_payload_attr_t *sdp_payload;
  135. int i;
  136. sdp_session_num = 0;
  137. i = 0;
  138. for(;;)
  139. {
  140. sdp_session = get_sdp_session_sdp(sdp, sdp_session_num);
  141. if(!sdp_session) break;
  142. sdp_stream_num = 0;
  143. for(;;)
  144. {
  145. sdp_stream = get_sdp_stream_sdp(sdp, sdp_session_num,
  146. sdp_stream_num);
  147. if(!sdp_stream) break;
  148. sdp_payload = sdp_stream->payload_attr;
  149. while (sdp_payload) {
  150. if(sdp_payload->rtp_enc.len==cname->len
  151. && strncasecmp(cname->s, sdp_payload->rtp_enc.s,
  152. cname->len)==0)
  153. {
  154. if(i==n)
  155. goto notfound;
  156. cids[i] = sdp_payload->rtp_payload;
  157. i++;
  158. }
  159. sdp_payload=sdp_payload->next;
  160. }
  161. sdp_stream_num++;
  162. }
  163. sdp_session_num++;
  164. }
  165. if(i==0)
  166. goto notfound;
  167. if(i<n)
  168. cids[i].s = NULL;
  169. return 0;
  170. notfound:
  171. cids[0].s = NULL;
  172. cids[0].len = 0;
  173. return -1;
  174. }
  175. /**
  176. * build the csv list of ids from csv list of names
  177. */
  178. int sdpops_build_ids_list(sdp_info_t *sdp, str *names, str *ids)
  179. {
  180. #define SDPOPS_MAX_LIST_SIZE 64
  181. static char _local_idslist[SDPOPS_MAX_LIST_SIZE];
  182. str tmp;
  183. str codec;
  184. #define SDPOPS_CIDS_SIZE 8
  185. str cids[SDPOPS_CIDS_SIZE];
  186. char *p;
  187. int i;
  188. tmp = *names;
  189. ids->len = 0;
  190. ids->s = 0;
  191. p = _local_idslist;
  192. while(str_find_token(&tmp, &codec, ',')==0
  193. && codec.len>0)
  194. {
  195. tmp.len -= (int)(&codec.s[codec.len]-codec.s);
  196. tmp.s = codec.s + codec.len;
  197. cids[0].s = NULL;
  198. if(sdpops_get_ids_by_name(&codec, &cids[0])==0) {
  199. LM_DBG("codecs list [%.*s] - at name [%.*s] with list ids [%.*s]\n",
  200. names->len, names->s,
  201. codec.len, codec.s,
  202. cids[0].len, cids[0].s);
  203. cids[1].s = NULL;
  204. } else {
  205. if(sdpops_sdp_get_ids_by_name(sdp, &codec, cids, SDPOPS_CIDS_SIZE)==0) {
  206. LM_DBG("codecs list [%.*s] - at name [%.*s] with first sdp id [%.*s]\n",
  207. names->len, names->s,
  208. codec.len, codec.s,
  209. cids[0].len, cids[0].s);
  210. }
  211. }
  212. for(i=0; i<SDPOPS_CIDS_SIZE && cids[i].s!=NULL; i++) {
  213. if(ids->len + cids[i].len>=SDPOPS_MAX_LIST_SIZE)
  214. {
  215. LM_ERR("the list with codecs ids is too big\n");
  216. ids->len = 0;
  217. ids->s = 0;
  218. return -1;
  219. }
  220. strncpy(p, cids[i].s, cids[i].len);
  221. p += cids[i].len;
  222. *p = ',';
  223. p++;
  224. ids->len += cids[i].len + 1;
  225. }
  226. }
  227. if(ids->len>0)
  228. {
  229. p--;
  230. ids->len--;
  231. *p = '\0';
  232. ids->s = _local_idslist;
  233. LM_DBG("codecs list [%.*s] - ids list [%.*s]\n",
  234. names->len, names->s,
  235. ids->len, ids->s);
  236. return 0;
  237. }
  238. return -1;
  239. }
  240. /**
  241. *
  242. */
  243. int str_find_token(str *text, str *result, char delim)
  244. {
  245. int i;
  246. if(text==NULL || result==NULL)
  247. return -1;
  248. if(text->s[0] == delim)
  249. {
  250. text->s += 1;
  251. text->len -= 1;
  252. }
  253. trim_leading(text);
  254. result->s = text->s;
  255. result->len = 0;
  256. for (i=0; i<text->len; i++)
  257. {
  258. if(result->s[i]==delim || result->s[i]=='\0'
  259. || result->s[i]=='\r' || result->s[i]=='\n')
  260. return 0;
  261. result->len++;
  262. }
  263. return 0;
  264. }