diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index a8838af10ea27628951a5bdf14fcc2a94b13dd5e..8e92103d95c662104ed346a95added62d644da70 100644 --- a/coreapi/linphonecall.c +++ b/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 a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 7afdf85fa7f27af1247e3518d481544fe1bac10a..ad693a824f25f9529cb75b6f70542f5d163fdfd6 100644 --- a/coreapi/linphonecore.c +++ b/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 a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 3b8948674fe38b7976e96c4364078dc198b349ad..cbc88c2c14c5a79b35ac3b18442b0e7d366d1fbe 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -218,22 +218,30 @@ 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;i<remote_offer->nstreams;++i){ + for(i=0;i<remote_offer->nstreams;++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){ + strncpy(result->streams[i].typeother,rs->typeother,sizeof(rs->typeother)-1); + } } } - 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 a/coreapi/private.h b/coreapi/private.h index 87605b15c0c2f596a045f1441d128cfb7f17b0e1..17754c289356577c0be1082e6e6d2ca3dc53650f 100644 --- a/coreapi/private.h +++ b/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 a/coreapi/sal.h b/coreapi/sal.h index 24cc8582ab9c06bf866aacf3dab528512bfc4915..09ff05f8115b90d1351da6c61608a39743d4220f 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -103,6 +103,7 @@ typedef struct SalEndpointCandidate{ typedef struct SalStreamDescription{ SalMediaProto proto; SalStreamType type; + char typeother[32]; char addr[64]; int port; MSList *payloads; //<list of PayloadType @@ -120,6 +121,8 @@ typedef struct SalMediaDescription{ char username[64]; int nstreams; int bandwidth; + unsigned int session_ver; + unsigned int session_id; SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS]; } SalMediaDescription; diff --git a/coreapi/sal_eXosip2_sdp.c b/coreapi/sal_eXosip2_sdp.c index a9f098ed24b99f9d3ad94aa5351d6dc727e99775..fd6d959d5f00a74626345f64302b0439f4d8869e 100644 --- a/coreapi/sal_eXosip2_sdp.c +++ b/coreapi/sal_eXosip2_sdp.c @@ -127,14 +127,18 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc) { sdp_message_t *local; int inet6; - + char sessid[16]; + char sessver[16]; + + snprintf(sessid,16,"%i",desc->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"; + const 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,13 @@ 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); + } + strncpy(stream->typeother,mtype,sizeof(stream->typeother)-1); + } 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); }