~ubuntu-branches/debian/sid/sflphone/sid

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/pjmedia/src/pjmedia/sdp_cmp.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2013-06-02 18:04:11 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130602180411-3rcpy8c1zdlo8y0s
Tags: 1.2.2-1
* New upstream release
* changeset_rb68857a4b485b7d43f92714cd5792595ff895f82.diff - fix QTest
* pjproject ./configure --disable-sound --disable-video

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sdp_cmp.c 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/* 
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program 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
 
 * This program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19
 
 */
20
 
#include <pjmedia/sdp.h>
21
 
#include <pjmedia/errno.h>
22
 
#include <pj/assert.h>
23
 
#include <pj/string.h>
24
 
 
25
 
 
26
 
/* Compare connection line. */
27
 
static pj_status_t compare_conn(const pjmedia_sdp_conn *c1,
28
 
                                const pjmedia_sdp_conn *c2)
29
 
{
30
 
    /* Compare network type. */
31
 
    if (pj_strcmp(&c1->net_type, &c2->net_type) != 0)
32
 
        return PJMEDIA_SDP_ECONNNOTEQUAL;
33
 
 
34
 
    /* Compare address type. */
35
 
    if (pj_strcmp(&c1->addr_type, &c2->addr_type) != 0)
36
 
        return PJMEDIA_SDP_ECONNNOTEQUAL;
37
 
 
38
 
    /* Compare address. */
39
 
    if (pj_strcmp(&c1->addr, &c2->addr) != 0)
40
 
        return PJMEDIA_SDP_ECONNNOTEQUAL;
41
 
 
42
 
    return PJ_SUCCESS;
43
 
}
44
 
 
45
 
/* Compare attributes array. */
46
 
static pj_status_t compare_attr_imp(unsigned count1,
47
 
                                    pjmedia_sdp_attr *const attr1[],
48
 
                                    unsigned count2,
49
 
                                    pjmedia_sdp_attr *const attr2[])
50
 
{
51
 
    pj_status_t status;
52
 
    unsigned i;
53
 
    const pj_str_t inactive = { "inactive", 8 };
54
 
    const pj_str_t sendrecv = { "sendrecv", 8 };
55
 
    const pj_str_t sendonly = { "sendonly", 8 };
56
 
    const pj_str_t recvonly = { "recvonly", 8 };
57
 
    const pj_str_t fmtp = { "fmtp", 4 };
58
 
    const pj_str_t rtpmap = { "rtpmap", 6 };
59
 
 
60
 
    /* For simplicity, we only compare the following attributes, and ignore
61
 
     * the others:
62
 
     *  - direction, eg. inactive, sendonly, recvonly, sendrecv
63
 
     *  - fmtp for each payload.
64
 
     *  - rtpmap for each payload.
65
 
     */
66
 
    for (i=0; i<count1; ++i) {
67
 
        const pjmedia_sdp_attr *a1 = attr1[i];
68
 
 
69
 
        if (pj_strcmp(&a1->name, &inactive) == 0 || 
70
 
            pj_strcmp(&a1->name, &sendrecv) == 0 ||
71
 
            pj_strcmp(&a1->name, &sendonly) == 0 ||
72
 
            pj_strcmp(&a1->name, &recvonly) == 0)
73
 
        {
74
 
            /* For inactive, sendrecv, sendonly, and recvonly attributes,
75
 
             * the same attribute must be present on the other SDP.
76
 
             */
77
 
            const pjmedia_sdp_attr *a2;
78
 
            a2 = pjmedia_sdp_attr_find(count2, attr2, &a1->name, NULL);
79
 
            if (!a2)
80
 
                return PJMEDIA_SDP_EDIRNOTEQUAL;
81
 
 
82
 
        } else if (pj_strcmp(&a1->name, &fmtp) == 0) {
83
 
            /* For fmtp attribute, find the fmtp attribute in the other SDP
84
 
             * for the same payload type, and compare the fmtp param/value.
85
 
             */
86
 
            pjmedia_sdp_fmtp fmtp1, fmtp2;
87
 
            const pjmedia_sdp_attr *a2;
88
 
 
89
 
            status = pjmedia_sdp_attr_get_fmtp(a1, &fmtp1);
90
 
            if (status != PJ_SUCCESS)
91
 
                return PJMEDIA_SDP_EFMTPNOTEQUAL;
92
 
 
93
 
            a2 = pjmedia_sdp_attr_find(count2, attr2, &a1->name, &fmtp1.fmt);
94
 
            if (!a2)
95
 
                return PJMEDIA_SDP_EFMTPNOTEQUAL;
96
 
 
97
 
            status = pjmedia_sdp_attr_get_fmtp(a2, &fmtp2);
98
 
            if (status != PJ_SUCCESS)
99
 
                return PJMEDIA_SDP_EFMTPNOTEQUAL;
100
 
 
101
 
            if (pj_strcmp(&fmtp1.fmt_param, &fmtp2.fmt_param) != 0)
102
 
                return PJMEDIA_SDP_EFMTPNOTEQUAL;
103
 
 
104
 
        } else if (pj_strcmp(&a1->name, &rtpmap) == 0) {
105
 
            /* For rtpmap attribute, find rtpmap attribute on the other SDP
106
 
             * for the same payload type, and compare both rtpmap atribute
107
 
             * values.
108
 
             */
109
 
            pjmedia_sdp_rtpmap r1, r2;
110
 
            const pjmedia_sdp_attr *a2;
111
 
 
112
 
            status = pjmedia_sdp_attr_get_rtpmap(a1, &r1);
113
 
            if (status != PJ_SUCCESS)
114
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
115
 
 
116
 
            a2 = pjmedia_sdp_attr_find(count2, attr2, &a1->name, &r1.pt);
117
 
            if (!a2)
118
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
119
 
 
120
 
            status = pjmedia_sdp_attr_get_rtpmap(a2, &r2);
121
 
            if (status != PJ_SUCCESS)
122
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
123
 
 
124
 
            if (pj_strcmp(&r1.pt, &r2.pt) != 0)
125
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
126
 
            if (pj_strcmp(&r1.enc_name, &r2.enc_name) != 0)
127
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
128
 
            if (r1.clock_rate != r2.clock_rate)
129
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
130
 
            if (pj_strcmp(&r1.param, &r2.param) != 0)
131
 
                return PJMEDIA_SDP_ERTPMAPNOTEQUAL;
132
 
        }
133
 
    }
134
 
 
135
 
    return PJ_SUCCESS;
136
 
}
137
 
 
138
 
 
139
 
