diff --git coreapi/linphonecall.c coreapi/linphonecall.c index a8838af..8e92103 100644 --- coreapi/linphonecall.c +++ coreapi/linphonecall.c @@ -59,7 +59,7 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw return l; } -SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){ +static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, LinphoneCall *call, unsigned int session_id, unsigned int session_ver){ MSList *l; PayloadType *pt; const char *me=linphone_core_get_identity(lc); @@ -67,6 +67,8 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa const char *username=linphone_address_get_username (addr); SalMediaDescription *md=sal_media_description_new(); + md->session_id=session_id; + md->session_ver=session_ver; md->nstreams=1; strncpy(md->addr,call->localip,sizeof(md->addr)); strncpy(md->username,username,sizeof(md->username)); @@ -96,6 +98,22 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa return md; } +void update_local_media_description(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription **md){ + if (*md == NULL) { + *md = _create_local_media_description(lc,call,0,0); + } else { + unsigned int id = (*md)->session_id; + unsigned int ver = (*md)->session_ver+1; + sal_media_description_unref(*md); + *md = _create_local_media_description(lc,call,id,ver); + } +} + +SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){ + unsigned int id=rand(); + return _create_local_media_description(lc,call,id,id); +} + static int find_port_offset(LinphoneCore *lc){ int offset; MSList *elem; diff --git coreapi/linphonecore.c coreapi/linphonecore.c index 4490bf4..c0434af 100644 --- coreapi/linphonecore.c +++ coreapi/linphonecore.c @@ -2196,10 +2196,8 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ int err=0; if (params!=NULL){ - if (call->localdesc) - sal_media_description_unref(call->localdesc); call->params=*params; - call->localdesc=create_local_media_description (lc,call); + update_local_media_description(lc,call,&call->localdesc); call->camera_active=params->has_video; if (lc->vtable.display_status) lc->vtable.display_status(lc,_("Modifying call parameters...")); diff --git coreapi/offeranswer.c coreapi/offeranswer.c index 91de86e..f427ea7 100644 --- coreapi/offeranswer.c +++ coreapi/offeranswer.c @@ -200,22 +200,33 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities, const SalMediaDescription *remote_offer, SalMediaDescription *result, bool_t one_matching_codec){ - int i,j; + int i; const SalStreamDescription *ls,*rs; - for(i=0,j=0;instreams;++i){ + for(i=0;instreams;++i){ rs=&remote_offer->streams[i]; ms_message("Processing for stream %i",i); ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type); if (ls){ - initiate_incoming(ls,rs,&result->streams[j],one_matching_codec); - ++j; + initiate_incoming(ls,rs,&result->streams[i],one_matching_codec); + } else { + /* create an inactive stream for the answer, as there where no matching stream a local capability */ + result->streams[i].dir=SalStreamInactive; + result->streams[i].port=0; + result->streams[i].type=rs->type; + if (rs->type==SalOther){ + if (!result->streams[i].typeother){ + result->streams[i].typeother=ms_new0(char,16); + } + strncpy(result->streams[i].typeother,rs->typeother,16); + } } } - result->nstreams=j; + result->nstreams=i; strcpy(result->username, local_capabilities->username); strcpy(result->addr,local_capabilities->addr); result->bandwidth=local_capabilities->bandwidth; + result->session_ver=local_capabilities->session_ver; + result->session_id=local_capabilities->session_id; return 0; } - diff --git coreapi/private.h coreapi/private.h index 87605b1..17754c2 100644 --- coreapi/private.h +++ coreapi/private.h @@ -445,6 +445,7 @@ int linphone_core_get_calls_nb(const LinphoneCore *lc); void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message); SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call); +void update_local_media_description(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription **md); void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md); diff --git coreapi/sal.c coreapi/sal.c index 6f80436..bc175d2 100644 --- coreapi/sal.c +++ coreapi/sal.c @@ -37,6 +37,9 @@ static void sal_media_description_destroy(SalMediaDescription *md){ ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy); ms_list_free(md->streams[i].payloads); md->streams[i].payloads=NULL; + if (md->streams[i].typeother){ + ms_free(md->streams[i].typeother); + } } ms_free(md); } diff --git coreapi/sal.h coreapi/sal.h index 2f39c69..81af401 100644 --- coreapi/sal.h +++ coreapi/sal.h @@ -103,6 +103,7 @@ typedef struct SalEndpointCandidate{ typedef struct SalStreamDescription{ SalMediaProto proto; SalStreamType type; + char *typeother; char addr[64]; int port; MSList *payloads; //session_id); + snprintf(sessver,16,"%i",desc->session_ver); sdp_message_init (&local); if (strchr(desc->addr,':')!=NULL){ inet6=1; }else inet6=0; sdp_message_v_version_set (local, osip_strdup ("0")); sdp_message_o_origin_set (local, osip_strdup (desc->username), - osip_strdup ("123456"), osip_strdup ("654321"), + osip_strdup (sessid), osip_strdup (sessver), osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"), osip_strdup (desc->addr)); sdp_message_s_name_set (local, osip_strdup ("A conversation")); @@ -181,11 +185,23 @@ static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt) static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){ - const char *mt=desc->type==SalAudio ? "audio" : "video"; + char *mt; const MSList *elem; const char *addr; const char *dir="sendrecv"; int port; + + switch (desc->type) { + case SalAudio: + mt="audio"; + break; + case SalVideo: + mt="video"; + break; + case SalOther: + mt=desc->typeother; + break; + } if (desc->candidates[0].addr[0]!='\0'){ addr=desc->candidates[0].addr; port=desc->candidates[0].port; @@ -310,7 +326,14 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){ stream->type=SalAudio; }else if (strcasecmp("video", mtype) == 0){ stream->type=SalVideo; - }else stream->type=SalOther; + }else { + stream->type=SalOther; + if (stream->typeother){ + ms_free(stream->typeother); + } + stream->typeother=ms_new0(char,16); + strncpy(stream->typeother,mtype,16); + } for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){ if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth); }