Commit | Line | Data |
---|---|---|
23e7e3ae JVH |
1 | /** |
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua | |
3 | * | |
4 | * This library is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License as published by the Free Software Foundation; either | |
7 | * version 2.1 of the License, or (at your option) any later version. | |
8 | * | |
9 | * This library is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * Lesser General Public License for more details. | |
13 | */ | |
14 | ||
2340bcd3 JVH |
15 | #include <stdlib.h> |
16 | #include <string.h> | |
17 | #include <assert.h> | |
18 | ||
19 | #include "sdp.h" | |
20 | ||
21 | struct sdp_s { | |
22 | char *data; | |
23 | ||
24 | /* Actual SDP records */ | |
25 | const char *version; | |
26 | const char *origin; | |
27 | const char *connection; | |
28 | const char *session; | |
29 | const char *time; | |
30 | const char *media; | |
31 | ||
32 | /* Additional SDP records */ | |
33 | const char *rtpmap; | |
34 | const char *fmtp; | |
35 | const char *rsaaeskey; | |
36 | const char *aesiv; | |
37 | const char *min_latency; | |
38 | }; | |
39 | ||
40 | static void | |
41 | parse_sdp_line(sdp_t *sdp, char *line) | |
42 | { | |
43 | int len = strlen(line); | |
44 | if (len < 2 || line[1] != '=') { | |
45 | return; | |
46 | } | |
47 | ||
48 | switch (line[0]) { | |
49 | case 'v': | |
50 | sdp->version = &line[2]; | |
51 | break; | |
52 | case 'o': | |
53 | sdp->origin = &line[2]; | |
54 | break; | |
55 | case 's': | |
56 | sdp->session = &line[2]; | |
57 | break; | |
58 | case 'c': | |
59 | sdp->connection = &line[2]; | |
60 | break; | |
61 | case 't': | |
62 | sdp->time = &line[2]; | |
63 | break; | |
64 | case 'm': | |
65 | sdp->media = &line[2]; | |
66 | break; | |
67 | case 'a': | |
68 | { | |
69 | char *key; | |
70 | char *value; | |
71 | ||
72 | /* Parse key and value */ | |
73 | key = &line[2]; | |
74 | value = strstr(line, ":"); | |
75 | if (!value) break; | |
76 | *(value++) = '\0'; | |
77 | ||
c8729c31 | 78 | if (!strcmp(key, "rtpmap") && !sdp->rtpmap) { |
2340bcd3 | 79 | sdp->rtpmap = value; |
c8729c31 | 80 | } else if (!strcmp(key, "fmtp") && !sdp->fmtp) { |
2340bcd3 JVH |
81 | sdp->fmtp = value; |
82 | } else if (!strcmp(key, "rsaaeskey")) { | |
83 | sdp->rsaaeskey = value; | |
84 | } else if (!strcmp(key, "aesiv")) { | |
85 | sdp->aesiv = value; | |
86 | } else if (!strcmp(key, "min-latency")) { | |
87 | sdp->min_latency = value; | |
88 | } | |
89 | break; | |
90 | } | |
91 | } | |
92 | } | |
93 | ||
94 | static void | |
95 | parse_sdp_data(sdp_t *sdp) | |
96 | { | |
97 | int pos, len; | |
98 | ||
99 | pos = 0; | |
100 | len = strlen(sdp->data); | |
101 | while (pos < len) { | |
102 | int lfpos; | |
103 | ||
104 | /* Find newline in string */ | |
105 | for (lfpos=pos; sdp->data[lfpos]; lfpos++) { | |
106 | if (sdp->data[lfpos] == '\n') { | |
107 | break; | |
108 | } | |
109 | } | |
110 | if (sdp->data[lfpos] != '\n') { | |
111 | break; | |
112 | } | |
113 | ||
114 | /* Replace newline with '\0' and parse line */ | |
115 | sdp->data[lfpos] = '\0'; | |
116 | if (lfpos > pos && sdp->data[lfpos-1] == '\r') { | |
117 | sdp->data[lfpos-1] = '\0'; | |
118 | } | |
119 | parse_sdp_line(sdp, sdp->data+pos); | |
120 | pos = lfpos+1; | |
121 | } | |
122 | } | |
123 | ||
124 | sdp_t * | |
125 | sdp_init(const char *sdpdata, int sdpdatalen) | |
126 | { | |
127 | sdp_t *sdp; | |
128 | ||
129 | sdp = calloc(1, sizeof(sdp_t)); | |
130 | if (!sdp) { | |
131 | return NULL; | |
132 | } | |
133 | ||
134 | /* Allocate data buffer */ | |
135 | sdp->data = malloc(sdpdatalen+1); | |
136 | if (!sdp->data) { | |
137 | free(sdp); | |
138 | return NULL; | |
139 | } | |
140 | memcpy(sdp->data, sdpdata, sdpdatalen); | |
141 | sdp->data[sdpdatalen] = '\0'; | |
142 | parse_sdp_data(sdp); | |
143 | return sdp; | |
144 | } | |
145 | ||
146 | void | |
147 | sdp_destroy(sdp_t *sdp) | |
148 | { | |
149 | if (sdp) { | |
150 | free(sdp->data); | |
151 | free(sdp); | |
152 | } | |
153 | } | |
154 | ||
155 | const char * | |
156 | sdp_get_version(sdp_t *sdp) | |
157 | { | |
158 | assert(sdp); | |
159 | ||
160 | return sdp->version; | |
161 | } | |
162 | ||
163 | const char * | |
164 | sdp_get_origin(sdp_t *sdp) | |
165 | { | |
166 | assert(sdp); | |
167 | ||
168 | return sdp->origin; | |
169 | } | |
170 | ||
171 | const char * | |
172 | sdp_get_session(sdp_t *sdp) | |
173 | { | |
174 | assert(sdp); | |
175 | ||
176 | return sdp->session; | |
177 | } | |
178 | ||
179 | const char * | |
180 | sdp_get_connection(sdp_t *sdp) | |
181 | { | |
182 | assert(sdp); | |
183 | ||
184 | return sdp->connection; | |
185 | } | |
186 | ||
187 | const char * | |
188 | sdp_get_time(sdp_t *sdp) | |
189 | { | |
190 | assert(sdp); | |
191 | ||
192 | return sdp->time; | |
193 | } | |
194 | ||
195 | const char * | |
196 | sdp_get_media(sdp_t *sdp) | |
197 | { | |
198 | assert(sdp); | |
199 | ||
200 | return sdp->media; | |
201 | } | |
202 | ||
203 | const char * | |
204 | sdp_get_rtpmap(sdp_t *sdp) | |
205 | { | |
206 | assert(sdp); | |
207 | ||
208 | return sdp->rtpmap; | |
209 | } | |
210 | ||
211 | const char * | |
212 | sdp_get_fmtp(sdp_t *sdp) | |
213 | { | |
214 | assert(sdp); | |
215 | ||
216 | return sdp->fmtp; | |
217 | } | |
218 | ||
219 | const char * | |
220 | sdp_get_rsaaeskey(sdp_t *sdp) | |
221 | { | |
222 | assert(sdp); | |
223 | ||
224 | return sdp->rsaaeskey; | |
225 | } | |
226 | ||
227 | const char * | |
228 | sdp_get_aesiv(sdp_t *sdp) | |
229 | { | |
230 | assert(sdp); | |
231 | ||
232 | return sdp->aesiv; | |
233 | } | |
234 | ||
235 | const char * | |
236 | sdp_get_min_latency(sdp_t *sdp) | |
237 | { | |
238 | assert(sdp); | |
239 | ||
240 | return sdp->min_latency; | |
241 | } | |
242 |