~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: sdp_cmp.c 3664 2011-07-19 03:42:28Z 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
 
 
298
PJ_DEF(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1, 
 
299
                                         const pjmedia_sdp_conn *conn2,
 
300
                                         unsigned option)
 
301
{
 
302
    PJ_UNUSED_ARG(option);
 
303
    return compare_conn(conn1, conn2);
 
304
}