source: verona/phapi/sdphandler.c @ 131:acaf0886270b

Last change on this file since 131:acaf0886270b was 131:acaf0886270b, checked in by Vadim Lebedev <vadim@…>, 2 years ago

BIG patch to bring old verona to the XXX level

File size: 19.9 KB
Line 
1/*
2 * Linphone is sip (RFC3261) compatible internet phone.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17
18
19#include <stdlib.h>
20#include <string.h>
21
22#include "sdphandler.h"
23#include <osipparser2/osip_port.h>
24#include <osipparser2/osip_list.h>
25#include <osipparser2/sdp_message.h>
26#include <eXosip2/eXosip.h>
27#include <ortp/b64.h>
28#include <mediastreamer2/mscommon.h>
29
30#define keywordcmp(key,str)  strncmp(key,str,strlen(key))
31
32
33#define sstrdup_sprintf ms_strdup_printf
34
35#define eXosip_trace(loglevel,args)  do        \
36                {                       \
37        char *__strmsg;  \
38        __strmsg=ms_strdup_printf args ;    \
39        OSIP_TRACE(osip_trace(__FILE__,__LINE__,(loglevel),NULL,"%s\n",__strmsg)); \
40        osip_free (__strmsg);        \
41                }while (0);
42
43
44static char *make_relay_session_id(const char *username, const char *relay){
45        /*ideally this should be a hash of the parameters with a random part*/
46        char tmp[128];
47        int s1=(int)random();
48        int s2=(int)random();
49        long long int res=((long long int)s1)<<32 | (long long int) s2;
50        void *src=&res;
51        s1 = b64_encode(src, sizeof(long long int), tmp, sizeof(tmp));
52        tmp[s1] = '\0';
53        return osip_strdup(tmp);
54}
55
56char * int_2char(int a){
57        char *p=osip_malloc(16);
58        snprintf(p,16,"%i",a);
59        return p;
60}
61
62int
63sdp_payload_list_add(struct osip_list* list, int pt, const char *rtpmap, int line)
64{
65        sdp_payload_t *payload = osip_malloc(sizeof(*payload));
66
67        sdp_payload_init(payload);
68        payload->pt = pt;
69        payload->line = line;
70        payload->a_rtpmap = osip_strdup(rtpmap);
71        return osip_list_add(list, payload, -1);
72}
73
74int
75sdp_payload_clone(void *vsrc, void **vdst)
76{
77        sdp_payload_t *src = vsrc;
78        sdp_payload_t **dst = (sdp_payload_t **) vdst;
79
80        *dst = osip_malloc(sizeof(**dst));
81        sdp_payload_init(*dst);
82        (*dst)->pt = src->pt;
83        (*dst)->line = src->line;
84        (*dst)->a_ptime = src->a_ptime;
85        (*dst)->a_rtpmap = osip_strdup(src->a_rtpmap);
86        return 0;
87}
88
89void sdp_parse_rtpmap(const char *rtpmap, int *clock_rate, int *channels, int *mime_len)
90{
91        char* subtype = ortp_strdup( rtpmap );
92        char* rate_str = NULL;
93        char* chan_str = NULL;
94
95
96        /* find the slash after the subtype */
97        rate_str = strchr(subtype, '/');
98        if (rate_str && strlen(rate_str)>1) {
99                *mime_len = rate_str - subtype;
100                *rate_str = 0;
101                rate_str++;
102
103                /* Look for another slash */
104                chan_str = strchr(rate_str, '/');
105                if (chan_str && strlen(chan_str)>1) {
106                        *chan_str = 0;
107                        chan_str++;
108                } else {
109                        chan_str = NULL;
110                }
111        } else {
112                rate_str = NULL;
113                *mime_len = strlen(subtype);
114        }
115
116        // Use default clock rate if none given
117        if (rate_str) *clock_rate = atoi(rate_str);
118        else *clock_rate = 8000;
119
120        // Use default number of channels if none given
121        if (chan_str) *channels = atoi(chan_str);
122        else *channels = -1;
123
124        ortp_free(subtype);
125}
126
127
128int
129sdp_equal_payload(const sdp_payload_t *cur_payload, const sdp_payload_t *payload)
130{
131        int rate1, rate2, channels1, channels2, mime_len1, mime_len2;
132
133        sdp_parse_rtpmap(cur_payload->a_rtpmap, &rate1, &channels1, &mime_len1);
134        sdp_parse_rtpmap(payload->a_rtpmap, &rate2, &channels2, &mime_len2);
135
136        if (mime_len1 != mime_len2)
137                return -1;
138        if (rate1 != rate2)
139                return -1;
140        if (channels1 > 0 && channels2 > 0 && channels1 != channels2)
141                return -1;
142        return osip_strncasecmp(cur_payload->a_rtpmap, payload->a_rtpmap, mime_len1);
143}
144
145/* return the value of attr "field" for payload pt at line pos (field=rtpmap,fmtp...)*/
146char *sdp_message_a_attr_value_get_with_pt(sdp_message_t *sdp,int pos,int pt,const char *field)
147{
148        int i,tmppt=0,scanned=0;
149        char *tmp;
150        sdp_attribute_t *attr;
151        for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){
152                if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){
153                        int nb = sscanf(attr->a_att_value,"%i %n",&tmppt,&scanned);
154                        /* the return value may depend on how %n is interpreted by the libc: see manpage*/
155                        if (nb == 1 || nb==2 ){
156                                if (pt==tmppt){
157                                        tmp=attr->a_att_value+scanned;
158                                        if (strlen(tmp)>0)
159                                                return tmp;
160                                }
161                        }else eXosip_trace(OSIP_WARNING,("sdp has a strange a= line (%s) nb=%i",attr->a_att_value,nb));
162                }
163        }
164        return NULL;
165}
166
167/* return the value of attr "field" */
168char *sdp_message_a_attr_value_get(sdp_message_t *sdp,int pos,const char *field)
169{
170        int i;
171        sdp_attribute_t *attr;
172        for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){
173                if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){
174                        return attr->a_att_value;
175                }
176        }
177        return NULL;
178}
179
180int sdp_message_m_attr_has_type(sdp_message_t *sdp, const char *type)
181{
182        int i;
183        for (i = 0; !sdp_message_endof_media (sdp, i); i++)
184        {
185                if (strcmp(sdp_message_m_media_get(sdp, i), type) == 0)
186                        return 1;
187        }
188        return 0;
189}
190
191static int _sdp_message_get_a_ptime(sdp_message_t *sdp, int mline){
192        int i,ret;
193        sdp_attribute_t *attr;
194        for (i=0;(attr=sdp_message_attribute_get(sdp,mline,i))!=NULL;i++){
195                if (keywordcmp("ptime",attr->a_att_field)==0){
196                        int nb = sscanf(attr->a_att_value,"%i",&ret);
197                        /* the return value may depend on how %n is interpreted by the libc: see manpage*/
198                        if (nb == 1){
199                                return ret;
200                        }else eXosip_trace(OSIP_WARNING,("sdp has a strange a=ptime line (%s) ",attr->a_att_value));
201                }
202        }
203        return 0;
204}
205
206int
207sdp_payload_init (sdp_payload_t * payload)
208{
209        memset (payload, 0, sizeof (sdp_payload_t));
210        return 0;
211}
212
213sdp_context_t *sdp_handler_create_context(sdp_handler_t *handler, const char *localip, const char *username, const char *relay){
214        sdp_context_t *ctx=osip_malloc(sizeof(sdp_context_t));
215        memset(ctx,0,sizeof(sdp_context_t));
216        if (localip!=NULL) ctx->localip=osip_strdup(localip);
217        ctx->username=osip_strdup(username);
218        ctx->handler=handler;
219        if (relay){
220                ctx->relay=osip_strdup(relay);
221                ctx->relay_session_id=make_relay_session_id(username,relay);
222        }
223        return ctx;
224}
225
226void sdp_context_set_user_pointer(sdp_context_t * ctx, void* up){
227        ctx->reference=up;
228}
229
230void *sdp_context_get_user_pointer(sdp_context_t * ctx){
231        return ctx->reference;
232}
233
234int sdp_context_get_status(sdp_context_t* ctx){
235        return ctx->negoc_status;
236}
237
238/* generate a template sdp */
239sdp_message_t *
240sdp_context_generate_template(sdp_context_t * ctx)
241{
242        sdp_message_t *local;
243        int inet6;
244
245        sdp_message_init(&local);
246        if (strchr(ctx->localip,':')!=NULL){
247                inet6=1;
248        }else inet6=0;
249        if (!inet6){
250                sdp_message_v_version_set (local, osip_strdup ("0"));
251                sdp_message_o_origin_set (local, osip_strdup (ctx->username),
252                                osip_strdup ("123456"), osip_strdup ("654321"),
253                                osip_strdup ("IN"), osip_strdup ("IP4"),
254                                osip_strdup (ctx->localip));
255                sdp_message_s_name_set (local, osip_strdup ("A conversation"));
256                sdp_message_c_connection_add (local, -1,
257                                osip_strdup ("IN"), osip_strdup ("IP4"),
258                                osip_strdup (ctx->localip), NULL, NULL);
259                sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0"));
260        }else{
261                sdp_message_v_version_set (local, osip_strdup ("0"));
262                sdp_message_o_origin_set (local, osip_strdup (ctx->username),
263                                osip_strdup ("123456"), osip_strdup ("654321"),
264                                osip_strdup ("IN"), osip_strdup ("IP6"),
265                                osip_strdup (ctx->localip));
266                sdp_message_s_name_set (local, osip_strdup ("A conversation"));
267                sdp_message_c_connection_add (local, -1,
268                                osip_strdup ("IN"), osip_strdup ("IP6"),
269                                osip_strdup (ctx->localip), NULL, NULL);
270                sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0"));
271        }
272        return local;
273}
274
275static void add_relay_info(sdp_message_t *sdp, int mline, const char *relay, const char *relay_session_id){
276
277        if (relay) sdp_message_a_attribute_add(sdp, mline,
278                        osip_strdup ("relay-addr"),osip_strdup(relay));
279        if (relay_session_id) sdp_message_a_attribute_add(sdp, mline,
280                        osip_strdup ("relay-session-id"), osip_strdup(relay_session_id));
281}
282
283/* to add payloads to the offer, must be called inside the write_offer callback */
284void
285sdp_context_add_payload (sdp_context_t * ctx, sdp_payload_t * payload, char *media, int ptime)
286{
287        sdp_message_t *offer = ctx->offer;
288        char *attr_field;
289        if (!ctx->incb)
290        {
291                eXosip_trace (OSIP_ERROR,
292                                ("You must not call sdp_context_add_*_payload outside the build_offer callback\n"));
293#if !defined(_WIN32_WCE)
294                abort();
295#else
296                exit(-1);
297#endif /*_WIN32_WCE*/
298
299        }
300        if (payload->proto == NULL)
301                payload->proto = "RTP/AVP";
302        /*printf("payload->line=%i payload->pt=%i\n",payload->line, payload->pt);*/
303        if (sdp_message_m_media_get (offer, payload->line) == NULL)
304        {
305                /*printf("Adding new mline %s \n",media);*/
306                /* need a new line */
307                sdp_message_m_media_add (offer, osip_strdup (media),
308                                int_2char (payload->localport), NULL,
309                                osip_strdup (payload->proto));
310                if (ptime >= 20)
311                {
312                        sdp_message_a_attribute_add(offer, payload->line, osip_strdup("ptime"), int_2char (ptime));
313                }
314                if (ctx->relay)
315                        add_relay_info(offer,payload->line,ctx->relay,ctx->relay_session_id);
316                sdp_message_a_attribute_add(offer, payload->line, osip_strdup("rtcp"), int_2char (payload->localrtcpport));
317
318        }
319        sdp_message_m_payload_add (offer, payload->line, int_2char (payload->pt));
320        if (payload->a_rtpmap != NULL)
321        {
322                attr_field =
323                                sstrdup_sprintf ("%i %s", payload->pt,
324                                                payload->a_rtpmap);
325                sdp_message_a_attribute_add (offer, payload->line,
326                                osip_strdup ("rtpmap"), attr_field);
327        }
328        if (payload->a_fmtp != NULL)
329        {
330                attr_field =
331                                sstrdup_sprintf ("%i %s", payload->pt,
332                                                payload->a_fmtp);
333                sdp_message_a_attribute_add (offer, payload->line, osip_strdup ("fmtp"),
334                                attr_field);
335        }
336        if (payload->b_as_bandwidth != 0)
337        {
338                if (sdp_message_bandwidth_get(offer,payload->line,0)==NULL){
339                        attr_field =
340                                        sstrdup_sprintf ("%i", payload->b_as_bandwidth);
341                        sdp_message_b_bandwidth_add (offer, payload->line, osip_strdup ("AS"),
342                                        attr_field);
343                }
344        }
345}
346
347void
348sdp_context_add_audio_payload (sdp_context_t * ctx, sdp_payload_t * payload, int ptime)
349{
350        sdp_context_add_payload (ctx, payload, "audio", ptime);
351}
352
353void
354sdp_context_add_video_payload (sdp_context_t * ctx, sdp_payload_t * payload)
355{
356        sdp_context_add_payload (ctx, payload, "video", 0);
357}
358
359char *
360sdp_context_build_offer ( sdp_context_t * ctx)
361{
362        sdp_message_t *offer;
363        sdp_handler_t *sdph=ctx->handler;
364        char *tmp;
365
366
367        offer = sdp_context_generate_template (ctx);
368        /* add audio codecs */
369        ctx->offer = offer;
370        ctx->incb = 1;
371        if (sdph->set_audio_codecs != NULL)
372                sdph->set_audio_codecs (ctx);
373        if (sdph->set_video_codecs != NULL)
374                sdph->set_video_codecs (ctx);
375        ctx->incb = 0;
376        sdp_message_to_str(offer,&tmp);
377        ctx->offerstr=tmp;
378        return tmp;
379}
380
381
382/* refuse the line */
383static void refuse_mline(sdp_message_t *answer, char *mtype, char *proto, int mline)
384{
385        sdp_message_m_media_add (answer,
386                        osip_strdup (mtype),
387                        int_2char (0), NULL,
388                        osip_strdup (proto));
389        /* add a payload just to comply with sdp RFC.*/
390        sdp_message_m_payload_add(answer,mline,int_2char(0));
391}
392
393static char *
394parse_relay_addr(char *addr, int *port)
395{
396        char *semicolon=NULL;
397        char *p;
398
399        *port=56789;
400        semicolon=strchr(addr,':');
401        for (p=addr+strlen(addr)-1;p>addr;p--){
402                if (*p==':') {
403                        semicolon=p;
404                        break;
405                }
406        }
407        if (semicolon){
408                *port=atoi(semicolon+1);
409                *semicolon='\0';
410        }
411        return addr;
412}
413
414static int
415process_mline_from_offer(sdp_context_t *ctx, sdp_message_t *answer, 
416                sdp_handler_read_codec_func_t accept_codec,
417                sdp_message_t *remote,
418                int mline, sdp_payload_t *init_payload, const char *mtype, int ptime)
419{
420        int ncodec;
421        int j;
422        sdp_payload_t payload;
423        int err;
424        int m_lines_accepted = 0;
425        const char *pt;
426        char *rtcpport=NULL;
427
428        if (accept_codec != 0)
429        {
430                rtcpport = sdp_message_a_attr_value_get(remote, mline, "rtcp");
431                if (rtcpport == NULL)
432                        init_payload->remotertcpport = init_payload->remoteport + 1;
433                else
434                        init_payload->remotertcpport = osip_atoi(rtcpport);
435
436                ncodec = 0;
437                /* for each payload type */
438                for (j = 0; ((pt = sdp_message_m_payload_get (remote, mline, j)) != NULL); j++)
439                {
440                        memcpy(&payload, init_payload, sizeof(payload));
441                        payload.pt = osip_atoi (pt);
442
443                        payload.a_rtpmap = sdp_message_a_attr_value_get_with_pt(remote, mline, payload.pt, "rtpmap");
444                        payload.a_fmtp = sdp_message_a_attr_value_get_with_pt(remote, mline, payload.pt,"fmtp");
445
446                        /* ask the application if this codec is supported */
447                        err = accept_codec(ctx, &payload);
448                        if (err == 0)
449                        {
450                                ncodec++;
451                                /* codec accepted */
452                                if (ncodec == 1)
453                                {
454                                        /* first codec accepted, setup the line  */
455                                        sdp_message_m_media_add(answer, osip_strdup(mtype),
456                                                        int_2char(payload.localport), NULL, osip_strdup(payload.proto));
457                                        /* and accept the remote relay addr if we planned to use our own */
458                                        if (ctx->relay!=NULL && payload.relay_host){
459                                                add_relay_info(answer, mline, payload.relay_host, payload.relay_session_id);
460                                        }
461                                        sdp_message_a_attribute_add(answer, payload.line, osip_strdup("rtcp"), int_2char (payload.localrtcpport));
462                                        if (ptime > 20)
463                                                sdp_message_a_attribute_add(answer, payload.line, osip_strdup("ptime"), int_2char (ptime));
464                                }
465                                /* add the payload, rtpmap, fmtp */
466                                sdp_message_m_payload_add (answer, mline, int_2char(payload.pt));
467                                if (payload.a_rtpmap != NULL)
468                                {
469                                        sdp_message_a_attribute_add(answer, mline, osip_strdup("rtpmap"),
470                                                        sstrdup_sprintf("%i %s",payload.pt,payload.a_rtpmap));
471                                }
472                                if (payload.a_fmtp != NULL)
473                                {
474                                        sdp_message_a_attribute_add(answer, mline, osip_strdup("fmtp"),
475                                                        sstrdup_sprintf("%i %s",payload.pt,payload.a_fmtp));
476                                }
477                                if (payload.b_as_bandwidth != 0)
478                                {
479                                        if (sdp_message_bandwidth_get(answer,mline,0)==NULL)
480                                                sdp_message_b_bandwidth_add(answer, mline,osip_strdup("AS"),
481                                                                sstrdup_sprintf("%i",payload.b_as_bandwidth));
482                                }
483                        }
484                }
485                if (ncodec)
486                        m_lines_accepted++;
487        }
488
489        if (!m_lines_accepted)
490        {
491                /* refuse this line (leave port to 0) */
492                // refuse_mline(answer, mtype, payload.proto, mline);
493        }
494
495        return m_lines_accepted;
496}
497
498
499char *
500sdp_context_build_answer (sdp_context_t *ctx, sdp_message_t *remote, int ptime)
501{
502        sdp_message_t *answer=NULL;
503        char *mtype=NULL, *tmp=NULL;
504        char *proto=NULL, *port=NULL;
505        int i, j, m_lines_accepted = 0;
506        sdp_payload_t init_payload;
507        sdp_handler_t *sdph=ctx->handler;
508        sdp_bandwidth_t *sbw=NULL;
509        char *relay;
510
511        tmp = sdp_message_c_addr_get (remote, 0, 0);
512        if (tmp == NULL)
513                tmp = sdp_message_c_addr_get (remote, -1, 0);
514        if (ctx->localip==NULL) {
515                /* NULL means guess, otherwise we use the address given as localip */
516                ctx->localip=osip_malloc(128);
517                eXosip_guess_localip(strchr(tmp,':') ?  AF_INET6 : AF_INET,ctx->localip,128);
518        }
519        else eXosip_trace(OSIP_INFO1,("Using firewall address in sdp."));
520
521        answer = sdp_context_generate_template (ctx);
522
523        /* for each m= line */
524        for (i = 0; !sdp_message_endof_media (remote, i); i++){
525                sdp_payload_init(&init_payload);
526                mtype = sdp_message_m_media_get (remote, i);
527                proto = sdp_message_m_proto_get (remote, i);
528                port = sdp_message_m_port_get (remote, i);
529                init_payload.remoteport = osip_atoi (port);
530                init_payload.proto = proto;
531                init_payload.line = i;
532                init_payload.c_addr = sdp_message_c_addr_get (remote, i, 0);
533                if (init_payload.c_addr == NULL)
534                        init_payload.c_addr = sdp_message_c_addr_get (remote, -1, 0);
535                /*parse relay address if given*/
536                relay=sdp_message_a_attr_value_get(remote,i,"relay-addr");
537                if (relay){
538                        init_payload.relay_host=parse_relay_addr(relay,&init_payload.relay_port);
539                }
540                init_payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id");
541                /* get application specific bandwidth, if any */
542                for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;j++){
543                        if (strcasecmp(sbw->b_bwtype,"AS")==0) init_payload.b_as_bandwidth=atoi(sbw->b_bandwidth);
544                }
545                init_payload.a_ptime=_sdp_message_get_a_ptime(remote,i);
546                if (keywordcmp ("audio", mtype) == 0)
547                {
548                        m_lines_accepted +=
549                                        process_mline_from_offer(ctx, answer, sdph->accept_audio_codecs,
550                                                        remote, i, &init_payload, mtype, ptime);
551                }
552                else if (keywordcmp ("video", mtype) == 0)
553                {
554                        m_lines_accepted +=
555                                        process_mline_from_offer(ctx, answer, sdph->accept_video_codecs,
556                                                        remote, i, &init_payload, mtype, 0);
557                }
558        }
559
560        if (ctx->answer!=NULL)
561                sdp_message_free(ctx->answer);
562        ctx->answer = answer;
563        if (m_lines_accepted > 0){
564                ctx->negoc_status = 200;
565                sdp_message_to_str(answer,&tmp);
566                if (ctx->answerstr!=NULL)
567                        osip_free(ctx->answerstr);
568                ctx->answerstr=tmp;
569                return tmp;
570        }else{
571                ctx->negoc_status = 415;
572                return NULL;
573        }
574}
575
576void
577sdp_context_process_answer (sdp_context_t *ctx, sdp_message_t *remote)
578{
579        char *mtype;
580        char *proto, *port, *pt;
581        int i, j,err;
582        char *relay,*rtcpport;
583        sdp_payload_t payload,arg_payload;
584        sdp_handler_t *sdph=ctx->handler;
585        sdp_bandwidth_t *sbw=NULL;
586
587        /* for each m= line */
588        for (i = 0; !sdp_message_endof_media (remote, i); i++)
589        {
590                sdp_payload_init(&payload);
591                mtype = sdp_message_m_media_get (remote, i);
592                proto = sdp_message_m_proto_get (remote, i);
593                port = sdp_message_m_port_get (remote, i);
594                payload.remoteport = osip_atoi (port);
595                payload.localport = osip_atoi (sdp_message_m_port_get (ctx->offer, i));
596                payload.proto = proto;
597                payload.line = i;
598                payload.c_addr = sdp_message_c_addr_get (remote, i, 0);
599                if (payload.c_addr == NULL)
600                        payload.c_addr = sdp_message_c_addr_get (remote, -1, 0);
601
602                rtcpport = sdp_message_a_attr_value_get(remote, i, "rtcp");
603                if (rtcpport == NULL)
604                        payload.remotertcpport = payload.remoteport + 1;
605                else
606                        payload.remotertcpport = osip_atoi(rtcpport);
607
608                /*parse relay address if given*/
609                relay=sdp_message_a_attr_value_get(remote,i,"relay-addr");
610                if (relay){
611                        payload.relay_host=parse_relay_addr(relay,&payload.relay_port);
612                }
613                payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id");
614                for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;++j){
615                        if (strcasecmp(sbw->b_bwtype,"AS")==0) payload.b_as_bandwidth=atoi(sbw->b_bandwidth);
616                }
617                payload.a_ptime=_sdp_message_get_a_ptime(remote,i);
618                if (keywordcmp ("audio", mtype) == 0)
619                {
620                        if (sdph->get_audio_codecs != NULL)
621                        {
622                                /* for each payload type */
623                                for (j = 0;
624                                                ((pt =
625                                                                sdp_message_m_payload_get (remote, i,
626                                                                                j)) != NULL); j++)
627                                {
628                                        payload.pt = osip_atoi (pt);
629                                        /* get the rtpmap associated to this codec, if any */
630                                        payload.a_rtpmap =
631                                                        sdp_message_a_attr_value_get_with_pt
632                                                        (remote, i, payload.pt,
633                                                                        "rtpmap");
634                                        /* get the fmtp, if any */
635                                        payload.a_fmtp =
636                                                        sdp_message_a_attr_value_get_with_pt
637                                                        (remote, i, payload.pt,
638                                                                        "fmtp");
639                                        /* ask the application if this codec is supported */
640                                        memcpy(&arg_payload,&payload,sizeof(payload));
641                                        err = sdph->get_audio_codecs (ctx,
642                                                        &arg_payload);
643                                }
644                        }
645                }
646                else if (keywordcmp ("video", mtype) == 0)
647                {
648                        if (sdph->get_video_codecs != NULL)
649                        {
650                                /* for each payload type */
651                                for (j = 0;
652                                                ((pt =
653                                                                sdp_message_m_payload_get (remote, i,
654                                                                                j)) != NULL); j++)
655                                {
656                                        payload.pt = osip_atoi (pt);
657                                        /* get the rtpmap associated to this codec, if any */
658                                        payload.a_rtpmap =
659                                                        sdp_message_a_attr_value_get_with_pt
660                                                        (remote, i, payload.pt,
661                                                                        "rtpmap");
662                                        /* get the fmtp, if any */
663                                        payload.a_fmtp =
664                                                        sdp_message_a_attr_value_get_with_pt
665                                                        (remote, i, payload.pt,
666                                                                        "fmtp");
667                                        /* ask the application if this codec is supported */
668                                        memcpy(&arg_payload,&payload,sizeof(payload));
669                                        err = sdph->get_video_codecs (ctx,
670                                                        &arg_payload);
671                                }
672                        }
673                }
674        }
675}
676
677void sdp_context_free(sdp_context_t *ctx){
678        osip_free(ctx->localip);
679        osip_free(ctx->username);
680        if (ctx->offer!=NULL) sdp_message_free(ctx->offer);
681        if (ctx->answer!=NULL) sdp_message_free(ctx->answer);
682        if (ctx->offerstr!=NULL) osip_free(ctx->offerstr);
683        if (ctx->answerstr!=NULL) osip_free(ctx->answerstr);
684        if (ctx->relay!=NULL) osip_free(ctx->relay);
685        if (ctx->relay_session_id!=NULL) osip_free(ctx->relay_session_id);
686        osip_free(ctx);
687}
Note: See TracBrowser for help on using the repository browser.