/* Compare attributes array. */
140
 
static pj_status_t compare_attr(unsigned count1,
141
 
                                pjmedia_sdp_attr *const attr1[],
142
 
                                unsigned count2,
143
 
                                pjmedia_sdp_attr *const attr2[])
144
 
{
145
 
    pj_status_t status;
146
 
 
147
 
    status = compare_attr_imp(count1, attr1, count2, attr2);
148
 
    if (status != PJ_SUCCESS)
149
 
        return status;
150
 
 
151
 
    status = compare_attr_imp(count2, attr2, count1, attr1);
152
 
    if (status != PJ_SUCCESS)
153
 
        return status;
154
 
 
155
 
    return PJ_SUCCESS;
156
 
}
157
 
 
158
 
/* Compare media descriptor */
159
 
PJ_DEF(pj_status_t) pjmedia_sdp_media_cmp( const pjmedia_sdp_media *sd1,
160
 
                                           const pjmedia_sdp_media *sd2,
161
 
                                           unsigned option)
162
 
{
163
 
    unsigned i;
164
 
    pj_status_t status;
165
 
 
166
 
    PJ_ASSERT_RETURN(sd1 && sd2 && option==0, PJ_EINVAL);
167
 
 
168
 
    PJ_UNUSED_ARG(option);
169
 
 
170
 
    /* Compare media type. */
171
 
    if (pj_strcmp(&sd1->desc.media, &sd2->desc.media) != 0)
172
 
        return PJMEDIA_SDP_EMEDIANOTEQUAL;
173
 
 
174
 
    /* Compare port number. */
175
 
    if (sd1->desc.port != sd2->desc.port)
176
 
        return PJMEDIA_SDP_EPORTNOTEQUAL;
177
 
 
178
 
    /* Compare port count. */
179
 
    if (sd1->desc.port_count != sd2->desc.port_count)
180
 
        return PJMEDIA_SDP_EPORTNOTEQUAL;
181
 
 
182
 
    /* Compare transports. */
183
 
    if (pj_strcmp(&sd1->desc.transport, &sd2->desc.transport) != 0)
184
 
        return PJMEDIA_SDP_ETPORTNOTEQUAL;
185
 
 
186
 
    /* For zeroed port media, stop comparing here */
187
 
    if (sd1->desc.port == 0)
188
 
        return PJ_SUCCESS;
189
 
 
190
 
    /* Compare number of formats. */
191
 
    if (sd1->desc.fmt_count != sd2->desc.fmt_count)
192
 
        return PJMEDIA_SDP_EFORMATNOTEQUAL;
193
 
 
194
 
    /* Compare formats, in order. */
195
 
    for (i=0; i<sd1->desc.fmt_count; ++i) {
196
 
        if (pj_strcmp(&sd1->desc.fmt[i], &sd2->desc.fmt[i]) != 0)
197
 
            return PJMEDIA_SDP_EFORMATNOTEQUAL;
198
 
    }
199
 
 
200
 
    /* Compare connection line, if they exist. */
201
 
    if (sd1->conn) {
202
 
        if (!sd2->conn)
203
 
            return PJMEDIA_SDP_EMEDIANOTEQUAL;
204
 
        status = compare_conn(sd1->conn, sd2->conn);
205
 
    } else {
206
 
        if (sd2->conn)
207
 
            return PJMEDIA_SDP_EMEDIANOTEQUAL;
208
 
    }
209
 
 
210
 
    /* Compare attributes. */
211
 
    status = compare_attr(sd1->attr_count, sd1->attr, 
212
 
                          sd2->attr_count, sd2->attr);
213
 
    if (status != PJ_SUCCESS)
214
 
        return status;
215
 
 
216
 
    /* Looks equal */
217
 
    return PJ_SUCCESS;
218
 
}
219
 
 
220
 
