From 8a5c00ac823547102bb44d489eb88be976bffa02 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 19 Apr 2010 22:18:04 +0200 Subject: [PATCH] implements global b=AS in sending and receiving side fix a few bugs with selfview in gui implements linphone_core_get_sip_socket() --- coreapi/linphonecore.c | 25 ++++++++++++--- coreapi/linphonecore.h | 2 ++ coreapi/sal.h | 2 ++ coreapi/sal_eXosip2.c | 67 ++++++++++++++++++++++++++++++++++++--- coreapi/sal_eXosip2.h | 1 + coreapi/sal_eXosip2_sdp.c | 6 ++++ gtk-glade/main.c | 8 +++-- 7 files changed, 100 insertions(+), 11 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index e6df7ee17..c9266b7de 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -84,6 +84,7 @@ static SalMediaDescription *create_local_media_description(LinphoneCore *lc, md->nstreams=1; strncpy(md->addr,localip,sizeof(md->addr)); strncpy(md->username,username,sizeof(md->username)); + md->bandwidth=linphone_core_get_download_bandwidth(lc); /*set audio capabilities */ strncpy(md->streams[0].addr,localip,sizeof(md->streams[0].addr)); md->streams[0].port=linphone_core_get_audio_port(lc); @@ -2147,11 +2148,12 @@ static void post_configure_audio_streams(LinphoneCore *lc){ } } -static RtpProfile *make_profile(LinphoneCore *lc, const SalStreamDescription *desc, int *used_pt){ +static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){ int bw; const MSList *elem; RtpProfile *prof=rtp_profile_new("Call profile"); bool_t first=TRUE; + int remote_bw=0; for(elem=desc->payloads;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; @@ -2163,9 +2165,18 @@ static RtpProfile *make_profile(LinphoneCore *lc, const SalStreamDescription *de *used_pt=payload_type_get_number(pt); first=FALSE; } + if (desc->bandwidth>0) remote_bw=desc->bandwidth; + else if (md->bandwidth>0) { + /*case where b=AS is given globally, not per stream*/ + remote_bw=md->bandwidth; + if (desc->type==SalVideo){ + remote_bw-=lc->audio_bw; + } + } + if (desc->type==SalAudio){ - bw=get_min_bandwidth(lc->up_audio_bw,desc->bandwidth); - }else bw=get_min_bandwidth(lc->up_video_bw,desc->bandwidth); + bw=get_min_bandwidth(lc->up_audio_bw,remote_bw); + }else bw=get_min_bandwidth(lc->up_video_bw,remote_bw); if (bw>0) pt->normal_bitrate=bw*1000; else if (desc->type==SalAudio){ pt->normal_bitrate=-1; @@ -2195,7 +2206,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){ const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc, SalProtoRtpAvp,SalAudio); if (stream){ - call->audio_profile=make_profile(lc,stream,&used_pt); + call->audio_profile=make_profile(lc,call->resultdesc,stream,&used_pt); if (!lc->use_files){ MSSndCard *playcard=lc->sound_conf.play_sndcard; MSSndCard *captcard=lc->sound_conf.capt_sndcard; @@ -2245,7 +2256,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){ } if (stream && (lc->video_conf.display || lc->video_conf.capture)) { const char *addr=stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr; - call->video_profile=make_profile(lc,stream,&used_pt); + call->video_profile=make_profile(lc,call->resultdesc,stream,&used_pt); video_stream_set_sent_video_size(lc->videostream,linphone_core_get_preferred_video_size(lc)); video_stream_enable_self_view(lc->videostream,lc->video_conf.selfview); if (lc->video_conf.display && lc->video_conf.capture) @@ -3559,6 +3570,10 @@ void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) { } set_network_reachable(lc,isReachable); } + +ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc){ + return sal_get_socket(lc->sal); +} /** * Destroys a LinphoneCore * diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 46d9e2944..8ef28f9ed 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -607,6 +607,8 @@ int linphone_core_get_sip_port(LinphoneCore *lc); void linphone_core_set_sip_port(LinphoneCore *lc,int port); +ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc); + void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds); int linphone_core_get_inc_timeout(LinphoneCore *lc); diff --git a/coreapi/sal.h b/coreapi/sal.h index 23780f6b3..882761ffb 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -107,6 +107,7 @@ typedef struct SalMediaDescription{ char addr[64]; char username[64]; int nstreams; + int bandwidth; SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS]; } SalMediaDescription; @@ -223,6 +224,7 @@ typedef struct SalAuthInfo{ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs); int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure); +ortp_socket_t sal_get_socket(Sal *ctx); void sal_set_user_agent(Sal *ctx, const char *user_agent); void sal_use_session_timers(Sal *ctx, int expires); int sal_iterate(Sal *sal); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 4e0f6a05a..c85079fc1 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -227,12 +227,15 @@ static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *c Sal * sal_init(){ static bool_t firsttime=TRUE; + Sal *sal; if (firsttime){ osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func); firsttime=FALSE; } eXosip_init(); - return ms_new0(Sal,1); + sal=ms_new0(Sal,1); + sal->sock=-1; + return sal; } void sal_uninit(Sal* sal){ @@ -290,13 +293,58 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){ ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub; } + +static ortp_socket_t create_socket(int pf, int proto, const char *addr, int local_port){ + struct addrinfo hints; + struct addrinfo *res=NULL; + ortp_socket_t sock; + int optval; + char tmp[20]; + int err; + + sock=socket(pf,(proto==IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM,0); + if (sock<0) { + ms_error("Fail to create socket"); + return -1; + } + snprintf(tmp,sizeof(tmp)-1,"%i",local_port); + memset (&hints,0,sizeof(hints)); + hints.ai_family=(pf==PF_INET) ? AF_INET : AF_INET6; + hints.ai_socktype=(proto==IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; + + if ((err=getaddrinfo(addr, + tmp, + &hints,&res))<0) { + ms_error("create_socket: getaddrinfo() failed: %s",gai_strerror(err)); + close_socket(sock); + return -1; + } + if (bind(sock,(struct sockaddr*)res->ai_addr,res->ai_addrlen)<0){ + ms_error("Bind socket to localhost:%i failed: %s",local_port,getSocketError()); + freeaddrinfo(res); + close_socket(sock); + return -1; + } + freeaddrinfo(res); + optval=1; + if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, + (SOCKET_OPTION_VALUE)&optval, sizeof (optval))<0){ + ms_warning("Fail to set SO_REUSEADDR"); + } + /*set_non_blocking_socket(sock);*/ + return sock; +} + + int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){ int err; bool_t ipv6; int proto=IPPROTO_UDP; - if (ctx->running) eXosip_quit(); - eXosip_init(); + if (ctx->running){ + eXosip_quit(); + eXosip_init(); + } err=0; eXosip_set_option(13,&err); /*13=EXOSIP_OPT_SRV_WITH_NAPTR, as it is an enum value, we can't use it unless we are sure of the version of eXosip, which is not the case*/ @@ -308,11 +356,21 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i ms_fatal("SIP over TCP or TLS or DTLS is not supported yet."); return -1; } - + ctx->sock=create_socket(ipv6 ? PF_INET6 : PF_INET, proto, addr, port); + if (ctx->sock==-1) return -1; + ms_message("Exosip is given socket %i",ctx->sock); + eXosip_set_socket(proto,ctx->sock,port); + /* err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, 0); + */ + ctx->running=TRUE; return err; } +ortp_socket_t sal_get_socket(Sal *ctx){ + return ctx->sock; +} + void sal_set_user_agent(Sal *ctx, const char *user_agent){ eXosip_set_user_agent(user_agent); } @@ -381,6 +439,7 @@ static void sdp_process(SalOp *h){ offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result); h->sdp_answer=media_description_to_sdp(h->result); strcpy(h->result->addr,h->base.remote_media->addr); + h->result->bandwidth=h->base.remote_media->bandwidth; for(i=0;iresult->nstreams;++i){ if (h->result->streams[i].port>0){ strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr); diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 1dd11e6ae..cc9b5b14b 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -37,6 +37,7 @@ struct Sal{ MSList *other_transactions; /*MSList of SalOp */ int running; int session_expires; + ortp_socket_t sock; void *up; }; diff --git a/coreapi/sal_eXosip2_sdp.c b/coreapi/sal_eXosip2_sdp.c index 580428765..2165708b1 100644 --- a/coreapi/sal_eXosip2_sdp.c +++ b/coreapi/sal_eXosip2_sdp.c @@ -125,6 +125,8 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc) osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"), osip_strdup (desc->addr), NULL, NULL); sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0")); + if (desc->bandwidth>0) sdp_message_b_bandwidth_add (local, -1, osip_strdup ("AS"), + int_2char(desc->bandwidth)); return local; } @@ -234,6 +236,10 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){ addr=sdp_message_c_addr_get (msg, -1, 0); if (addr) strncpy(desc->addr,addr,sizeof(desc->addr)); + for(j=0;(sbw=sdp_message_bandwidth_get(msg,-1,j))!=NULL;++j){ + if (strcasecmp(sbw->b_bwtype,"AS")==0) desc->bandwidth=atoi(sbw->b_bandwidth); + } + /* for each m= line */ for (i=0; !sdp_message_endof_media (msg, i) && i