Move src to src/lib, include to src/include, test to src/test.
[deb_shairplay.git] / src / lib / sdp.c
CommitLineData
2340bcd3
JVH
1#include <stdlib.h>
2#include <string.h>
3#include <assert.h>
4
5#include "sdp.h"
6
7struct sdp_s {
8 char *data;
9
10 /* Actual SDP records */
11 const char *version;
12 const char *origin;
13 const char *connection;
14 const char *session;
15 const char *time;
16 const char *media;
17
18 /* Additional SDP records */
19 const char *rtpmap;
20 const char *fmtp;
21 const char *rsaaeskey;
22 const char *aesiv;
23 const char *min_latency;
24};
25
26static void
27parse_sdp_line(sdp_t *sdp, char *line)
28{
29 int len = strlen(line);
30 if (len < 2 || line[1] != '=') {
31 return;
32 }
33
34 switch (line[0]) {
35 case 'v':
36 sdp->version = &line[2];
37 break;
38 case 'o':
39 sdp->origin = &line[2];
40 break;
41 case 's':
42 sdp->session = &line[2];
43 break;
44 case 'c':
45 sdp->connection = &line[2];
46 break;
47 case 't':
48 sdp->time = &line[2];
49 break;
50 case 'm':
51 sdp->media = &line[2];
52 break;
53 case 'a':
54 {
55 char *key;
56 char *value;
57
58 /* Parse key and value */
59 key = &line[2];
60 value = strstr(line, ":");
61 if (!value) break;
62 *(value++) = '\0';
63
64 if (!strcmp(key, "rtpmap")) {
65 sdp->rtpmap = value;
66 } else if (!strcmp(key, "fmtp")) {
67 sdp->fmtp = value;
68 } else if (!strcmp(key, "rsaaeskey")) {
69 sdp->rsaaeskey = value;
70 } else if (!strcmp(key, "aesiv")) {
71 sdp->aesiv = value;
72 } else if (!strcmp(key, "min-latency")) {
73 sdp->min_latency = value;
74 }
75 break;
76 }
77 }
78}
79
80static void
81parse_sdp_data(sdp_t *sdp)
82{
83 int pos, len;
84
85 pos = 0;
86 len = strlen(sdp->data);
87 while (pos < len) {
88 int lfpos;
89
90 /* Find newline in string */
91 for (lfpos=pos; sdp->data[lfpos]; lfpos++) {
92 if (sdp->data[lfpos] == '\n') {
93 break;
94 }
95 }
96 if (sdp->data[lfpos] != '\n') {
97 break;
98 }
99
100 /* Replace newline with '\0' and parse line */
101 sdp->data[lfpos] = '\0';
102 if (lfpos > pos && sdp->data[lfpos-1] == '\r') {
103 sdp->data[lfpos-1] = '\0';
104 }
105 parse_sdp_line(sdp, sdp->data+pos);
106 pos = lfpos+1;
107 }
108}
109
110sdp_t *
111sdp_init(const char *sdpdata, int sdpdatalen)
112{
113 sdp_t *sdp;
114
115 sdp = calloc(1, sizeof(sdp_t));
116 if (!sdp) {
117 return NULL;
118 }
119
120 /* Allocate data buffer */
121 sdp->data = malloc(sdpdatalen+1);
122 if (!sdp->data) {
123 free(sdp);
124 return NULL;
125 }
126 memcpy(sdp->data, sdpdata, sdpdatalen);
127 sdp->data[sdpdatalen] = '\0';
128 parse_sdp_data(sdp);
129 return sdp;
130}
131
132void
133sdp_destroy(sdp_t *sdp)
134{
135 if (sdp) {
136 free(sdp->data);
137 free(sdp);
138 }
139}
140
141const char *
142sdp_get_version(sdp_t *sdp)
143{
144 assert(sdp);
145
146 return sdp->version;
147}
148
149const char *
150sdp_get_origin(sdp_t *sdp)
151{
152 assert(sdp);
153
154 return sdp->origin;
155}
156
157const char *
158sdp_get_session(sdp_t *sdp)
159{
160 assert(sdp);
161
162 return sdp->session;
163}
164
165const char *
166sdp_get_connection(sdp_t *sdp)
167{
168 assert(sdp);
169
170 return sdp->connection;
171}
172
173const char *
174sdp_get_time(sdp_t *sdp)
175{
176 assert(sdp);
177
178 return sdp->time;
179}
180
181const char *
182sdp_get_media(sdp_t *sdp)
183{
184 assert(sdp);
185
186 return sdp->media;
187}
188
189const char *
190sdp_get_rtpmap(sdp_t *sdp)
191{
192 assert(sdp);
193
194 return sdp->rtpmap;
195}
196
197const char *
198sdp_get_fmtp(sdp_t *sdp)
199{
200 assert(sdp);
201
202 return sdp->fmtp;
203}
204
205const char *
206sdp_get_rsaaeskey(sdp_t *sdp)
207{
208 assert(sdp);
209
210 return sdp->rsaaeskey;
211}
212
213const char *
214sdp_get_aesiv(sdp_t *sdp)
215{
216 assert(sdp);
217
218 return sdp->aesiv;
219}
220
221const char *
222sdp_get_min_latency(sdp_t *sdp)
223{
224 assert(sdp);
225
226 return sdp->min_latency;
227}
228