/*
221
 
 * Compare two SDP session for equality.
222
 
 */
223
 
PJ_DEF(pj_status_t) pjmedia_sdp_session_cmp( const pjmedia_sdp_session *sd1,
224
 
                                             const pjmedia_sdp_session *sd2,
225
 
                                             unsigned option)
226
 
{
227
 
    unsigned i;
228
 
    pj_status_t status;
229
 
 
230
 
    PJ_ASSERT_RETURN(sd1 && sd2 && option==0, PJ_EINVAL);
231
 
 
232
 
    PJ_UNUSED_ARG(option);
233
 
 
234
 
    /* Compare the origin line. */
235
 
    if (pj_strcmp(&sd1->origin.user, &sd2->origin.user) != 0)
236
 
        return PJMEDIA_SDP_EORIGINNOTEQUAL;
237
 
 
238
 
    if (sd1->origin.id != sd2->origin.id)
239
 
        return PJMEDIA_SDP_EORIGINNOTEQUAL;
240
 
 
241
 
    if (sd1->origin.version != sd2->origin.version)
242
 
        return PJMEDIA_SDP_EORIGINNOTEQUAL;
243
 
 
244
 
    if (pj_strcmp(&sd1->origin.net_type, &sd2->origin.net_type) != 0)
245
 
        return PJMEDIA_SDP_EORIGINNOTEQUAL;
246
 
 
247
 
    if (pj_strcmp(&sd1->origin.addr_type, &sd2->origin.addr_type) != 0)
248
 
        return PJMEDIA_SDP_EORIGINNOTEQUAL;
249
 
 
250
 
    if (pj_strcmp(&sd1->origin.addr, &sd2->origin.addr) != 0)
251
 
        return PJMEDIA_SDP_EORIGINNOTEQUAL;
252
 
 
253
 
    
254
 
    /* Compare the subject line. */
255
 
    if (pj_strcmp(&sd1->name, &sd2->name) != 0)
256
 
        return PJMEDIA_SDP_ENAMENOTEQUAL;
257
 
 
258
 
    /* Compare connection line, when they exist */
259
 
    if (sd1->conn) {
260
 
        if (!sd2->conn)
261
 
            return PJMEDIA_SDP_ECONNNOTEQUAL;
262
 
        status = compare_conn(sd1->conn, sd2->conn);
263
 
        if (status != PJ_SUCCESS)
264
 
            return status;
265
 
    } else {
266
 
        if (sd2->conn)
267
 
            return PJMEDIA_SDP_ECONNNOTEQUAL;
268
 
    }
269
 
 
270
 
    /* Compare time line. */
271
 
    if (sd1->time.start != sd2->time.start)
272
 
        return PJMEDIA_SDP_ETIMENOTEQUAL;
273
 
 
274
 
    if (sd1->time.stop != sd2->time.stop)
275
 
        return PJMEDIA_SDP_ETIMENOTEQUAL;
276
 
 
277
 
    /* Compare attributes. */
278
 
    status = compare_attr(sd1->attr_count, sd1->attr, 
279
 
                          sd2->attr_count, sd2->attr);
280
 
    if (status != PJ_SUCCESS)
281
 
        return status;
282
 
 
283
 
    /* Compare media lines. */
284
 
    if (sd1->media_count != sd2->media_count)
285
 
        return PJMEDIA_SDP_EMEDIANOTEQUAL;
286
 
 
287
 
    for (i=0; i<sd1->media_count; ++i) {
288
 
        status = pjmedia_sdp_media_cmp(sd1->media[i], sd2->media[i], 0);
289
 
        if (status != PJ_SUCCESS)
290
 
            return status;
291
 
    }
292
 
 
293
 
    /* Looks equal. */
294
 
    return PJ_SUCCESS;
295
 
}
296
 
 
297