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);
}
}
-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;
*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;
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;
}
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)
}
set_network_reachable(lc,isReachable);
}
+
+ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc){
+ return sal_get_socket(lc->sal);
+}
/**
* Destroys a LinphoneCore
*
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);
char addr[64];
char username[64];
int nstreams;
+ int bandwidth;
SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
} SalMediaDescription;
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);
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){
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*/
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);
}
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;i<h->result->nstreams;++i){
if (h->result->streams[i].port>0){
strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
MSList *other_transactions; /*MSList of SalOp */
int running;
int session_expires;
+ ortp_socket_t sock;
void *up;
};
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;
}
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<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++)
{
void linphone_gtk_set_audio_video(){
linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE);
+ linphone_core_enable_video_preview(linphone_gtk_get_core(),
+ linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT));
}
void linphone_gtk_set_audio_only(){
static void linphone_gtk_show_main_window(){
GtkWidget *w=linphone_gtk_get_main_window();
LinphoneCore *lc=linphone_gtk_get_core();
- linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview",
- VIDEOSELFVIEW_DEFAULT));
+ if (linphone_core_video_enabled(lc)){
+ linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview",
+ VIDEOSELFVIEW_DEFAULT));
+ }
gtk_widget_show(w);
gtk_window_present(GTK_WINDOW(w));
}