From ba4ff464b3e382cfc0ac2f806f383c11752a8d8c Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 31 Aug 2012 18:17:27 +0200 Subject: [PATCH 01/51] add access to country code from iso name --- coreapi/linphonecore_utils.h | 10 +++++++++- coreapi/proxy.c | 24 ++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecore_utils.h b/coreapi/linphonecore_utils.h index bd41ec2b9..964385683 100644 --- a/coreapi/linphonecore_utils.h +++ b/coreapi/linphonecore_utils.h @@ -86,7 +86,15 @@ typedef bool_t (*LinphoneCoreIterateHook)(void *data); void linphone_core_add_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data); void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data); - +/** + * @ingroup misc + *Function to get call country code from ISO 3166-1 alpha-2 code, ex: FR returns 33 + *@param iso country code alpha2 + *@return call country code or -1 if not found + */ +int linphone_dial_plan_lookup_ccc_from_iso(const char* iso); + + #ifdef __cplusplus } #endif diff --git a/coreapi/proxy.c b/coreapi/proxy.c index bb01f14ee..47fe08bdd 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -375,21 +375,33 @@ bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg */ typedef struct dial_plan{ const char *country; + const char* iso_country_code; /* ISO 3166-1 alpha-2 code, ex: FR for France*/ char ccc[8]; /*country calling code*/ int nnl; /*maximum national number length*/ const char * icp; /*international call prefix, ex: 00 in europe*/ + }dial_plan_t; /* TODO: fill with information for all countries over the world*/ static dial_plan_t const dial_plans[]={ - {"France" , "33" , 9 , "00" }, - {"United States", "1" , 10 , "011" }, - {"Turkey" , "90" , 10 , "00" }, - {"Switzerland" , "41" , 9 , "00" }, - {NULL , "" , 0 , NULL } + {"France" ,"FR" , "33" , 9 , "00" }, + {"United States" ,"US" , "1" , 10 , "011" }, + {"Turkey" ,"TR" , "90" , 10 , "00" }, + {"Switzerland" ,"XK" , "41" , 9 , "00" }, + {NULL ,NULL,"" , 0 , NULL } }; -static dial_plan_t most_common_dialplan={ "generic" , "", 10, "00"}; +static dial_plan_t most_common_dialplan={ "generic" ,"", "", 10, "00"}; + +int linphone_dial_plan_lookup_ccc_from_iso(const char* iso) { + dial_plan_t* dial_plan; + for (dial_plan=(dial_plan_t*)dial_plans; dial_plan->country!=NULL; dial_plan++) { + if (strcmp(iso, dial_plan->iso_country_code)==0) { + return atoi(dial_plan->ccc); + } + } + return -1; +} static void lookup_dial_plan(const char *ccc, dial_plan_t *plan){ int i; From cfb3b3dfd5eed379ce773f4d3c8f415f452f23f1 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 31 Aug 2012 22:07:00 +0200 Subject: [PATCH 02/51] edge optimization in progress --- coreapi/linphonecall.c | 35 ++++++++++++++++++++++++++++++----- coreapi/misc.c | 39 ++++++++++++++++++++++++++++++++------- coreapi/private.h | 15 +++++++++------ 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 929814b52..9136eb1e4 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -333,9 +333,17 @@ static void discover_mtu(LinphoneCore *lc, const char *remote){ } } +static void update_sal_media_description_from_params(SalMediaDescription *md, const LinphoneCallParams *params){ + if (params->down_bw) + md->bandwidth=params->down_bw; + if (params->down_ptime) + md->streams[0].ptime=params->down_ptime; +} + LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params) { LinphoneCall *call=ms_new0(LinphoneCall,1); + int ping_time=-1; call->dir=LinphoneCallOutgoing; call->op=sal_op_new(lc->sal); sal_op_set_user_pointer(call->op,call); @@ -350,7 +358,11 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->localdesc=create_local_media_description (lc,call); call->camera_active=params->has_video; if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseStun) { - linphone_core_run_stun_tests(call->core,call); + ping_time=linphone_core_run_stun_tests(call->core,call); + } + if (ping_time>=0) { + linphone_core_adapt_to_network(lc,ping_time,&call->params); + update_sal_media_description_from_params(call->localdesc,&call->params); } discover_mtu(lc,linphone_address_get_domain (to)); if (params->referer){ @@ -363,6 +375,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){ LinphoneCall *call=ms_new0(LinphoneCall,1); char *from_str; + int ping_time=-1; call->dir=LinphoneCallIncoming; sal_op_set_user_pointer(op,call); @@ -385,7 +398,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_call_init_common(call, from, to); linphone_core_init_default_params(lc, &call->params); call->params.has_video &= !!lc->video_policy.automatically_accept; - call->localdesc=create_local_media_description (lc,call); + call->localdesc=create_local_media_description(lc,call); call->camera_active=call->params.has_video; switch (linphone_core_get_firewall_policy(call->core)) { case LinphonePolicyUseIce: @@ -403,11 +416,15 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro } break; case LinphonePolicyUseStun: - linphone_core_run_stun_tests(call->core,call); + ping_time=linphone_core_run_stun_tests(call->core,call); /* No break to also destroy ice session in this case. */ default: break; } + if (ping_time>=0) { + linphone_core_adapt_to_network(lc,ping_time,&call->params); + update_sal_media_description_from_params(call->localdesc,&call->params); + }; discover_mtu(lc,linphone_address_get_domain(from)); return call; } @@ -1137,6 +1154,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m int remote_bw=0; LinphoneCore *lc=call->core; int up_ptime=0; + const LinphoneCallParams *params=&call->params; *used_pt=-1; for(elem=desc->payloads;elem!=NULL;elem=elem->next){ @@ -1146,7 +1164,9 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m if ((pt->flags & PAYLOAD_TYPE_FLAG_CAN_SEND) && first) { if (desc->type==SalAudio){ linphone_core_update_allocated_audio_bandwidth_in_call(call,pt); - up_ptime=linphone_core_get_upload_ptime(lc); + if (params->up_ptime) + up_ptime=params->up_ptime; + else up_ptime=linphone_core_get_upload_ptime(lc); } *used_pt=payload_type_get_number(pt); first=FALSE; @@ -1161,7 +1181,12 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m } if (desc->type==SalAudio){ - bw=get_min_bandwidth(call->audio_bw,remote_bw); + int audio_bw=call->audio_bw; + if (params->up_bw){ + if (params->up_bw< audio_bw) + audio_bw=params->up_bw; + } + bw=get_min_bandwidth(audio_bw,remote_bw); }else bw=get_min_bandwidth(get_video_bandwidth(linphone_core_get_upload_bandwidth (lc),call->audio_bw),remote_bw); if (bw>0) pt->normal_bitrate=bw*1000; else if (desc->type==SalAudio){ diff --git a/coreapi/misc.c b/coreapi/misc.c index a22bbc1d9..a696cd7f4 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -466,12 +466,13 @@ static int recvStunResponse(ortp_socket_t sock, char *ipaddr, int *port, int *id return len; } -void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ +/* this functions runs a simple stun test and return the number of milliseconds to complete the tests, or -1 if the test were failed.*/ +int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ const char *server=linphone_core_get_stun_server(lc); - + if (lc->sip_conf.ipv6_enabled){ ms_warning("stun support is not implemented for ipv6"); - return; + return -1; } if (server!=NULL){ struct sockaddr_storage ss; @@ -483,29 +484,31 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ bool_t cone_audio=FALSE,cone_video=FALSE; struct timeval init,cur; SalEndpointCandidate *ac,*vc; + double elapsed; + int ret=0; ac=&call->localdesc->streams[0].candidates[0]; vc=&call->localdesc->streams[1].candidates[0]; if (parse_hostname_to_addr(server,&ss,&ss_len)<0){ ms_error("Fail to parser stun server address: %s",server); - return; + return -1; } if (lc->vtable.display_status!=NULL) lc->vtable.display_status(lc,_("Stun lookup in progress...")); /*create the two audio and video RTP sockets, and send STUN message to our stun server */ sock1=create_socket(call->audio_port); - if (sock1==-1) return; + if (sock1==-1) return -1; if (video_enabled){ sock2=create_socket(call->video_port); - if (sock2==-1) return ; + if (sock2==-1) return -1; } got_audio=FALSE; got_video=FALSE; gettimeofday(&init,NULL); do{ - double elapsed; + int id; if (loops%20==0){ ms_message("Sending stun requests..."); @@ -544,10 +547,12 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ elapsed=((cur.tv_sec-init.tv_sec)*1000.0) + ((cur.tv_usec-init.tv_usec)/1000.0); if (elapsed>2000) { ms_message("Stun responses timeout, going ahead."); + ret=-1; break; } loops++; }while(!(got_audio && (got_video||sock2==-1) ) ); + if (ret==0) ret=(int)elapsed; if (!got_audio){ ms_error("No stun server response for audio port."); }else{ @@ -570,9 +575,29 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ } close_socket(sock1); if (sock2!=-1) close_socket(sock2); + return ret; + } + return -1; + +} + +void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params){ + if (lp_config_get_int(lc->config,"net","activate_edge_workarounds",0)==1){ + int threshold=lp_config_get_int(lc->config,"net","edge_ping_time",500); + + if (ping_time_ms>threshold){ + int edge_ptime=lp_config_get_int(lc->config,"net","edge_ptime",100); + int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",30); + /* we are in a 2G network*/ + params->up_bw=params->down_bw=edge_bw; + params->up_ptime=params->down_ptime=edge_ptime; + + }/*else use default settings */ } } + + int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) { char local_addr[64]; diff --git a/coreapi/private.h b/coreapi/private.h index 6c9ba8d29..b1b16ed03 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -69,8 +69,12 @@ struct _LinphoneCallParams{ LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */ int audio_bw; /* bandwidth limit for audio stream */ LinphoneMediaEncryption media_encryption; - PayloadType *audio_codec; - PayloadType *video_codec; + PayloadType *audio_codec; /*audio codec currently in use */ + PayloadType *video_codec; /*video codec currently in use */ + int down_bw; + int up_bw; + int down_ptime; + int up_ptime; bool_t has_video; bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/ bool_t in_conference; /*in conference mode */ @@ -179,10 +183,7 @@ int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, sock int set_lock_file(); int get_lock_file(); int remove_lock_file(); -int do_registration(LinphoneCore *lc, bool_t doit); -void check_for_registration(LinphoneCore *lc); void check_sound_device(LinphoneCore *lc); -void linphone_core_verify_codecs(LinphoneCore *lc); void linphone_core_get_local_ip(LinphoneCore *lc, const char *to, char *result); bool_t host_has_ipv6_network(); bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret); @@ -229,7 +230,8 @@ MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFri void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc); void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt); -void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); +int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); +void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params); int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call); void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session); void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md); @@ -386,6 +388,7 @@ typedef struct rtp_config /* stop rtp xmit when audio muted */ bool_t audio_adaptive_jitt_comp_enabled; bool_t video_adaptive_jitt_comp_enabled; + bool_t pad; }rtp_config_t; From b86d76b490e97a58f9385d7d2f3e97a9b8475ce8 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 3 Sep 2012 13:18:40 +0200 Subject: [PATCH 03/51] Fix crash. --- coreapi/sal_eXosip2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 10d0459b4..447ce34eb 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -1954,12 +1954,12 @@ static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){ static void other_request_reply(Sal *sal,eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); LinphoneChatMessage* chat_msg; - ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request)); if (op==NULL){ ms_warning("other_request_reply(): Receiving response to unknown request."); return; } if (ev->response){ + ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request)); update_contact_from_response(op,ev->response); if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0) sal->callbacks.ping_reply(op); From e5fc650e90633a93243e0d0b23343ff1bcb9e2f5 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Mon, 3 Sep 2012 16:28:38 +0200 Subject: [PATCH 04/51] Opaque parameter for sent chat update. --- java/common/org/linphone/core/LinphoneChatRoom.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index a8ef5e215..f06e8fda5 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -34,6 +34,6 @@ public interface LinphoneChatRoom { * send a message to peer member of this chat room. * @param message to be sent */ - void sendMessage(String message); + void sendMessage(Object opaque, String message); } From 3cbabc10695909027c774303346aebdc0edf88eb Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 19 Jul 2012 15:22:51 +0200 Subject: [PATCH 05/51] add device identifier api --- coreapi/linphonecall.c | 4 ++++ coreapi/linphonecore.c | 7 +++++++ coreapi/linphonecore.h | 18 ++++++++++++++++++ coreapi/private.h | 1 + 4 files changed, 30 insertions(+) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 929814b52..786744fb2 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -521,7 +521,11 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const switch(call->reason){ case LinphoneReasonDeclined: call->log->status=LinphoneCallDeclined; +<<<<<<< HEAD break; +======= + break; +>>>>>>> add device identifier api case LinphoneReasonNotAnswered: call->log->status=LinphoneCallMissed; break; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 47f8a61ae..d67ba6d56 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5104,3 +5104,10 @@ void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, }else ms_warning("Could not apply zoom: video output wasn't activated."); } +void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id) { + if (lc->device_id) ms_free(lc->device_id); + lc->device_id=ms_strdup(device_id); +} +const char* linphone_core_get_device_identifier(const LinphoneCore *lc) { + return lc->device_id; +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 2972bc090..637630997 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -827,6 +827,24 @@ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, /* function to be periodically called in a main loop */ void linphone_core_iterate(LinphoneCore *lc); +#if 0 /*not implemented yet*/ +/** + * @ingroup initializing + * Provide Linphone Core with an unique identifier. This be later used to identified contact address coming from this device. + * Value is not saved. + * @param lc object + * @param string identifying the device, can be EMEI or UDID + * + */ +void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id); +/** + * @ingroup initializing + * get Linphone unique identifier + * + */ +const char* linphone_core_get_device_identifier(const LinphoneCore *lc); + +#endif LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url); diff --git a/coreapi/private.h b/coreapi/private.h index 6c9ba8d29..2687ddc03 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -539,6 +539,7 @@ struct _LinphoneCore int device_rotation; int max_calls; LinphoneTunnel *tunnel; + char* device_id; }; LinphoneTunnel *linphone_core_tunnel_new(LinphoneCore *lc); From f252a1ad202aeb04f59c0e6b679e3cdaf94a5b3c Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Mon, 3 Sep 2012 18:13:02 +0200 Subject: [PATCH 06/51] add traces for ICE troubleshooting --- coreapi/linphonecall.c | 5 +---- coreapi/linphonecore.c | 3 ++- coreapi/misc.c | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 786744fb2..679d2da10 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -521,11 +521,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const switch(call->reason){ case LinphoneReasonDeclined: call->log->status=LinphoneCallDeclined; -<<<<<<< HEAD - break; -======= break; ->>>>>>> add device identifier api case LinphoneReasonNotAnswered: call->log->status=LinphoneCallMissed; break; @@ -1747,6 +1743,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ ice_session_eliminate_redundant_candidates(call->ice_session); ice_session_choose_default_candidates(call->ice_session); } else { + ms_warning("No STUN answer from [%s], disabling ICE",linphone_core_get_stun_server(call->core)); linphone_call_delete_ice_session(call); } switch (call->state) { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d67ba6d56..e4f35e387 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1903,7 +1903,8 @@ void linphone_core_iterate(LinphoneCore *lc){ if (call->state==LinphoneCallOutgoingInit && (curtime-call->start_time>=2)){ /*start the call even if the OPTIONS reply did not arrive*/ if (call->ice_session != NULL) { - /* ICE candidates gathering has not finished yet, proceed with the call without ICE anyway. */ + ms_warning("ICE candidates gathering from [%s] has not finished yet, proceed with the call without ICE anyway." + ,linphone_core_get_stun_server(lc)); linphone_call_delete_ice_session(call); linphone_call_stop_media_streams(call); } diff --git a/coreapi/misc.c b/coreapi/misc.c index a22bbc1d9..b97f265be 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -611,6 +611,7 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port + 1, 2, NULL); } + ms_message("ICE: gathering candidate from [%s]",server); /* Gather local srflx candidates. */ ice_session_gather_candidates(call->ice_session, ss, ss_len); return 0; From 5792504e34bee3cfa2b643a1a2a22fa1c46f5bef Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 4 Sep 2012 10:43:59 +0200 Subject: [PATCH 07/51] add readline dependency to README --- README.macos | 1 + 1 file changed, 1 insertion(+) diff --git a/README.macos b/README.macos index 3ec0d0429..aecd2922f 100644 --- a/README.macos +++ b/README.macos @@ -16,6 +16,7 @@ You need: $ port install libeXosip2 #WARNING: currently outdated in macport $ port install ffmpeg-devel $ port install libvpx + $ port install readline - Install srtp (optional) for call encryption $ port install srtp From 9e6b47328461d2eb307023d3d3b133bc3bc0c40f Mon Sep 17 00:00:00 2001 From: Margaux Clerc Date: Tue, 4 Sep 2012 16:17:47 +0200 Subject: [PATCH 08/51] implement incoming chat notification on Mac --- gtk/chat.c | 14 +++++++++++++- gtk/linphone.h | 2 ++ gtk/main.c | 5 +++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/gtk/chat.c b/gtk/chat.c index 0dafbdb9c..4138f6722 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -19,6 +19,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" + +#ifdef HAVE_GTK_OSX +#include +#endif + GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const char *with){ GtkWidget *w; GtkTextBuffer *b; @@ -37,6 +42,7 @@ GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const char *with){ } void linphone_gtk_create_chatroom(const char *with){ + LinphoneChatRoom *cr=linphone_core_create_chat_room(linphone_gtk_get_core(),with); if (!cr) return; linphone_gtk_init_chatroom(cr,with); @@ -101,9 +107,15 @@ void linphone_gtk_send_text(GtkWidget *button){ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message){ GtkWidget *w=(GtkWidget*)linphone_chat_room_get_user_data(room); - if (w==NULL){ + if (w==NULL){ w=linphone_gtk_init_chatroom(room,linphone_address_as_string_uri_only(from)); } + + #ifdef HAVE_GTK_OSX + /* Notify when a new message is send */ + linphone_gtk_status_icon_set_blinking(TRUE); + #endif + linphone_gtk_push_text(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog")), linphone_address_as_string_uri_only(from), message,FALSE); diff --git a/gtk/linphone.h b/gtk/linphone.h index d4cafe28f..f817969f7 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -97,6 +97,8 @@ void * linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, c void linphone_gtk_show_directory_search(void); +void linphone_gtk_status_icon_set_blinking(gboolean val); + /*functions controlling the different views*/ gboolean linphone_gtk_use_in_call_view(); LinphoneCall *linphone_gtk_get_currently_displayed_call(gboolean *is_conf); diff --git a/gtk/main.c b/gtk/main.c index 2955b3ecc..2085e3d20 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -65,10 +65,11 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token); static void linphone_gtk_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate); static gboolean linphone_gtk_auto_answer(LinphoneCall *call); -static void linphone_gtk_status_icon_set_blinking(gboolean val); +void linphone_gtk_status_icon_set_blinking(gboolean val); void _linphone_gtk_enable_video(gboolean val); + static gboolean verbose=0; static gboolean auto_answer = 0; static gchar * addr_to_call = NULL; @@ -1347,7 +1348,7 @@ static gboolean do_icon_blink(GtkStatusIcon *gi){ #endif -static void linphone_gtk_status_icon_set_blinking(gboolean val){ +void linphone_gtk_status_icon_set_blinking(gboolean val){ #ifdef HAVE_GTK_OSX static gint attention_id; GtkOSXApplication *theMacApp=(GtkOSXApplication*)g_object_new(GTK_TYPE_OSX_APPLICATION, NULL); From 5e4ac070cc9fbf979ef789bb5f85b48859c7f4eb Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 4 Sep 2012 22:02:34 +0200 Subject: [PATCH 09/51] implement edge detection, and automatic configuration of call parameters for low bitrates --- coreapi/linphonecall.c | 60 +++++++++++++++++++++++++-------------- coreapi/misc.c | 15 +++------- coreapi/offeranswer.c | 1 - coreapi/private.h | 8 +++++- coreapi/sal.h | 6 ---- coreapi/sal_eXosip2_sdp.c | 4 --- mediastreamer2 | 2 +- 7 files changed, 51 insertions(+), 45 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index b60517136..9192a84b7 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -207,7 +207,10 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li md->nstreams=1; strncpy(md->addr,call->localip,sizeof(md->addr)); strncpy(md->username,username,sizeof(md->username)); - md->bandwidth=linphone_core_get_download_bandwidth(lc); + + if (call->params.down_bw) + md->bandwidth=call->params.down_bw; + else md->bandwidth=linphone_core_get_download_bandwidth(lc); /*set audio capabilities */ strncpy(md->streams[0].rtp_addr,call->localip,sizeof(md->streams[0].rtp_addr)); @@ -217,7 +220,10 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li md->streams[0].proto=(call->params.media_encryption == LinphoneMediaEncryptionSRTP) ? SalProtoRtpSavp : SalProtoRtpAvp; md->streams[0].type=SalAudio; - md->streams[0].ptime=lc->net_conf.down_ptime; + if (call->params.down_ptime) + md->streams[0].ptime=call->params.down_ptime; + else + md->streams[0].ptime=lc->net_conf.down_ptime; l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw,&md->streams[0].max_rate); pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event")); l=ms_list_append(l,pt); @@ -320,6 +326,21 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) { stats->sent_rtcp = NULL; } +static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){ + if (ac->port!=0){ + strcpy(md->streams[0].rtp_addr,ac->addr); + md->streams[0].rtp_port=ac->port; + if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->nstreams==1){ + strcpy(md->addr,ac->addr); + } + } + if (vc->port!=0){ + strcpy(md->streams[1].rtp_addr,vc->addr); + md->streams[1].rtp_port=vc->port; + } + +} + static void discover_mtu(LinphoneCore *lc, const char *remote){ int mtu; if (lc->net_conf.mtu==0 ){ @@ -333,16 +354,12 @@ static void discover_mtu(LinphoneCore *lc, const char *remote){ } } -static void update_sal_media_description_from_params(SalMediaDescription *md, const LinphoneCallParams *params){ - if (params->down_bw) - md->bandwidth=params->down_bw; - if (params->down_ptime) - md->streams[0].ptime=params->down_ptime; -} +#define STUN_CANDIDATE_INIT {{0},0} LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params) { LinphoneCall *call=ms_new0(LinphoneCall,1); + StunCandidate ac=STUN_CANDIDATE_INIT,vc=STUN_CANDIDATE_INIT; int ping_time=-1; call->dir=LinphoneCallOutgoing; call->op=sal_op_new(lc->sal); @@ -355,15 +372,16 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->ice_session = ice_session_new(); ice_session_set_role(call->ice_session, IR_Controlling); } - call->localdesc=create_local_media_description (lc,call); - call->camera_active=params->has_video; if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseStun) { - ping_time=linphone_core_run_stun_tests(call->core,call); + ping_time=linphone_core_run_stun_tests(call->core,call,&ac, &vc); } if (ping_time>=0) { linphone_core_adapt_to_network(lc,ping_time,&call->params); - update_sal_media_description_from_params(call->localdesc,&call->params); } + call->localdesc=create_local_media_description(lc,call); + update_media_description_from_stun(call->localdesc,&ac,&vc); + call->camera_active=params->has_video; + discover_mtu(lc,linphone_address_get_domain (to)); if (params->referer){ sal_call_set_referer(call->op,params->referer->op); @@ -376,6 +394,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro LinphoneCall *call=ms_new0(LinphoneCall,1); char *from_str; int ping_time=-1; + StunCandidate ac=STUN_CANDIDATE_INIT,vc=STUN_CANDIDATE_INIT; call->dir=LinphoneCallIncoming; sal_op_set_user_pointer(op,call); @@ -398,8 +417,6 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_call_init_common(call, from, to); linphone_core_init_default_params(lc, &call->params); call->params.has_video &= !!lc->video_policy.automatically_accept; - call->localdesc=create_local_media_description(lc,call); - call->camera_active=call->params.has_video; switch (linphone_core_get_firewall_policy(call->core)) { case LinphonePolicyUseIce: call->ice_session = ice_session_new(); @@ -416,15 +433,18 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro } break; case LinphonePolicyUseStun: - ping_time=linphone_core_run_stun_tests(call->core,call); + ping_time=linphone_core_run_stun_tests(call->core,call,&ac, &vc); /* No break to also destroy ice session in this case. */ default: break; } if (ping_time>=0) { linphone_core_adapt_to_network(lc,ping_time,&call->params); - update_sal_media_description_from_params(call->localdesc,&call->params); }; + call->localdesc=create_local_media_description(lc,call); + update_media_description_from_stun(call->localdesc,&ac,&vc); + call->camera_active=call->params.has_video; + discover_mtu(lc,linphone_address_get_domain(from)); return call; } @@ -953,11 +973,10 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; - SalMediaDescription *md=call->localdesc; AudioStream *audiostream; int dscp=lp_config_get_int(lc->config,"rtp","audio_dscp",-1); - call->audiostream=audiostream=audio_stream_new(md->streams[0].rtp_port,md->streams[0].rtcp_port,linphone_core_ipv6_enabled(lc)); + call->audiostream=audiostream=audio_stream_new(call->audio_port,call->audio_port+1,linphone_core_ipv6_enabled(lc)); if (dscp!=-1) audio_stream_set_dscp(audiostream,dscp); if (linphone_core_echo_limiter_enabled(lc)){ @@ -1006,13 +1025,12 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ void linphone_call_init_video_stream(LinphoneCall *call){ #ifdef VIDEO_ENABLED LinphoneCore *lc=call->core; - SalMediaDescription *md=call->localdesc; - if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].rtp_port>0){ + if ((lc->video_conf.display || lc->video_conf.capture) && call->params.has_video){ int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0); int dscp=lp_config_get_int(lc->config,"rtp","video_dscp",-1); - call->videostream=video_stream_new(md->streams[1].rtp_port,md->streams[1].rtcp_port,linphone_core_ipv6_enabled(lc)); + call->videostream=video_stream_new(call->video_port,call->video_port+1,linphone_core_ipv6_enabled(lc)); if (dscp!=-1) video_stream_set_dscp(call->videostream,dscp); video_stream_enable_display_filter_auto_rotate(call->videostream, lp_config_get_int(lc->config,"video","display_filter_auto_rotate",0)); diff --git a/coreapi/misc.c b/coreapi/misc.c index a2a61ce85..1e7676bfa 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -467,7 +467,7 @@ static int recvStunResponse(ortp_socket_t sock, char *ipaddr, int *port, int *id } /* this functions runs a simple stun test and return the number of milliseconds to complete the tests, or -1 if the test were failed.*/ -int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ +int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc){ const char *server=linphone_core_get_stun_server(lc); if (lc->sip_conf.ipv6_enabled){ @@ -483,13 +483,9 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ bool_t got_audio,got_video; bool_t cone_audio=FALSE,cone_video=FALSE; struct timeval init,cur; - SalEndpointCandidate *ac,*vc; double elapsed; int ret=0; - ac=&call->localdesc->streams[0].candidates[0]; - vc=&call->localdesc->streams[1].candidates[0]; - if (parse_hostname_to_addr(server,&ss,&ss_len)<0){ ms_error("Fail to parser stun server address: %s",server); return -1; @@ -569,28 +565,25 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ } } } - if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) - || sock2==-1){ - strcpy(call->localdesc->addr,ac->addr); - } close_socket(sock1); if (sock2!=-1) close_socket(sock2); return ret; } return -1; - } void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params){ if (lp_config_get_int(lc->config,"net","activate_edge_workarounds",0)==1){ + ms_message("Stun server ping time is %i ms",ping_time_ms); int threshold=lp_config_get_int(lc->config,"net","edge_ping_time",500); if (ping_time_ms>threshold){ int edge_ptime=lp_config_get_int(lc->config,"net","edge_ptime",100); - int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",30); + int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",20); /* we are in a 2G network*/ params->up_bw=params->down_bw=edge_bw; params->up_ptime=params->down_ptime=edge_ptime; + params->has_video=FALSE; }/*else use default settings */ } diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index f2cb836c2..541a1eee3 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -240,7 +240,6 @@ static void initiate_incoming(const SalStreamDescription *local_cap, if (result->payloads && !only_telephone_event(result->payloads) && (remote_offer->rtp_port!=0 || remote_offer->rtp_port==SalStreamSendOnly)){ strcpy(result->rtp_addr,local_cap->rtp_addr); strcpy(result->rtcp_addr,local_cap->rtcp_addr); - memcpy(result->candidates,local_cap->candidates,sizeof(result->candidates)); result->rtp_port=local_cap->rtp_port; result->rtcp_port=local_cap->rtcp_port; result->bandwidth=local_cap->bandwidth; diff --git a/coreapi/private.h b/coreapi/private.h index d5e98c956..2bf643d47 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -230,7 +230,13 @@ MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFri void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc); void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt); -int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); + +typedef struct StunCandidate{ + char addr[64]; + int port; +}StunCandidate; + +int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc); void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params); int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call); void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session); diff --git a/coreapi/sal.h b/coreapi/sal.h index 616b0aba9..8faa11375 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -105,11 +105,6 @@ typedef enum{ SalStreamInactive }SalStreamDir; -typedef struct SalEndpointCandidate{ - char addr[64]; - int port; -}SalEndpointCandidate; - #define SAL_ENDPOINT_CANDIDATE_MAX 2 #define SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN 64 @@ -159,7 +154,6 @@ typedef struct SalStreamDescription{ MSList *payloads; //rtcp_addr; rtp_port=desc->rtp_port; rtcp_port=desc->rtcp_port; - if (desc->candidates[0].addr[0]!='\0'){ - rtp_addr=desc->candidates[0].addr; - rtp_port=desc->candidates[0].port; - } if (desc->proto == SalProtoRtpSavp) { int i; diff --git a/mediastreamer2 b/mediastreamer2 index beb4318d1..18a6f4d86 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit beb4318d1e5eb282adc82967a9c80e89cd406045 +Subproject commit 18a6f4d8629593125cc7b707f5fdad1462b2dcd9 From acd370ea93fff73c76a74f1cbb3f1c8b64bdef72 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 5 Sep 2012 09:00:28 +0200 Subject: [PATCH 10/51] add linphone_core_get_calls_nb to linphonecore.h --- coreapi/linphonecore.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 637630997..7a1d27f09 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1267,6 +1267,8 @@ void linphone_core_set_rtp_transport_factories(LinphoneCore* lc, LinphoneRtpTran int linphone_core_get_current_call_stats(LinphoneCore *lc, rtp_stats_t *local, rtp_stats_t *remote); +int linphone_core_get_calls_nb(const LinphoneCore *lc); + const MSList *linphone_core_get_calls(LinphoneCore *lc); LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc); From fd4937409b089ba35c887dde134c2ab0864411ca Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 5 Sep 2012 11:51:26 +0200 Subject: [PATCH 11/51] Add java interface for chat. Add -D for exosip Remove obsolete media_api to avoid confusion --- build/android/common.mk | 1 + .../org/linphone/core/LinphoneChatRoom.java | 12 +- media_api/.gitignore | 3 - media_api/DESIGN.txt | 135 ------------- media_api/Makefile.am | 31 --- media_api/apitest.c | 36 ---- media_api/apitest.h | 0 media_api/basiccall.c | 170 ----------------- media_api/basiccall.h | 51 ----- media_api/callmember.c | 153 --------------- media_api/callmember.h | 59 ------ media_api/ccl | 1 - media_api/common.h | 31 --- media_api/media_api.c | 69 ------- media_api/media_api.h | 69 ------- media_api/mediaflow.c | 179 ------------------ media_api/mediaflow.h | 68 ------- 17 files changed, 12 insertions(+), 1056 deletions(-) delete mode 100644 media_api/.gitignore delete mode 100644 media_api/DESIGN.txt delete mode 100644 media_api/Makefile.am delete mode 100644 media_api/apitest.c delete mode 100644 media_api/apitest.h delete mode 100644 media_api/basiccall.c delete mode 100644 media_api/basiccall.h delete mode 100644 media_api/callmember.c delete mode 100644 media_api/callmember.h delete mode 100644 media_api/ccl delete mode 100644 media_api/common.h delete mode 100644 media_api/media_api.c delete mode 100644 media_api/media_api.h delete mode 100644 media_api/mediaflow.c delete mode 100644 media_api/mediaflow.h diff --git a/build/android/common.mk b/build/android/common.mk index 4fa833b59..4db1f6809 100644 --- a/build/android/common.mk +++ b/build/android/common.mk @@ -59,6 +59,7 @@ LOCAL_CFLAGS += \ -DORTP_INET6 \ -DINET6 \ -DOSIP_MT \ + -DHAVE_EXOSIP_RESET_TRANSPORTS \ -DENABLE_TRACE \ -DLINPHONE_VERSION=\"$(LINPHONE_VERSION)\" \ -DLINPHONE_PLUGINS_DIR=\"\\tmp\" \ diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index f06e8fda5..8c85b64bc 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -34,6 +34,16 @@ public interface LinphoneChatRoom { * send a message to peer member of this chat room. * @param message to be sent */ + void sendMessage(String message); + /** + * Send a message to peer member of this chat room. + * @param chat message + */ + void sendMessage(LinphoneChatMessage msg, LinphoneChatMessage.StateListener listener); + /** + * DEPRECATED + * @param opaque + * @param message + */ void sendMessage(Object opaque, String message); - } diff --git a/media_api/.gitignore b/media_api/.gitignore deleted file mode 100644 index e99558847..000000000 --- a/media_api/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/media_api/DESIGN.txt b/media_api/DESIGN.txt deleted file mode 100644 index f7c9cfc1f..000000000 --- a/media_api/DESIGN.txt +++ /dev/null @@ -1,135 +0,0 @@ -MEDIA API DESIGN DRAFT -********************** - - -The objective of the media_api is to construct and run the necessary -processing on audio and video data flows for a given call (two party call) or -conference. -The media_api must support calls where callmember can be remote as well -local hosted, in other words the media_api can be used inside linphone as -well as in sip conferencing server. The api must support multiples way of -getting media data: from disk, from rtp, from soundcard... -The media_api is object oriented in C, and is based on the mediastreamer library -to deal with audio or video signals, and on glib for types and usefull routines. - -The api must provide object and methods that describes the call, and then functions -that executes the processing (using the mediastreamer) that is necessary for the -call described. - -Proposed API: - -************************************************************************ -object: MediaFlow -This object reprensent a media that is shared between all members of the call, -for example voice. -methods: -MediaFlow *media_flow_new(char *id_string,gint type,gint duplex); -type can be FLOW_AUDIO, FLOW_VIDEO. -if duplex is 1, it means that the media flow is used by every member in both -receiving and sending mode. -id_string is just a string to identify the flow. - -void media_flow_destroy(MediaFlow *flow); -destructor - -************************************************************************** -object: CallMember -This object reprensent a member of a call. -methods: -CallMember *call_member_new(); - -gint call_member_setup_flow(CallMember *member, MediaFlow *flow, - char *rx_endpoint, char *tx_endpoint); - This is the most important function of the API. It describes the way each - call member receives and send a given media flow. - The MediaFlow "flow" is added to the list of flows used by the member "member". - rx_endpoint is a string that described how data is received by the call member. - It should be an url, for example "rtp://213.21.54.127:7080". In this case it - means that data will be received on port 7080 at ip address 213.21.54.127. - tx_endpoint is a string that described how data is sent by the call member. - The role of url is very important. They can be: - "rtp://213.21.54.127:7080" - "file://tmp/media.out" -a file on disk - "oss://0" -souncard 0 using oss api - "alsa://0" -soundcard 0 using alsa api. - In order to work, the call member must be part of a BasicCall, as well as - the flow must be part of the BasicCall too (using basic_call_add_flow()) - This function may (on the backend) create a MediaEndpoint object that stores - the rx_endpoint and tx_endpoint parameter. This object is added to: - -the list of MediaEndpoint maintained by the member (list per member) - -the list of MediaEndpoint maintained by the flow (list per flow) - - -************************************************************************** -object: BasicCall -This object handles simple calls (two party calls). It defines inside itself -two CallMember objects. -method: -BasicCall *basic_call_new(); - -CallMember *basic_call_get_member(BasicCall *call, gint member_number); - Returns a member of a BasicCall according to a number. - -void basic_call_add_flow(BasicCall *call, MediaFlow *flow); - Adds a flow to the call's list of flow. - -gint basic_call_start_flow(BasicCall *call, MediaFlow *flow); - This function construct the mediastreamer processing chain necessary to make - the call running, if not done, and runs it using ms_start() - -gint basic_call_stop_flow(BasicCall *call, MediaFlow *flow); - -gint basic_call_start_all_flows(BasicCall *call); - -void basic_call_destroy(BasicCall *call); - Destroy all data used by the call: call members, call flows. - -************************************************************************** -object: ConferenceCall -This object handles conference call (which are quite much complicated than basic -calls). But this object should have the same method as the BasicCall object. - -******************************************************************* - EXAMPLE -******************************************************************* - -Two party call between call member A on machine "linphone.org" and call member B on machine "home.com". -The media_api is running on "home.com". - - A (on linphone.org) B (on home.com) - ------->(send to rtp://home.com:7080 MSRTPReceiver------>Decode----->(send to oss:/0) - -------<(recv on rtp://linphone.org:7020 MSRTPSender<--------Encode<-----(read on oss://0) - -This is how to setup this call using the media_api: -BasicCall *call; -CallMember *memberA,*memberB; -MediaFlow *flow; - -/* create a basic call*/ -call=basic_call_new(); -/* get a pointer to the pre-define members of the call */ -memberA=basic_call_get_member(call,0); -memberB=basic_call_get_member(call,1); - -/* create a media flow */ -flow=media_flow_new("voice",FLOW_AUDIO,1); -/* tell that the flow is used by the call */ -basic_call_add_flow(call,flow); -/* tell how each member uses the flow (how is the interface ?)*/ -call_member_setup_flow(memberA,flow,"rtp://linphone.org:7020","rtp://home.com:7080"); -/* note: it is not efficient to do name resolution at this stage: that's why in reality numeric ip address -should be given instead of host name */ -call_member_setup_flow(memberB,flow,"oss://0","oss://0"); - -/* start the flow */ -basic_call_start_flow(call,flow); - -In case where the media api is running on another host called "toto" (in a media translator application for example), - the only thing that would change is the url given to memberB: tx="rtp://home.com:8820" for example and - rx="rtp://toto:9522". - -In the sipomatic application (the test application I use to test linphone (it answers to call and plays -a short annoucement)), I would write rx="file://path_to_annoucement.raw" and tx="file://dev/null" instead of -"oss://0". diff --git a/media_api/Makefile.am b/media_api/Makefile.am deleted file mode 100644 index 38dcf063f..000000000 --- a/media_api/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -## Process this file with automake to produce Makefile.in -if BUILD_MEDIA_API - -#the media_api library is the only one we have to build here -lib_LTLIBRARIES=libmedia_api.la - -#definition of the sources of libmedia_api -libmedia_api_la_SOURCES= basiccall.c callmember.c mediaflow.c - -# libmedia_api needs libmediastreamer -libmedia_api_la_LIBADD=$(top_srcdir)/mediastreamer/libmediastreamer.la - -#the media_api test program -bin_PROGRAMS=apitest - -apitest_SOURCES= apitest.c -# the test program links to libmedia_api -apitest_LDADD=libmedia_api.la - -endif - -DEFS=@DEFS@ @SOUNDDEFS@ -DDEBUG -DG_LOG_DOMAIN=\"MediaApi\" - -INCLUDES=-I$(top_srcdir)/mediastreamer \ - -I$(top_srcdir)/speex \ - -I$(top_srcdir)/gsmlib \ - $(ORTP_CFLAGS) \ - -I$(top_srcdir)/lpc10-1.5 \ - -I$(top_srcdir)/ffmpeg - - diff --git a/media_api/apitest.c b/media_api/apitest.c deleted file mode 100644 index cd4ac9e33..000000000 --- a/media_api/apitest.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "basiccall.h" -#include -static int flag = 1; -void stop(int sign){ - flag = 0; -} - - -int main(){ - BasicCall *call; - char *id; - CallMember *memberA, *memberB; - MediaFlow *flow, *flow1; - - signal(SIGINT, stop); - call = basic_call_new(); - memberA = basic_call_get_member(call,MemberA); - memberB = basic_call_get_member(call,MemberB); - - id = "test_voice"; - printf("\n"); - flow = media_flow_new(id, MEDIA_FLOW_VOICE); - - basic_call_add_flow(call, flow); - - call_member_setup_flow(memberA, flow, "file://temp", "oss://0"); - call_member_setup_flow(memberB, flow, "oss://0", "oss://0"); - - media_flow_setup_fd(flow, memberA, memberB, MEDIA_FLOW_HALF_DUPLEX); - basic_call_start_flow(call, flow); - - while(flag){ - sleep(1); - } - -} diff --git a/media_api/apitest.h b/media_api/apitest.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/media_api/basiccall.c b/media_api/basiccall.c deleted file mode 100644 index 8a0044754..000000000 --- a/media_api/basiccall.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "basiccall.h" -#include "../mediastreamer/mscodec.h" - -#define ONESYNC 10 -#define MULTISYNC 20 - -BasicCall *basic_call_new(){ - BasicCall *bc = (BasicCall*) g_malloc(sizeof(BasicCall)); - api_trace("basic_call_new: creating a basic call"); - bc->memberA = call_member_new("memberA"); - bc->memberB = call_member_new("memberB"); - return bc; -} - -CallMember *basic_call_get_member(BasicCall *call, int member_nu){ - api_trace("basic_call_get_member: called for %d",member_nu); - if(member_nu == MemberA){ - return call->memberA; - } - else if(member_nu == MemberB){ - return call->memberB; - } -} - -void basic_call_add_flow(BasicCall *call, MediaFlow *flow){ - api_trace("basic_call_add_flow: called for %s",flow->id); - call->flows = g_list_append( call->flows, flow); - return 1; -} - -int find_mediaflow(gconstpointer llist, gconstpointer flow){ - //MediaFlow *mf = (MediaFlow *) ((BasicCallFlow*)llist)->mediaFlow; - if(((MediaFlow*)flow)->id == ((MediaFlow*)llist)->id){ - return 0; - } - return 1; -} - -int basic_call_start_flow(BasicCall *call, MediaFlow *flow){ - int i=0; - int syncFlag=0; - int nFlowDirections; - MSSync *sync; - Members *source, *destination; - FlowDirections *fd; - GList *elem, *selem; - GList *snd_read = NULL, *snd_write = NULL, *filter = NULL; - - //Commented by Sharat - //This is initialized in media_api.c - //when should these functions be really called? - //ms_init(); - //ortp_init(); - - api_trace("basic_call_start_flow: called for flow %s", flow->id); - - elem = g_list_find_custom( call->flows, flow, &find_mediaflow); - if(elem == NULL){ - api_error("basic_call_start_flow: Called for unregistered mediaflow %s", flow->id); - } - - nFlowDirections = g_list_length(flow->flowDirections); - if(flow->type == MEDIA_FLOW_VOICE){ - syncFlag = ONESYNC; - sync = ms_timer_new(); - } - else{ - syncFlag = MULTISYNC; - } - - for(i=0;i< nFlowDirections; i++){ - - if(syncFlag == MULTISYNC){ - sync = ms_timer_new(); - } - fd = (FlowDirections*)g_list_nth_data(flow->flowDirections,i); - source = fd->source; - destination = fd->destination; - - media_flow_start_fd(fd, sync); - if(fd->type == MEDIA_FLOW_DUPLEX){ - switch(source->tx_endpoint->protocol){ - case MEDIA_ALSA: - case MEDIA_OSS: - snd_read = g_list_append(snd_read, fd->recv); - } - switch(destination->rx_endpoint->protocol){ - case MEDIA_ALSA: - case MEDIA_OSS: - snd_write = g_list_append(snd_write, fd->play); - } - - switch(destination->tx_endpoint->protocol){ - case MEDIA_ALSA: - case MEDIA_OSS: - snd_read = g_list_append(snd_read, fd->read); - } - - switch(source->rx_endpoint->protocol){ - case MEDIA_ALSA: - case MEDIA_OSS: - snd_write = g_list_append(snd_write, fd->send); - } - - } - else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){ - - switch(source->tx_endpoint->protocol){ - case MEDIA_ALSA: - case MEDIA_OSS: - snd_read = g_list_append(snd_read, fd->recv); - } - switch(destination->rx_endpoint->protocol){ - case MEDIA_ALSA: - case MEDIA_OSS: - snd_write = g_list_append(snd_write, fd->play); - } - } - if(syncFlag == MULTISYNC){ - flow->sync = g_list_append(flow->sync, sync); - } - } - if(syncFlag == ONESYNC){ - ms_start(sync); - flow->sync = g_list_append(flow->sync, sync); - } - if(syncFlag == MULTISYNC){ - selem = flow->sync; - while(selem != NULL){ - ms_start(selem->data); - selem = g_list_next(selem); - } - } - filter = snd_read; - while(filter != NULL){ - ms_sound_read_start(MS_SOUND_READ((MSFilter*)filter->data)); - filter = g_list_next(filter); - } - - filter = snd_write; - while(filter != NULL){ - ms_sound_write_start(MS_SOUND_WRITE((MSFilter*)filter->data)); - filter = g_list_next(filter); - } - return 1; -} - -int basic_call_stop_flow(BasicCall *call, MediaFlow *flow){ - -} diff --git a/media_api/basiccall.h b/media_api/basiccall.h deleted file mode 100644 index 2351faccc..000000000 --- a/media_api/basiccall.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "common.h" -#include "mediaflow.h" -#include "callmember.h" - -//other includes required to be done here -#define MemberA 1 -#define MemberB 2 - - -struct _BasicCall{ - CallMember *memberA, *memberB; - GList *flows; //linked list of MediaFlows -}; - -typedef struct _BasicCall BasicCall; - - -BasicCall *basic_call_new(); - -CallMember *basic_call_get_member(BasicCall *call, int member_nu); - -void basic_call_add_flow(BasicCall *call, MediaFlow *flow); - -int basic_call_start_flow(BasicCall *call, MediaFlow *flow); - -int basic_call_stop_flow(BasicCall *call, MediaFlow *flow); - -int basic_call_start_all_flows(BasicCall *call); - -int basic_call_destroy(BasicCall *call); - diff --git a/media_api/callmember.c b/media_api/callmember.c deleted file mode 100644 index 643ba7b7c..000000000 --- a/media_api/callmember.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include -#include "common.h" -#include "callmember.h" -#include "mediaflow.h" - - -CallMember *call_member_new(char *name){ - CallMember *member = (CallMember*) g_malloc(sizeof(CallMember)); - api_trace("call_member_new: creating %s", name); - member->name = name; - member->flows = NULL; - member->profile = NULL; - return member; -} - -int call_member_set_rtp_profile(CallMember *member, RtpProfile *profile){ - member->profile = profile; - return 1; -} - -int call_member_setup_flow(CallMember *member, MediaFlow *flow, char* rx, char *tx){ - Members *mem = (Members*) g_malloc(sizeof(Members)); - Flows *flows = (Flows*) g_malloc(sizeof(Flows)); - api_trace("call_member_setup_flow: setting up flow for: CallMember->%s , MediaFlow->%s", member->name, flow->id); - mem->member = member; - mem->rx_endpoint = parse_end_point(rx); - mem->tx_endpoint = parse_end_point(tx); - flow->members = g_list_append(flow->members, mem); - - flows->flow = flow; - flows->rx_endpoint = parse_end_point(rx); - flows->tx_endpoint = parse_end_point(tx); - member->flows = g_list_append(member->flows, flows); - return 1; -} - -EndPoint *parse_end_point(char *endpoint){ - EndPoint *result = (EndPoint*) g_malloc(sizeof(EndPoint)); - int i=0,len1,len2,len, tlen; - char *str2, temp[30], *host_str; - //api_trace("parse_end_point: parsing %s\n", endpoint); - result->pt = -1; - while(1){ - str2 = (char*) strpbrk(endpoint, ":"); - if(str2 == NULL){ - str2 = (char*) strpbrk(endpoint, ";"); - if(str2 == NULL){ - len = strlen(endpoint); - } - else{ - len1 = strlen(endpoint); - len2 = strlen(str2); - len = len1-len2; - } - } - else{ - len1 = strlen(endpoint); - len2 = strlen(str2); - len = len1-len2; - } - strncpy(temp,endpoint,len); - temp[len] = '\0'; - tlen = strlen(temp); - if((tlen >= 2)&&(temp[0] == '/')&&(temp[1] == '/')){ - host_str = remove_slash(temp); - } - switch(i){ - case 0: if(strcmp(temp,"rtp")==0){ - result->protocol=MEDIA_RTP; - } - else if(strcmp(temp,"oss")==0){ - result->protocol=MEDIA_OSS; - } - else if(strcmp(temp,"alsa")==0){ - result->protocol=MEDIA_ALSA; - } - else if(strcmp(temp,"file")==0){ - result->protocol=MEDIA_FILE; - } - break; - case 1: if(result->protocol==MEDIA_FILE){ - result->file=host_str; - } - else{ - result->host = host_str; - } - break; - case 2: result->port = to_digits(temp); - break; - case 3: result->pt = pt_digits(temp); - break; - default://result->options[result->nOptions++] = temp; - break; - } - if(str2 != NULL) endpoint = str2+1; - else break; - i++; - } - return result; -} - -int to_digits(char *str){ - int nu=0,a,len,i; - len = strlen(str); - for(i=0;i3)&&(str[0]=='p')&&(str[1]=='t')&&(str[2]=='=')){ - return to_digits(str+3); - } - else{ - api_warn("Wrong parameters passed in the endpoints"); - return 0; - //ERROR handling - } -} -char *remove_slash(char var[]){ - char *temp = (char*) g_malloc(10*sizeof(char)); - int len,i; - len=strlen(var); - for(i=2;i - -#define api_trace g_message -#define api_error g_error -#define api_warn g_warning - -#define MEDIA_FLOW_DUPLEX 1 -#define MEDIA_FLOW_HALF_DUPLEX 2 - -//Mediaflow type -#define MEDIA_FLOW_VIDEO 1 -#define MEDIA_FLOW_VOICE 2 - -//Mediaflow protocols -#define MEDIA_RTP 1 -#define MEDIA_OSS 2 -#define MEDIA_ALSA 3 -#define MEDIA_FILE 4 - -//Mediaflow codec function -#define MEDIA_API_DECODER 1 -#define MEDIA_API_ENCODER 2 - -#endif - - diff --git a/media_api/media_api.c b/media_api/media_api.c deleted file mode 100644 index 8746e9b0c..000000000 --- a/media_api/media_api.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "media_api.h" - -/* non-standard payload types for oRTP */ -PayloadType lpc1015={ - PAYLOAD_AUDIO_PACKETIZED, - 8000, - 0, - NULL, - 0, - 2400, - "1015/8000/1" -}; - -PayloadType speex_nb={ - PAYLOAD_AUDIO_PACKETIZED, - 8000, - 0, - NULL, - 0, - 15000, - "speex/8000/1" -}; - -PayloadType speex_nb_lbr={ - PAYLOAD_AUDIO_PACKETIZED, - 8000, - 0, - NULL, - 0, - 8000, - "speex-lbr/8000/1" -}; - -void media_api_init() -{ - ortp_init(); - ortp_set_debug_file("oRTP",NULL); - rtp_profile_set_payload(&av_profile,115,&lpc1015); - rtp_profile_set_payload(&av_profile,110,&speex_nb); - rtp_profile_set_payload(&av_profile,111,&speex_nb_lbr); - rtp_profile_set_payload(&av_profile,101,&telephone_event); - ms_init(); - ms_speex_codec_init(); -#ifdef HAVE_AVCODEC - ms_AVCodec_init(); -#endif -} - - diff --git a/media_api/media_api.h b/media_api/media_api.h deleted file mode 100644 index b7341fc4a..000000000 --- a/media_api/media_api.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef MEDIA_API_H -#define MEDIA_API_H - -/* some mediastreamer include files....*/ - -#include "ms.h" - -/* audio codecs ; all these header are not really required as we should use ms_codec_new..() to -create codec filters*/ -/*Commented by Sharath Udupa -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_FFMPEG -#include -#include */ -#endif - -/* some usefull filters of the mediastreamer */ -#include "mscopy.h" -#include "msfdispatcher.h" -#include "msqdispatcher.h" - -/* some synchronisation sources */ -#include -#include - -/* some streams sources and sinks */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif - - - diff --git a/media_api/mediaflow.c b/media_api/mediaflow.c deleted file mode 100644 index e0e6be403..000000000 --- a/media_api/mediaflow.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "common.h" -#include "mediaflow.h" -#include "callmember.h" - - -MediaFlow *media_flow_new(char *id_string, int type){ - MediaFlow *flow = (MediaFlow *) g_malloc(sizeof(MediaFlow)); //malloc required? - api_trace("media_flow_new: creating %s",id_string); - flow->id = id_string; - flow->type = type; - flow->flowDirections = NULL; - flow->members = NULL; - return flow; -} - -int media_flow_destroy(MediaFlow *flow){ - g_free(flow); - return 1; -} - -int media_flow_setup_fd(MediaFlow *flow, CallMember* csource, CallMember *cdestination, int direction){ - GList *source, *destination; - char *dir; - FlowDirections *fd = (FlowDirections *) g_malloc(sizeof(FlowDirections)); - if(direction == MEDIA_FLOW_DUPLEX) dir = "DUPLEX"; - else if(direction == MEDIA_FLOW_HALF_DUPLEX) dir = "HALF_DUPLEX"; - api_trace("media_flow_setup_fd: setting up %s flow for %s , %s",dir, csource->name, cdestination->name); - source = g_list_find_custom(flow->members, csource, &find); - destination =g_list_find_custom(flow->members, cdestination, &find); - if(source == NULL){ - api_error("media_flow_setup_fd: Invalid source %s specified", csource->name); - } - if(destination == NULL){ - api_error("media_flow_setup_fd: Invalid destination %s specified", cdestination->name); - //ERROR handling to be done here - } - fd->source = (Members*)source->data; - fd->destination = (Members*)destination->data; - fd->type = direction; - flow->flowDirections = g_list_append(flow->flowDirections, fd); - return 1; -} - -int find(gconstpointer mem, gconstpointer cmember){ - if(!strcmp(((Members*)mem)->member->name, ((CallMember*)cmember)->name)){ - return 0; - } - return 1; -} - -int media_flow_start_fd(FlowDirections *fd, MSSync *sync){ - Members *source, *destination; - source = fd->source; - destination = fd->destination; - if(fd->type == MEDIA_FLOW_DUPLEX){ - fd->recv = set_MSFilter(source->tx_endpoint,1,fd); - fd->dec = set_CODECFilter(source->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER); - fd->play = set_MSFilter(destination->rx_endpoint,0,fd); - - ms_filter_add_link(fd->recv,fd->dec); - ms_filter_add_link(fd->dec,fd->play); - ms_sync_attach(sync, fd->recv); - - fd->read = set_MSFilter(destination->tx_endpoint,1,fd); - fd->enc = set_CODECFilter(destination->member->profile, destination->tx_endpoint->pt,MEDIA_API_ENCODER); - fd->send = set_MSFilter(source->rx_endpoint,0,fd); - - ms_filter_add_link(fd->read, fd->enc); - ms_filter_add_link(fd->enc, fd->send); - ms_sync_attach(sync, fd->read); - - } - else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){ - - fd->recv = set_MSFilter(source->tx_endpoint,1,fd); - fd->dec = set_CODECFilter(sourcec->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER); - fd->play = set_MSFilter(destination->rx_endpoint,0,fd); - - ms_filter_add_link(fd->recv,fd->dec); - ms_filter_add_link(fd->dec,fd->play); - ms_sync_attach(sync, fd->recv); - } - return 1; -} - - -MSFilter *set_MSFilter(EndPoint *endpoint, int type, FlowDirections *fdir){ - MSFilter *filter; - RtpSession *rtps; - switch(endpoint->protocol){ - case MEDIA_RTP: - rtps = rtp_session_new(RTP_SESSION_RECVONLY); - rtp_session_set_local_addr(rtps,"0.0.0.0",8000,8001); - rtp_session_set_scheduling_mode(rtps,0); - rtp_session_set_blocking_mode(rtps,0); - - if(type == 1){ - filter = ms_rtp_recv_new(); - ms_rtp_recv_set_session(MS_RTP_RECV(filter), rtps); - fdir->rtpSessions = g_list_append(fdir->rtpSessions, rtps); - return filter; - } - else{ - //ms_rtp_send_new - } - case MEDIA_OSS: - if(type == 1){ - filter = ms_oss_read_new(); - ms_sound_read_set_device(MS_SOUND_READ(filter),0); - return filter; - } - else{ - filter = ms_oss_write_new(); - ms_sound_write_set_device(MS_SOUND_WRITE(filter),0); - return filter; - } - case MEDIA_FILE: - if(type == 1){ - filter = ms_read_new(endpoint->file); - return filter; - } - if(type == 0){ - filter = ms_write_new(endpoint->file); - return filter; - } - - } -} - -MSFilter *set_CODECFilter(RtpProfile *profile, int pt, int mode){ - PayloadType *payload; - - switch(mode){ - case MEDIA_API_DECODER: - payload = rtp_profile_get_payload(profile, pt); - if(payload == NULL){ - api_error("media_api: undefined payload in URL\n"); - return NULL; - } - return ms_decoder_new_with_string_id(payload->mime_type); - - //Commented this to include the new RtpProfile - /*if(pt != -1) return ms_decoder_new_with_pt(pt); - *else return ms_copy_new(); - */ - case MEDIA_API_ENCODER: - - payload = rtp_profile_get_payload(profile, pt); - if(payload == NULL){ - api_error("media_api: undefined payload in URL\n"); - return NULL; - } - return ms_encoder_new_with_string_id(payload->mime_type); - /*if(pt != -1) return ms_encoder_new_with_pt(pt); - *else return ms_copy_new(); - */ - } -} - - diff --git a/media_api/mediaflow.h b/media_api/mediaflow.h deleted file mode 100644 index 598df4d98..000000000 --- a/media_api/mediaflow.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - The objective of the media_api is to construct and run the necessary processing - on audio and video data flows for a given call (two party call) or conference. - Copyright (C) 2001 Sharath Udupa skuds@gmx.net - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a c:opy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -struct _MediaFlow{ - char *id; - int type; - GList *members; - GList *flowDirections; - GList *sync; //holds all the filters in this MediaFlow -}; - -typedef struct _MediaFlow MediaFlow; - -struct _Members{ - struct _CallMember *member; - struct _EndPoint *rx_endpoint; - struct _EndPoint *tx_endpoint; -}; - -typedef struct _Members Members; - -struct _FlowDirections{ - Members *source, *destination; - MSFilter *recv, - *dec, - *play; - MSFilter *read, //Filters used - *enc, //if type==DUPLEX - *send; - GList *rtpSessions; - int type; -}; - -typedef struct _FlowDirections FlowDirections; - - -MediaFlow *media_flow_new(char *id_string, int type); - -int media_flow_setup_fd(MediaFlow*, struct _CallMember *, struct _CallMember *, int); - -int media_flow_start_fd(FlowDirections *fd, MSSync *sync); - -int media_flow_destroy(MediaFlow *flow); - -/* Internal functions */ -int find(gconstpointer, gconstpointer); - -MSFilter *set_MSFilter(struct _EndPoint *, int, FlowDirections *); - -MSFilter *set_CODECFilter(RtpProfile* , int, int); - From cc7a707754f028a36dd2dfee914b93f431419622 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 5 Sep 2012 14:19:50 +0200 Subject: [PATCH 12/51] forgot to commit a file --- .../linphone/core/LinphoneChatMessage.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 java/common/org/linphone/core/LinphoneChatMessage.java diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java new file mode 100644 index 000000000..77238d270 --- /dev/null +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -0,0 +1,53 @@ +package org.linphone.core; + +import java.util.Vector; + + +public interface LinphoneChatMessage { + interface StateListener{ + void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state); + } + static class State { + static private Vector values = new Vector(); + private final int mValue; + public final int value() {return mValue;} + + private final String mStringValue; + /** + * Idle + */ + public final static State Idle = new State(0,"Idle"); + /** + * Incoming call received. + */ + public final static State InProgress = new State(1,"InProgress"); + /** + * Outgoing call initialiazed. + */ + public final static State Delivered = new State(2,"Delivered"); + /** + * Outgoing call in progress. + */ + public final static State NotDelivered = new State(3,"NotDelivered"); + + private State(int value,String stringValue) { + mValue = value; + values.addElement(this); + mStringValue=stringValue; + } + + public static State fromInt(int value) { + + for (int i=0; i Date: Wed, 5 Sep 2012 16:34:27 +0200 Subject: [PATCH 13/51] fix ice mode with srtp --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index 716ac0178..3d41a5c30 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 716ac0178612a7416c828fd74261e4dda44930de +Subproject commit 3d41a5c307868cb2898d4fee24ad575c565b1ae9 From 1b4e6a2a693936d5561ceecf0b1cfddf73117bbf Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 6 Sep 2012 14:34:58 +0200 Subject: [PATCH 14/51] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 18a6f4d86..0e62557bf 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 18a6f4d8629593125cc7b707f5fdad1462b2dcd9 +Subproject commit 0e62557bfedcb090b10c81697a41d6f1b3a85e1e diff --git a/oRTP b/oRTP index 3d41a5c30..efe109e84 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 3d41a5c307868cb2898d4fee24ad575c565b1ae9 +Subproject commit efe109e844b4049b5184d1246a42d83260529b94 From 180327c15fef603c8f2edff46ffe4cd61f199364 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 7 Sep 2012 08:56:47 +0200 Subject: [PATCH 15/51] Calculate ICE gathering time to adapt call params on edge network. --- coreapi/linphonecall.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 9192a84b7..da2a461e0 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1781,10 +1781,15 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ break; } } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) { + int ping_time = -1; if (evd->info.ice_processing_successful==TRUE) { ice_session_compute_candidates_foundations(call->ice_session); ice_session_eliminate_redundant_candidates(call->ice_session); ice_session_choose_default_candidates(call->ice_session); + ping_time = ice_session_gathering_duration(call->ice_session); + if (ping_time >=0) { + ping_time /= ice_session_nb_check_lists(call->ice_session); + } } else { ms_warning("No STUN answer from [%s], disabling ICE",linphone_core_get_stun_server(call->core)); linphone_call_delete_ice_session(call); @@ -1797,10 +1802,16 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ linphone_core_start_accept_call_update(call->core, call); break; case LinphoneCallOutgoingInit: + if (ping_time >= 0) { + linphone_core_adapt_to_network(call->core, ping_time, &call->params); + } linphone_call_stop_media_streams(call); linphone_core_proceed_with_invite_if_ready(call->core, call, NULL); break; default: + if (ping_time >= 0) { + linphone_core_adapt_to_network(call->core, ping_time, &call->params); + } linphone_call_stop_media_streams(call); linphone_core_notify_incoming_call(call->core, call); break; From 5d93e79c71ef1bb6912b6e98ec60a51e0a5e89e9 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 7 Sep 2012 09:08:18 +0200 Subject: [PATCH 16/51] Update ms2 and oRTP submodules for ICE gathering duration calculation. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 0e62557bf..3078bac7e 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0e62557bfedcb090b10c81697a41d6f1b3a85e1e +Subproject commit 3078bac7ee1a234900b152f1f21aceb0f6a55645 diff --git a/oRTP b/oRTP index efe109e84..fe897fd4c 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit efe109e844b4049b5184d1246a42d83260529b94 +Subproject commit fe897fd4c6d96a211b3a4ae4f9005b03144d1a66 From 62ce92ff69c6920bbd71c4b4276fd5b4a843b3d2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 7 Sep 2012 11:11:18 +0200 Subject: [PATCH 17/51] Exposed setContactParameters method in JNI --- coreapi/linphonecore_jni.cc | 5 +++++ java/common/org/linphone/core/LinphoneProxyConfig.java | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 194626111..f27ad0270 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -955,6 +955,11 @@ extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_getProxy(JNIEn return NULL; } } +extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setContactParameters(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jparams) { + const char* params = env->GetStringUTFChars(jparams, NULL); + linphone_proxy_config_set_contact_parameters((LinphoneProxyConfig*)proxyCfg, params); + env->ReleaseStringUTFChars(jparams, params); +} extern "C" int Java_org_linphone_core_LinphoneProxyConfigImpl_setRoute(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jroute) { if (jroute != NULL) { const char* route = env->GetStringUTFChars(jroute, NULL); diff --git a/java/common/org/linphone/core/LinphoneProxyConfig.java b/java/common/org/linphone/core/LinphoneProxyConfig.java index 666fa75a4..bf2907d26 100644 --- a/java/common/org/linphone/core/LinphoneProxyConfig.java +++ b/java/common/org/linphone/core/LinphoneProxyConfig.java @@ -133,4 +133,10 @@ public interface LinphoneProxyConfig { * @param delay expiration time in seconds */ void setExpires(int delay); + + /** + * Sets parameters for the contact + * @param parameters to add + */ + public void setContactParameters(String params); } From f815b0d5aaec61743302a1a5c48f62abe8224948 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 7 Sep 2012 13:04:27 +0200 Subject: [PATCH 18/51] remove adherence from Sal to liblinphone, improve notification of failed messageso --- coreapi/callbacks.c | 25 ++++++++++++++++++++++++- coreapi/chat.c | 6 ++++-- coreapi/private.h | 2 +- coreapi/sal.h | 8 ++++++++ coreapi/sal_eXosip2.c | 35 ++++++++++++++++++----------------- gtk/chat.c | 8 +++++++- 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 161aaab24..cd20cf6b9 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -801,6 +801,28 @@ static void notify_refer(SalOp *op, SalReferStatus status){ } } +static LinphoneChatMessageState chatStatusSal2Linphone(SalTextDeliveryStatus status){ + switch(status){ + case SalTextDeliveryInProgress: + return LinphoneChatMessageStateInProgress; + case SalTextDeliveryDone: + return LinphoneChatMessageStateDelivered; + case SalTextDeliveryFailed: + return LinphoneChatMessageStateNotDelivered; + } + return LinphoneChatMessageStateIdle; +} + +static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){ + LinphoneChatMessage *chat_msg=(LinphoneChatMessage* )sal_op_get_user_pointer(op); + if (chat_msg && chat_msg->cb) { + chat_msg->cb(chat_msg + ,chatStatusSal2Linphone(status) + ,chat_msg->cb_ud); + } + linphone_chat_message_destroy(chat_msg); +} + SalCallbacks linphone_sal_callbacks={ call_received, call_ringing, @@ -818,12 +840,13 @@ SalCallbacks linphone_sal_callbacks={ dtmf_received, refer_received, text_received, + text_delivery_update, notify, notify_presence, notify_refer, subscribe_received, subscribe_closed, - ping_reply + ping_reply, }; diff --git a/coreapi/chat.c b/coreapi/chat.c index 3d336dbcd..758293067 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -136,10 +136,12 @@ LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *c msg->message=ms_strdup(message); return msg; } + void linphone_chat_message_destroy(LinphoneChatMessage* msg) { - if (msg->message) ms_free((void*)msg->message); - ms_free((void*)msg); + if (msg->message) ms_free(msg->message); + ms_free(msg); } + void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangeCb status_cb,void* ud) { msg->cb=status_cb; msg->cb_ud=ud; diff --git a/coreapi/private.h b/coreapi/private.h index 2bf643d47..6affd1599 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -91,7 +91,7 @@ typedef struct _CallCallbackObj static const int linphone_call_magic=0x3343; struct _LinphoneChatMessage { - const char* message; + char* message; LinphoneChatRoom* chat_room; LinphoneChatMessageStateChangeCb cb; void* cb_ud; diff --git a/coreapi/sal.h b/coreapi/sal.h index 8faa11375..e12cdaf0c 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -253,6 +253,12 @@ typedef enum SalSubscribeStatus{ SalSubscribeTerminated }SalSubscribeStatus; +typedef enum SalTextDeliveryStatus{ + SalTextDeliveryInProgress, + SalTextDeliveryDone, + SalTextDeliveryFailed +}SalTextDeliveryStatus; + typedef void (*SalOnCallReceived)(SalOp *op); typedef void (*SalOnCallRinging)(SalOp *op); typedef void (*SalOnCallAccepted)(SalOp *op); @@ -269,6 +275,7 @@ typedef void (*SalOnVfuRequest)(SalOp *op); typedef void (*SalOnDtmfReceived)(SalOp *op, char dtmf); typedef void (*SalOnRefer)(Sal *sal, SalOp *op, const char *referto); typedef void (*SalOnTextReceived)(Sal *sal, const char *from, const char *msg); +typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus status); typedef void (*SalOnNotify)(SalOp *op, const char *from, const char *event); typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state); typedef void (*SalOnNotifyPresence)(SalOp *op, SalSubscribeStatus ss, SalPresenceStatus status, const char *msg); @@ -293,6 +300,7 @@ typedef struct SalCallbacks{ SalOnDtmfReceived dtmf_received; SalOnRefer refer_received; SalOnTextReceived text_received; + SalOnTextDeliveryUpdate text_delivery_update; SalOnNotify notify; SalOnNotifyPresence notify_presence; SalOnNotifyRefer notify_refer; diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 447ce34eb..d3ce16929 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #include "sal_eXosip2.h" -#include "private.h" #include "offeranswer.h" #ifdef ANDROID @@ -98,12 +97,12 @@ static void sal_remove_register(Sal *sal, int rid){ } } -static SalOp * sal_find_other(Sal *sal, osip_message_t *response){ +static SalOp * sal_find_other(Sal *sal, osip_message_t *message){ const MSList *elem; SalOp *op; - osip_call_id_t *callid=osip_message_get_call_id(response); + osip_call_id_t *callid=osip_message_get_call_id(message); if (callid==NULL) { - ms_error("There is no call-id in this response !"); + ms_error("There is no call-id in this message !"); return NULL; } for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){ @@ -931,9 +930,9 @@ void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){ } void sal_op_cancel_authentication(SalOp *h) { if (h->rid >0) { - sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure")); + sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure"); } else if (h->cid >0) { - sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"),0); + sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0); } else { ms_warning("Auth failure not handled"); } @@ -999,6 +998,7 @@ static SalOp *find_op(Sal *sal, eXosip_event_t *ev){ return sal_find_in_subscribe(sal,ev->nid); } if (ev->response) return sal_find_other(sal,ev->response); + else if (ev->request) return sal_find_other(sal,ev->request); return NULL; } @@ -1953,7 +1953,6 @@ static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){ static void other_request_reply(Sal *sal,eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); - LinphoneChatMessage* chat_msg; if (op==NULL){ ms_warning("other_request_reply(): Receiving response to unknown request."); return; @@ -1963,16 +1962,18 @@ static void other_request_reply(Sal *sal,eXosip_event_t *ev){ update_contact_from_response(op,ev->response); if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0) sal->callbacks.ping_reply(op); - else if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) { - /*out of call message acknolegment*/ - chat_msg=(LinphoneChatMessage* )op->base.user_pointer; - if (chat_msg->cb) { - chat_msg->cb(chat_msg - ,(ev->response->status_code==200?LinphoneChatMessageStateDelivered:LinphoneChatMessageStateNotDelivered) - ,chat_msg->cb_ud); + } + if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) { + /*out of call message acknolegment*/ + SalTextDeliveryStatus status=SalTextDeliveryFailed; + if (ev->response){ + if (ev->response->status_code<200){ + status=SalTextDeliveryInProgress; + }else if (ev->response->status_code<300 && ev->response->status_code>=200){ + status=SalTextDeliveryDone; } - linphone_chat_message_destroy(chat_msg); } + sal->callbacks.text_delivery_update(op,status); } } @@ -2081,8 +2082,8 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){ if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){ return process_authentication(sal,ev); } - case EXOSIP_SUBSCRIPTION_SERVERFAILURE: - case EXOSIP_SUBSCRIPTION_GLOBALFAILURE: + case EXOSIP_SUBSCRIPTION_SERVERFAILURE: + case EXOSIP_SUBSCRIPTION_GLOBALFAILURE: sal_exosip_subscription_closed(sal,ev); break; case EXOSIP_REGISTRATION_FAILURE: diff --git a/gtk/chat.c b/gtk/chat.c index 4138f6722..cb866a92f 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -90,6 +90,10 @@ const char* linphone_gtk_get_used_identity(){ else return linphone_core_get_primary_contact(lc); } +static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *user_pointer){ + g_message("chat message state is %s",linphone_chat_message_state_to_string(state)); +} + void linphone_gtk_send_text(GtkWidget *button){ GtkWidget *w=gtk_widget_get_toplevel(button); GtkWidget *entry=linphone_gtk_get_widget(w,"text_entry"); @@ -97,10 +101,12 @@ void linphone_gtk_send_text(GtkWidget *button){ const gchar *entered; entered=gtk_entry_get_text(GTK_ENTRY(entry)); if (strlen(entered)>0) { + LinphoneChatMessage *msg; linphone_gtk_push_text(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog")), linphone_gtk_get_used_identity(), entered,TRUE); - linphone_chat_room_send_message(cr,entered); + msg=linphone_chat_room_create_message(cr,entered); + linphone_chat_room_send_message2(cr,msg,on_chat_state_changed,NULL); gtk_entry_set_text(GTK_ENTRY(entry),""); } } From 2c7cc3a261764fa65a31d177cba6c31b7ae249fd Mon Sep 17 00:00:00 2001 From: Margaux Clerc Date: Mon, 10 Sep 2012 11:12:53 +0200 Subject: [PATCH 19/51] implement chat notification on Linux --- gtk/chat.c | 14 ++++++++++++-- gtk/linphone.h | 1 + gtk/main.c | 4 +++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gtk/chat.c b/gtk/chat.c index cb866a92f..aa1e7dff6 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -112,14 +112,24 @@ void linphone_gtk_send_text(GtkWidget *button){ } void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message){ - GtkWidget *w=(GtkWidget*)linphone_chat_room_get_user_data(room); + GtkWidget *w=(GtkWidget*)linphone_chat_room_get_user_data(room); if (w==NULL){ w=linphone_gtk_init_chatroom(room,linphone_address_as_string_uri_only(from)); + g_object_set_data(G_OBJECT(w),"is_notified",GINT_TO_POINTER(FALSE)); } #ifdef HAVE_GTK_OSX - /* Notify when a new message is send */ + /* Notified when a new message is sent */ linphone_gtk_status_icon_set_blinking(TRUE); + #else + if (!gtk_window_is_active((GtkWindow*)w)){ + if(!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_notified"))){ + linphone_gtk_notify(NULL,message); + g_object_set_data(G_OBJECT(w),"is_notified",GINT_TO_POINTER(TRUE)); + } + } else { + g_object_set_data(G_OBJECT(w),"is_notified",GINT_TO_POINTER(FALSE)); + } #endif linphone_gtk_push_text(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog")), diff --git a/gtk/linphone.h b/gtk/linphone.h index f817969f7..97a4400c7 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -98,6 +98,7 @@ void * linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, c void linphone_gtk_show_directory_search(void); void linphone_gtk_status_icon_set_blinking(gboolean val); +void linphone_gtk_notify(LinphoneCall *call, const char *msg); /*functions controlling the different views*/ gboolean linphone_gtk_use_in_call_view(); diff --git a/gtk/main.c b/gtk/main.c index 2085e3d20..193803256 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1029,18 +1029,20 @@ static void make_notification(const char *title, const char *body){ #endif -static void linphone_gtk_notify(LinphoneCall *call, const char *msg){ +void linphone_gtk_notify(LinphoneCall *call, const char *msg){ #ifdef HAVE_NOTIFY if (!notify_is_initted()) if (!notify_init ("Linphone")) ms_error("Libnotify failed to init."); #endif if (!call) { + #ifdef HAVE_NOTIFY if (!notify_notification_show(notify_notification_new("Linphone",msg,NULL #ifdef HAVE_NOTIFY1 ,NULL #endif ),NULL)) + ms_error("Failed to send notification."); #else linphone_gtk_show_main_window(); From 1d4943a5ab805daeca6c73a161d6df1035160aef Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 10 Sep 2012 14:21:05 +0200 Subject: [PATCH 20/51] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 3078bac7e..5003efb68 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3078bac7ee1a234900b152f1f21aceb0f6a55645 +Subproject commit 5003efb6866d0482680a49a5101258d3aa5ebaba diff --git a/oRTP b/oRTP index fe897fd4c..cf067f6e6 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit fe897fd4c6d96a211b3a4ae4f9005b03144d1a66 +Subproject commit cf067f6e6f7509cd2576a4ac4e89b47ab9296495 From c8be820dad8cba85af0521043e88d649a31af236 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 10 Sep 2012 14:21:41 +0200 Subject: [PATCH 21/51] Link with the two splitted mediastreamer2 libraries. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index eae637b84..6e68f7ba1 100644 --- a/configure.ac +++ b/configure.ac @@ -502,7 +502,7 @@ AS_CASE($enable_external_mediastreamer, AC_CONFIG_SUBDIRS( mediastreamer2 ) MEDIASTREAMER_DIR=${top_srcdir}/mediastreamer2 MEDIASTREAMER_CFLAGS="-I\$(top_srcdir)/mediastreamer2/include" - MEDIASTREAMER_LIBS="\$(top_builddir)/mediastreamer2/src/libmediastreamer.la" + MEDIASTREAMER_LIBS="\$(top_builddir)/mediastreamer2/src/libmediastreamer_base.la \$(top_builddir)/mediastreamer2/src/libmediastreamer_voip.la" dnl need to temporary change quotes to allow square brackets changequote(<<, >>) MS2_VERSION=`grep -e '^.C_INIT(' $MEDIASTREAMER_DIR/configure.ac | sed -e 's:\([^(]\+\)(\[mediastreamer\],\[\(.*\)\]):\2:g'` From e4505317065b76a89665bd1bf07a66ee3972d771 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 10 Sep 2012 16:14:29 +0200 Subject: [PATCH 22/51] save contact parameters --- coreapi/proxy.c | 5 +++++ oRTP | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 47fe08bdd..ba9c0d752 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -740,6 +740,9 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC if (obj->reg_identity!=NULL){ lp_config_set_string(config,key,"reg_identity",obj->reg_identity); } + if (obj->contact_params!=NULL){ + lp_config_set_string(config,key,"contact_params",obj->contact_params); + } lp_config_set_int(config,key,"reg_expires",obj->expires); lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister); lp_config_set_int(config,key,"publish",obj->publish); @@ -774,6 +777,8 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config tmp=lp_config_get_string(config,key,"reg_route",NULL); if (tmp!=NULL) linphone_proxy_config_set_route(cfg,tmp); + linphone_proxy_config_set_contact_parameters(cfg,lp_config_get_string(config,key,"contact_parameters",NULL)); + linphone_proxy_config_expires(cfg,lp_config_get_int(config,key,"reg_expires",DEFAULT_INT(config,reg_expires,600))); linphone_proxy_config_enableregister(cfg,lp_config_get_int(config,key,"reg_sendregister",0)); diff --git a/oRTP b/oRTP index cf067f6e6..385f742c5 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit cf067f6e6f7509cd2576a4ac4e89b47ab9296495 +Subproject commit 385f742c579e443862ee30cfbcd691a0a6a5e145 From 5501bf70155a9f073abee16e30391d60242e8c64 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 10 Sep 2012 17:20:27 +0200 Subject: [PATCH 23/51] Update ms2. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 5003efb68..e110f7668 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 5003efb6866d0482680a49a5101258d3aa5ebaba +Subproject commit e110f7668c8d4afa52cf15a372e35cd996f72053 From c5f1290f25bf45a3871a02385af0fd6afeafba44 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 10 Sep 2012 21:25:21 +0200 Subject: [PATCH 24/51] fix config storage for ptimes (was not consistent) --- coreapi/linphonecall.c | 2 +- coreapi/linphonecore.c | 4 ++-- coreapi/private.h | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index da2a461e0..41b39cb8b 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -223,7 +223,7 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li if (call->params.down_ptime) md->streams[0].ptime=call->params.down_ptime; else - md->streams[0].ptime=lc->net_conf.down_ptime; + md->streams[0].ptime=linphone_core_get_download_ptime(lc); l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw,&md->streams[0].max_rate); pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event")); l=ms_list_append(l,pt); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index e4f35e387..f8a33de57 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -967,14 +967,14 @@ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){ * Set audio packetization time linphone expects to receive from peer */ void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) { - lc->net_conf.down_ptime=ptime; + lp_config_set_int(lc->config,"rtp","download_ptime",ptime); } /** * Get audio packetization time linphone expects to receive from peer */ int linphone_core_get_download_ptime(LinphoneCore *lc) { - return lc->net_conf.down_ptime; + return lp_config_get_int(lc->config,"rtp","download_ptime",0); } /** diff --git a/coreapi/private.h b/coreapi/private.h index 6affd1599..7fbc6d8cb 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -409,7 +409,6 @@ typedef struct net_config int upload_bw; int firewall_policy; int mtu; - int down_ptime; bool_t nat_sdp_only; }net_config_t; From 3e7882dabf2b486f60d5e0516c50ce195ebd0ac5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 11 Sep 2012 11:05:03 +0200 Subject: [PATCH 25/51] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index e110f7668..d52aa7726 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit e110f7668c8d4afa52cf15a372e35cd996f72053 +Subproject commit d52aa7726ce5d11ea31ebd538ec1903790bbcbb6 From 742476710838e2799f336174dda666b4362fe066 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 11 Sep 2012 15:01:41 +0200 Subject: [PATCH 26/51] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index d52aa7726..a26e2588b 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d52aa7726ce5d11ea31ebd538ec1903790bbcbb6 +Subproject commit a26e2588b64e6ad57da944f661758154c170250c diff --git a/oRTP b/oRTP index 385f742c5..4934d1de8 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 385f742c579e443862ee30cfbcd691a0a6a5e145 +Subproject commit 4934d1de87717914042bbed8445a33c192d9d1ef From 0eb64837704f796702869a5272ee80005cb1955d Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 11 Sep 2012 15:16:44 +0200 Subject: [PATCH 27/51] Update ms2. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index a26e2588b..c6f2baffe 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a26e2588b64e6ad57da944f661758154c170250c +Subproject commit c6f2baffe88cae29cd846b95269c37b736626fab From c9d11c06b497c52581bc6bc1e18d1aec3e3d133a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 12 Sep 2012 10:44:45 +0200 Subject: [PATCH 28/51] Add missing include. --- coreapi/sal_eXosip2_sdp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/sal_eXosip2_sdp.c b/coreapi/sal_eXosip2_sdp.c index 2b439c000..050a53a76 100644 --- a/coreapi/sal_eXosip2_sdp.c +++ b/coreapi/sal_eXosip2_sdp.c @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "ortp/port.h" #include "ortp/b64.h" #include "ortp/ortp_srtp.h" #include "sal.h" From ce2057ac43fd9833225a3cfa374dc700c6e905b3 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 12 Sep 2012 10:46:01 +0200 Subject: [PATCH 29/51] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index c6f2baffe..506462c5c 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit c6f2baffe88cae29cd846b95269c37b736626fab +Subproject commit 506462c5c2043c595fd85a02506a824aa56839d2 diff --git a/oRTP b/oRTP index 4934d1de8..409c83fb5 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 4934d1de87717914042bbed8445a33c192d9d1ef +Subproject commit 409c83fb5216a641062fdc4934c4b81cb6e00c96 From 55c123625840c0c5fcd120711b672e625ad40b1d Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 12 Sep 2012 11:37:05 +0200 Subject: [PATCH 30/51] Update ms2 and oRTP submodules one more time. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 506462c5c..85dee1377 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 506462c5c2043c595fd85a02506a824aa56839d2 +Subproject commit 85dee13777a3c62ec25d144b9fbd598c79495a48 diff --git a/oRTP b/oRTP index 409c83fb5..6a31e56e1 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 409c83fb5216a641062fdc4934c4b81cb6e00c96 +Subproject commit 6a31e56e1f32f8ca82592e1f4301cd799a9751ea From 76c56b7eb717c41b822ef4aca8f84b2cf0ea5832 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 12 Sep 2012 16:35:30 +0200 Subject: [PATCH 31/51] callback notif text delivered JNI --- coreapi/chat.c | 9 ++- coreapi/linphonecore.h | 3 +- coreapi/linphonecore_jni.cc | 59 ++++++++++++++++++- .../linphone/core/LinphoneChatMessage.java | 9 +++ .../org/linphone/core/LinphoneChatRoom.java | 10 +++- 5 files changed, 85 insertions(+), 5 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 758293067..ddc3f5bfc 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -119,6 +119,13 @@ void linphone_core_text_received(LinphoneCore *lc, const char *from, const char ms_free(cleanfrom); } +LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr){ + return cr->lc; +} + +LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg){ + return msg->chat_room; +} void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud){ cr->user_data=ud; @@ -169,4 +176,4 @@ void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void* ud) */ void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message) { return message->message_userdata; -} \ No newline at end of file +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 7a1d27f09..da55604d1 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -669,7 +669,8 @@ typedef void (*LinphoneChatMessageStateChangeCb)(LinphoneChatMessage* msg,Linpho * @param ud user data for the status cb. */ void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangeCb status_cb,void* ud); - +LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr); +LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg); void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud); void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index f27ad0270..9d30dc33d 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -132,6 +132,9 @@ public: callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State")); callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;"); + chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State")); + chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); + /*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/ callEncryptionChangedId=env->GetMethodID(listenerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); @@ -176,6 +179,7 @@ public: env->DeleteGlobalRef(globalStateClass); env->DeleteGlobalRef(registrationStateClass); env->DeleteGlobalRef(callStateClass); + env->DeleteGlobalRef(chatMessageStateClass); env->DeleteGlobalRef(proxyClass); env->DeleteGlobalRef(callClass); env->DeleteGlobalRef(chatRoomClass); @@ -204,6 +208,9 @@ public: jmethodID callStateId; jmethodID callStateFromIntId; + jclass chatMessageStateClass; + jmethodID chatMessageStateFromIntId; + jmethodID callEncryptionChangedId; jclass ecCalibratorStatusClass; @@ -1358,16 +1365,64 @@ extern "C" long Java_org_linphone_core_LinphoneChatRoomImpl_getPeerAddress(JNIEn ,jlong ptr) { return (long) linphone_chat_room_get_peer_address((LinphoneChatRoom*)ptr); } +extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatMessage(JNIEnv* env + ,jobject thiz + ,jlong ptr + ,jstring jmessage) { + const char* message = env->GetStringUTFChars(jmessage, NULL); + LinphoneChatMessage *chatMessage = linphone_chat_room_create_message((LinphoneChatRoom *)ptr, message); + env->ReleaseStringUTFChars(jmessage, message); + + return (jlong) chatMessage; +} +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setUserData(JNIEnv* env + ,jobject thiz + ,jlong ptr + ) { + jobject ud = env->NewGlobalRef(thiz); + linphone_chat_message_set_user_data((LinphoneChatMessage*)ptr,(void*) ud); +} extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv* env ,jobject thiz ,jlong ptr ,jstring jmessage) { const char* message = env->GetStringUTFChars(jmessage, NULL); - linphone_chat_room_send_message((LinphoneChatRoom*)ptr,message); + linphone_chat_room_send_message((LinphoneChatRoom*)ptr, message); env->ReleaseStringUTFChars(jmessage, message); - } +static void chat_room_impl_callback(LinphoneChatMessage* msg, LinphoneChatMessageState state, void* ud) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + jobject listener = (jobject) ud; + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V"); + + LinphoneCore *lc = linphone_chat_room_get_lc(linphone_chat_message_get_chat_room(msg)); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); + env->CallVoidMethod( + listener, + method, + (jobject)linphone_chat_message_get_user_data(msg), + env->CallStaticObjectMethod(lcData->chatMessageStateClass,lcData->chatMessageStateFromIntId,(jint)state)); + + if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { + env->DeleteGlobalRef(listener); + } +} +extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage2(JNIEnv* env + ,jobject thiz + ,jlong ptr + ,jlong jmessage + ,jobject jlistener) { + jobject listener = env->NewGlobalRef(jlistener); + linphone_chat_room_send_message2((LinphoneChatRoom*)ptr, (LinphoneChatMessage*)jmessage, chat_room_impl_callback, (void*)listener); +} extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* env ,jobject thiz ,jlong lc diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index 77238d270..5e107619f 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -8,6 +8,7 @@ public interface LinphoneChatMessage { void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state); } static class State { + @SuppressWarnings("rawtypes") static private Vector values = new Vector(); private final int mValue; public final int value() {return mValue;} @@ -30,6 +31,7 @@ public interface LinphoneChatMessage { */ public final static State NotDelivered = new State(3,"NotDelivered"); + @SuppressWarnings("unchecked") private State(int value,String stringValue) { mValue = value; values.addElement(this); @@ -47,7 +49,14 @@ public interface LinphoneChatMessage { public String toString() { return mStringValue; } + public int toInt() { + return mValue; + } } + + long getNativePtr(); + Object getUserData(); + void setUserData(); } diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index 8c85b64bc..102a03c21 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -39,11 +39,19 @@ public interface LinphoneChatRoom { * Send a message to peer member of this chat room. * @param chat message */ - void sendMessage(LinphoneChatMessage msg, LinphoneChatMessage.StateListener listener); + void sendMessage(LinphoneChatMessage message, LinphoneChatMessage.StateListener listener); /** * DEPRECATED * @param opaque * @param message */ void sendMessage(Object opaque, String message); + + /** + * Create a LinphoneChatMessage + * @param chatRoom chat room associated to the message + * @param message message to send + * @return LinphoneChatMessage object + */ + LinphoneChatMessage createLinphoneChatMessage(String message); } From 328c83b51c47cde5f4fec74e2556194097ed22d4 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 12 Sep 2012 16:45:59 +0200 Subject: [PATCH 32/51] GetMessage method for linphoneChatMessage --- coreapi/chat.c | 5 +++++ coreapi/linphonecore.h | 1 + coreapi/linphonecore_jni.cc | 9 +++++++-- java/common/org/linphone/core/LinphoneChatMessage.java | 2 ++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index ddc3f5bfc..72cb42ce5 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -165,6 +165,11 @@ const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState } } + +char* linphone_chat_message_get_message(LinphoneChatMessage* msg) { + return msg->message; +} + /** * user pointer set function */ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index da55604d1..0fb87e9c7 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -671,6 +671,7 @@ typedef void (*LinphoneChatMessageStateChangeCb)(LinphoneChatMessage* msg,Linpho void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangeCb status_cb,void* ud); LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr); LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg); +char* linphone_chat_message_get_message(LinphoneChatMessage *msg); void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud); void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 9d30dc33d..57fd81e96 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1377,11 +1377,16 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatM } extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setUserData(JNIEnv* env ,jobject thiz - ,jlong ptr - ) { + ,jlong ptr) { jobject ud = env->NewGlobalRef(thiz); linphone_chat_message_set_user_data((LinphoneChatMessage*)ptr,(void*) ud); } +extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getMessage(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + jstring jvalue =env->NewStringUTF(linphone_chat_message_get_message((LinphoneChatMessage*)ptr)); + return jvalue; +} extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv* env ,jobject thiz ,jlong ptr diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index 5e107619f..31f8c122a 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -59,4 +59,6 @@ public interface LinphoneChatMessage { Object getUserData(); void setUserData(); + + String getMessage(); } From d74083cfaa2d757ab16588490c1844b090687f18 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 12 Sep 2012 16:56:12 +0200 Subject: [PATCH 33/51] GetPeerAdress added to LinphoneChatMessage --- coreapi/chat.c | 4 ++++ coreapi/linphonecore.h | 1 + coreapi/linphonecore_jni.cc | 5 +++++ .../org/linphone/core/LinphoneChatMessage.java | 12 ++++++++++++ 4 files changed, 22 insertions(+) diff --git a/coreapi/chat.c b/coreapi/chat.c index 72cb42ce5..cc36d7305 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -170,6 +170,10 @@ char* linphone_chat_message_get_message(LinphoneChatMessage* msg) { return msg->message; } +const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg) { + return linphone_chat_room_get_peer_address(msg->chat_room); +} + /** * user pointer set function */ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 0fb87e9c7..d4a0355b6 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -672,6 +672,7 @@ void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr); LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg); char* linphone_chat_message_get_message(LinphoneChatMessage *msg); +const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg); void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud); void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 57fd81e96..4d95af693 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1387,6 +1387,11 @@ extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getMessage(JNI jstring jvalue =env->NewStringUTF(linphone_chat_message_get_message((LinphoneChatMessage*)ptr)); return jvalue; } +extern "C" long Java_org_linphone_core_LinphoneChatMessageImpl_getPeerAddress(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + return (long) linphone_chat_message_get_peer_address((LinphoneChatMessage*)ptr); +} extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv* env ,jobject thiz ,jlong ptr diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index 31f8c122a..726a8690e 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -60,5 +60,17 @@ public interface LinphoneChatMessage { void setUserData(); + /** + * get text associated to this LinphoneChatMessage + * + * @return text sent along with the message + */ String getMessage(); + + /** + * get peer address associated to this LinphoneChatMessage + * + * @return LinphoneAddress peer address + */ + LinphoneAddress getPeerAddress(); } From e0249febe75b7a31c211ee28a534018bd9c3dfcd Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 12 Sep 2012 18:13:30 +0200 Subject: [PATCH 34/51] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 85dee1377..d0aa4891f 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 85dee13777a3c62ec25d144b9fbd598c79495a48 +Subproject commit d0aa4891f2a21f2a8f4171a213ad2c1faa83e25a From da4114607f0d080efb9bcee2fa0dbcc94a2f0d17 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 12 Sep 2012 21:17:29 +0200 Subject: [PATCH 35/51] Updated Android build, fixing LINPHONE_VIDEO=0 issue --- build/android/Android-no-neon.mk | 2 ++ build/android/Android.mk | 2 ++ 2 files changed, 4 insertions(+) diff --git a/build/android/Android-no-neon.mk b/build/android/Android-no-neon.mk index 3d72ffc55..d0c87b4f8 100644 --- a/build/android/Android-no-neon.mk +++ b/build/android/Android-no-neon.mk @@ -26,11 +26,13 @@ include $(CLEAR_VARS) include $(linphone-root-dir)/submodules/linphone/build/android/common.mk +ifeq ($(LINPHONE_VIDEO),1) LOCAL_SHARED_LIBRARIES += \ libavcodecnoneon \ libswscale \ libavcore \ libavutil +endif LOCAL_MODULE := liblinphonenoneon ifeq ($(TARGET_ARCH_ABI),armeabi) diff --git a/build/android/Android.mk b/build/android/Android.mk index 549367611..b46664b61 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -26,11 +26,13 @@ include $(CLEAR_VARS) include $(linphone-root-dir)/submodules/linphone/build/android/common.mk +ifeq ($(LINPHONE_VIDEO),1) LOCAL_SHARED_LIBRARIES += \ libavcodec \ libswscale \ libavcore \ libavutil +endif LOCAL_MODULE := liblinphone From c2e7592a2a349104ed2aa4121e1e4d44633a0908 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 12 Sep 2012 22:25:51 +0200 Subject: [PATCH 36/51] store playback gain as a float (not a char) --- coreapi/private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/private.h b/coreapi/private.h index 7fbc6d8cb..3042342d2 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -421,10 +421,10 @@ typedef struct sound_config struct _MSSndCard * lsd_card; /* dummy playback card for Linphone Sound Daemon extension */ const char **cards; int latency; /* latency in samples of the current used sound device */ + float soft_play_lev; /*playback gain in db.*/ char rec_lev; char play_lev; char ring_lev; - char soft_play_lev; char source; char *local_ring; char *remote_ring; From 7d2844a0c16f9c1505802d273f030016bb23226c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 13 Sep 2012 14:54:38 +0200 Subject: [PATCH 37/51] maximum time spent in linphone_core_refresh_registers for iOS. --- coreapi/sal_eXosip2.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index d3ce16929..695d8568d 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -2222,12 +2222,26 @@ int sal_register(SalOp *h, const char *proxy, const char *from, int expires){ int sal_register_refresh(SalOp *op, int expires){ osip_message_t *msg=NULL; const char *contact=sal_op_get_contact(op); - + int tries=0; + if (op->rid==-1){ ms_error("Unexistant registration context, not possible to refresh."); return -1; } +#ifdef HAVE_EXOSIP_TRYLOCK + /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever. + * In order to prevent this case that can occur when the exosip thread is busy with DNS while network isn't in a good shape, we try to take + * the exosip lock in a non blocking way, and give up if it takes too long*/ + while (eXosip_trylock()!=0){ + ms_usleep(100000); + if (tries>30) {/*after 3 seconds, give up*/ + ms_warning("Could not obtain exosip lock in a reasonable time, giving up."); + return -1; + } + } +#else eXosip_lock(); +#endif eXosip_register_build_register(op->rid,expires,&msg); if (msg!=NULL){ if (contact) register_set_contact(msg,contact); From cb0fe631e18ad86f37739afeef5c2d6c60231421 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 13 Sep 2012 15:16:48 +0200 Subject: [PATCH 38/51] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index d0aa4891f..84dfa4d69 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d0aa4891f2a21f2a8f4171a213ad2c1faa83e25a +Subproject commit 84dfa4d69e62c2545fc4ad30561c03a6a1ad2701 From 8004607607c344a0f1dd09d1854848fca0e52d59 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 13 Sep 2012 17:42:54 +0200 Subject: [PATCH 39/51] add support of external-body for SIP message --- coreapi/callbacks.c | 8 +++- coreapi/chat.c | 76 ++++++++++++++++++++++++++++++---- coreapi/linphonecore.h | 65 ++++++++++++++++++++++++++--- coreapi/private.h | 4 +- coreapi/sal.h | 3 ++ coreapi/sal_eXosip2.c | 33 ++++++++++++++- coreapi/sal_eXosip2_presence.c | 14 ++++--- 7 files changed, 179 insertions(+), 24 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index cd20cf6b9..14ca748e1 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -732,9 +732,12 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){ static void text_received(Sal *sal, const char *from, const char *msg){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); - linphone_core_text_received(lc,from,msg); + linphone_core_message_received(lc,from,msg,NULL); +} +void message_external_body_received(Sal *sal, const char *from, const char *url) { + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); + linphone_core_message_received(lc,from,NULL,url); } - static void notify(SalOp *op, const char *from, const char *msg){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer (op); @@ -840,6 +843,7 @@ SalCallbacks linphone_sal_callbacks={ dtmf_received, refer_received, text_received, + message_external_body_received, text_delivery_update, notify, notify_presence, diff --git a/coreapi/chat.c b/coreapi/chat.c index cc36d7305..941cce423 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -55,6 +55,7 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route); SalOp *op=NULL; LinphoneCall *call; + char* content_type; if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL){ if (call->state==LinphoneCallConnected || call->state==LinphoneCallStreamsRunning || @@ -77,7 +78,15 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM cr->op=op; sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/ } - sal_text_send(op,identity,cr->peer,msg->message); + if (msg->external_body_url) { + content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url); + sal_message_send(op,identity,cr->peer,content_type,NULL); + ms_free(content_type); + } else { + sal_text_send(op, identity, cr->peer, msg->message); + } + + } void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg) { @@ -89,16 +98,20 @@ bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *f return FALSE; } -void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, const LinphoneAddress *from, const char *msg){ - if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, from, msg); +void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc, LinphoneChatMessage *msg){ + if (msg->message) + //legacy API + if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, msg->from, msg->message); + if (lc->vtable.message_received!=NULL) lc->vtable.message_received(lc, cr,msg); + } -void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg){ +void linphone_core_message_received(LinphoneCore *lc, const char *from, const char *raw_msg,const char* external_url){ MSList *elem; LinphoneChatRoom *cr=NULL; LinphoneAddress *addr; char *cleanfrom; - + LinphoneChatMessage* msg; addr=linphone_address_new(from); linphone_address_clean(addr); for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){ @@ -113,9 +126,13 @@ void linphone_core_text_received(LinphoneCore *lc, const char *from, const char /* create a new chat room */ cr=linphone_core_create_chat_room(lc,cleanfrom); } - + msg = linphone_chat_room_create_message(cr, raw_msg); + linphone_chat_message_set_from(msg, cr->peer_url); + if (external_url) { + linphone_chat_message_set_external_body_url(msg, external_url); + } linphone_address_destroy(addr); - linphone_chat_room_text_received(cr,lc,cr->peer_url,msg); + linphone_chat_room_message_received(cr,lc,msg); ms_free(cleanfrom); } @@ -140,12 +157,14 @@ const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *cr,const char* message) { LinphoneChatMessage* msg = ms_new0(LinphoneChatMessage,1); msg->chat_room=(LinphoneChatRoom*)cr; - msg->message=ms_strdup(message); + msg->message=message?ms_strdup(message):NULL; return msg; } void linphone_chat_message_destroy(LinphoneChatMessage* msg) { if (msg->message) ms_free(msg->message); + if (msg->external_body_url) ms_free(msg->external_body_url); + if (msg->from) linphone_address_destroy(msg->from); ms_free(msg); } @@ -186,3 +205,44 @@ void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void* ud) void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message) { return message->message_userdata; } + +const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message) { + return message->external_body_url; +} + +void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url) { + if (message->external_body_url) { + ms_free(message->external_body_url); + } + message->external_body_url=url?ms_strdup(url):NULL; +} +void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from) { + if(message->from) linphone_address_destroy(message->from); + message->from=linphone_address_clone(from); + +} +LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message) { + return message->from; +} +const char * linphone_chat_message_get_text(const LinphoneChatMessage* message) { + return message->message; +} +LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg) { + /*struct _LinphoneChatMessage { + char* message; + LinphoneChatRoom* chat_room; + LinphoneChatMessageStateChangeCb cb; + void* cb_ud; + void* message_userdata; + char* external_body_url; + LinphoneAddress* from; + };*/ + LinphoneChatMessage* new_message = linphone_chat_room_create_message(msg->chat_room,msg->message); + if (msg->external_body_url) new_message->external_body_url=ms_strdup(msg->external_body_url); + new_message->cb=msg->cb; + new_message->cb_ud=msg->cb_ud; + new_message->message_userdata=msg->message_userdata; + new_message->cb=msg->cb; + if (msg->from) new_message->from=linphone_address_clone(msg->from); + return new_message; +} \ No newline at end of file diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index d4a0355b6..009648be3 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -617,7 +617,6 @@ void linphone_chat_room_destroy(LinphoneChatRoom *cr); */ LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *cr,const char* message); - /** * get peer address \link linphone_core_create_chat_room() associated to \endlink this #LinphoneChatRoom @@ -641,18 +640,61 @@ typedef enum _LinphoneChatMessageStates { LinphoneChatMessageStateNotDelivered /** message was not delivered*/ }LinphoneChatMessageState; + /** * to string function */ const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state); + +/** + * clone a chat message + *@param message #LinphoneChatMessage obj + *@return #LinphoneChatMessage + */ +LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message); +/** + * set origine of the message + *@param message #LinphoneChatMessage obj + *@param from #LinphoneAddress origin of this message (copied) + */ +void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from); + +/** + * get origine of the message + *@param message #LinphoneChatMessage obj + *@return #LinphoneAddress + */ +LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message); + +/** + * Linphone message can carry external body as defined by rfc2017 + * @param message #LinphoneChatMessage + * @return return external body url null if not present. + */ +const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message); + +/** + * Linphone message can carry external body as defined by rfc2017 + * + * @param #LinphoneChatMessage + * @param url ex: access-type=URL; URL="http://www.foo.com/file" + */ +void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url); + +/** + * get text part of this message + *@return text or NULL if no text. + */ +const char * linphone_chat_message_get_text(const LinphoneChatMessage* message); +/** + * user pointer get function + */ + +void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message); /** * user pointer set function */ void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*); -/** - * user pointer get function - */ -void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message); /** * Call back used to notify message delivery status @@ -744,6 +786,7 @@ typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, c typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl); /** * Callback prototype + * @deprecated use #MessageReceived instead. * * @param lc #LinphoneCore object * @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room. @@ -751,6 +794,15 @@ typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog * @param message incoming message * */ typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message); +/** + * Chat message callback prototype + * + * @param lc #LinphoneCore object + * @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room. + * @param LinphoneChatMessage incoming message + * */ +typedef void (*MessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message); + /** Callback prototype */ typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf); /** Callback prototype */ @@ -774,7 +826,8 @@ typedef struct _LinphoneVTable{ NewSubscribtionRequestCb new_subscription_request; /**< Notify about pending subscription request */ AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */ CallLogUpdated call_log_updated; /**< Notifies that call log list has been updated */ - TextMessageReceived text_received; /**< A text message has been received */ + TextMessageReceived text_received; /** @deprecated, use #message_received instead
A text message has been received */ + MessageReceived message_received; /** a message is received, can be text or external body*/ DtmfReceived dtmf_received; /**< A dtmf has been received received */ ReferReceived refer_received; /**< An out of call refer was received */ CallEncryptionChangedCb call_encryption_changed; /**callbacks.text_received=(SalOnTextReceived)unimplemented_stub; if (ctx->callbacks.ping_reply==NULL) ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub; + if (ctx->callbacks.message_external_body==NULL) + ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub; } int sal_unlisten_ports(Sal *ctx){ @@ -1701,15 +1703,44 @@ static bool_t comes_from_local_if(osip_message_t *msg){ static void text_received(Sal *sal, eXosip_event_t *ev){ osip_body_t *body=NULL; char *from=NULL,*msg; + osip_content_type_t* content_type; + osip_uri_param_t* external_body_url; + char unquoted_external_body_url [256]; + int external_body_size=0; + content_type= osip_message_get_content_type(ev->request); + if (!content_type) { + ms_error("Could not get message because no content type"); + return; + } + osip_from_to_str(ev->request->from,&from); + if (content_type->type + && strcmp(content_type->type, "text")==0 + && content_type->subtype + && strcmp(content_type->subtype, "plain")==0 ) { osip_message_get_body(ev->request,0,&body); if (body==NULL){ ms_error("Could not get text message from SIP body"); return; } msg=body->body; - osip_from_to_str(ev->request->from,&from); sal->callbacks.text_received(sal,from,msg); + } if (content_type->type + && strcmp(content_type->type, "message")==0 + && content_type->subtype + && strcmp(content_type->subtype, "external-body")==0 ) { + + osip_content_type_param_get_byname(content_type, "URL", &external_body_url); + /*remove both first and last character*/ + strncpy(unquoted_external_body_url + ,&external_body_url->gvalue[1] + ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url))); + unquoted_external_body_url[external_body_size-1]='\0'; + sal->callbacks.message_external_body(sal,from,unquoted_external_body_url); + + } else { + ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype); + } osip_free(from); } diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index f79866a0a..3559081db 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -81,7 +81,7 @@ void sal_remove_in_subscribe(Sal *sal, SalOp *op){ sal->in_subscribes=ms_list_remove(sal->in_subscribes,op); } -int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){ +int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){ osip_message_t *sip=NULL; if(op->cid == -1) @@ -97,8 +97,8 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){ eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op), sal_op_get_from(op),sal_op_get_route(op)); if (sip!=NULL){ - osip_message_set_content_type(sip,"text/plain"); - osip_message_set_body(sip,msg,strlen(msg)); + osip_message_set_content_type(sip,content_type); + if (msg) osip_message_set_body(sip,msg,strlen(msg)); sal_add_other(op->base.root,op,sip); eXosip_message_send_request(sip); }else{ @@ -118,14 +118,16 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){ eXosip_unlock(); return -1; } - osip_message_set_content_type(sip,"text/plain"); - osip_message_set_body(sip,msg,strlen(msg)); + osip_message_set_content_type(sip,content_type); + if (msg) osip_message_set_body(sip,msg,strlen(msg)); eXosip_call_send_request(op->did,sip); eXosip_unlock(); } return 0; } - +int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) { + return sal_message_send(op,from,to,"text/plain",msg); +} /*presence Subscribe/notify*/ int sal_subscribe_presence(SalOp *op, const char *from, const char *to){ osip_message_t *msg=NULL; From b1db37d06eb5167a3efe97ab273abdbdf33087e0 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 14 Sep 2012 09:59:27 +0200 Subject: [PATCH 40/51] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 84dfa4d69..a457709df 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 84dfa4d69e62c2545fc4ad30561c03a6a1ad2701 +Subproject commit a457709df8daa72544fc36283c0053c4f09d0249 diff --git a/oRTP b/oRTP index 6a31e56e1..cbe444a60 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 6a31e56e1f32f8ca82592e1f4301cd799a9751ea +Subproject commit cbe444a6098346311b412a5723190107e77d9c42 From 4d943c9bcc0c7739d51f19722c9754551d2ae3fe Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 14 Sep 2012 15:54:30 +0200 Subject: [PATCH 41/51] Updated JNI for LinphoneChatMessage --- coreapi/linphonecore_jni.cc | 38 +++++++++++++++++++ .../linphone/core/LinphoneChatMessage.java | 14 +++++++ .../linphone/core/LinphoneCoreListener.java | 11 +++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 4d95af693..224c26503 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -109,6 +109,7 @@ public: vTable.call_state_changed = callStateChange; vTable.call_encryption_changed = callEncryptionChange; vTable.text_received = text_received; + vTable.message_received = message_received; vTable.new_subscription_request = new_subscription_request; vTable.notify_presence_recv = notify_presence_recv; @@ -158,6 +159,9 @@ public: callClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCallImpl")); callCtrId = env->GetMethodID(callClass,"", "(J)V"); + chatMessageClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessageImpl")); + chatMessageCtrId = env->GetMethodID(chatMessageClass,"", "(J)V"); + chatRoomClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatRoomImpl")); chatRoomCtrId = env->GetMethodID(chatRoomClass,"", "(J)V"); @@ -182,6 +186,7 @@ public: env->DeleteGlobalRef(chatMessageStateClass); env->DeleteGlobalRef(proxyClass); env->DeleteGlobalRef(callClass); + env->DeleteGlobalRef(chatMessageClass); env->DeleteGlobalRef(chatRoomClass); env->DeleteGlobalRef(friendClass); @@ -195,6 +200,7 @@ public: jmethodID newSubscriptionRequestId; jmethodID notifyPresenceReceivedId; jmethodID textReceivedId; + jmethodID messageReceivedId; jclass globalStateClass; jmethodID globalStateId; @@ -223,6 +229,9 @@ public: jclass callClass; jmethodID callCtrId; + jclass chatMessageClass; + jmethodID chatMessageCtrId; + jclass chatRoomClass; jmethodID chatRoomCtrId; @@ -380,6 +389,21 @@ public: ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from) ,message ? env->NewStringUTF(message) : NULL); } + static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const LinphoneChatMessage *msg) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); + env->CallVoidMethod(lcData->listener + ,lcData->messageReceivedId + ,lcData->core + ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room) + ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from) + ,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg)); + } static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); @@ -1387,6 +1411,20 @@ extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getMessage(JNI jstring jvalue =env->NewStringUTF(linphone_chat_message_get_message((LinphoneChatMessage*)ptr)); return jvalue; } +extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getExternalBodyUrl(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + jstring jvalue =env->NewStringUTF(linphone_chat_message_get_external_body_url((LinphoneChatMessage*)ptr)); + return jvalue; +} +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setExternalBodyUrl(JNIEnv* env + ,jobject thiz + ,jlong ptr + ,jstring jurl) { + const char* url = env->GetStringUTFChars(jurl, NULL); + linphone_chat_message_set_external_body_url((LinphoneChatMessage *)ptr, url); + env->ReleaseStringUTFChars(jurl, url); +} extern "C" long Java_org_linphone_core_LinphoneChatMessageImpl_getPeerAddress(JNIEnv* env ,jobject thiz ,jlong ptr) { diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index 726a8690e..3b135fc65 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -73,4 +73,18 @@ public interface LinphoneChatMessage { * @return LinphoneAddress peer address */ LinphoneAddress getPeerAddress(); + + /** + * Linphone message can carry external body as defined by rfc2017 + * @param message #LinphoneChatMessage + * @return return external body url null if not present. + */ + String getExternalBodyUrl(); + + /** + * Linphone message can carry external body as defined by rfc2017 + * @param #LinphoneChatMessage + * @param url ex: access-type=URL; URL="http://www.foo.com/file" + */ + void setExternalBodyUrl(String url); } diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index 400e942c3..ab9dd1ac3 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -93,7 +93,16 @@ public interface LinphoneCoreListener { * @param from LinphoneAddress from * @param message incoming message */ - void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message); + void textReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneAddress from, String message); + + /** + * invoked when a new linphone chat message is received + * @param lc LinphoneCore + * @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room. + * @param from LinphoneAddress from + * @param message incoming linphone chat message message + */ + void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneAddress from, LinphoneChatMessage message); /** * Invoked when echo cancalation calibration is completed From 417d5d93e096c20ddf60da895682e412a779b572 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 14 Sep 2012 16:20:02 +0200 Subject: [PATCH 42/51] Fix JNI compil --- coreapi/linphonecore_jni.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 224c26503..440afcbc6 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -152,6 +152,7 @@ public: /*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/ textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); + messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Lorg/linphone/core/LinphoneChatMessage;)V"); proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); proxyCtrId = env->GetMethodID(proxyClass,"", "(J)V"); @@ -389,7 +390,7 @@ public: ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from) ,message ? env->NewStringUTF(message) : NULL); } - static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const LinphoneChatMessage *msg) { + static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); if (result != 0) { @@ -401,7 +402,7 @@ public: ,lcData->messageReceivedId ,lcData->core ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room) - ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from) + ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)msg->from) ,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg)); } static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) { From d676eb51df61e1b69c46980cc519ac63ba176e53 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 14 Sep 2012 17:38:18 +0200 Subject: [PATCH 43/51] implement dscp settings from config file and gtk interface --- coreapi/linphonecall.c | 4 +- coreapi/linphonecore.c | 72 +++++++++++++++++ coreapi/linphonecore.h | 9 +++ coreapi/lpconfig.c | 14 +++- coreapi/lpconfig.h | 8 ++ coreapi/sal.h | 1 + coreapi/sal_eXosip2.c | 8 ++ coreapi/sal_eXosip2.h | 1 + gtk/Makefile.am | 3 +- gtk/dscp_settings.ui | 178 +++++++++++++++++++++++++++++++++++++++++ gtk/parameters.ui | 93 +++++++++++++-------- gtk/propertybox.c | 52 ++++++++++++ 12 files changed, 407 insertions(+), 36 deletions(-) create mode 100644 gtk/dscp_settings.ui diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 41b39cb8b..5962badd3 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -974,7 +974,7 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; AudioStream *audiostream; - int dscp=lp_config_get_int(lc->config,"rtp","audio_dscp",-1); + int dscp=linphone_core_get_audio_dscp(lc); call->audiostream=audiostream=audio_stream_new(call->audio_port,call->audio_port+1,linphone_core_ipv6_enabled(lc)); if (dscp!=-1) @@ -1028,7 +1028,7 @@ void linphone_call_init_video_stream(LinphoneCall *call){ if ((lc->video_conf.display || lc->video_conf.capture) && call->params.has_video){ int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0); - int dscp=lp_config_get_int(lc->config,"rtp","video_dscp",-1); + int dscp=linphone_core_get_video_dscp(lc); call->videostream=video_stream_new(call->video_port,call->video_port+1,linphone_core_ipv6_enabled(lc)); if (dscp!=-1) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index f8a33de57..6d81d8b71 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -615,6 +615,7 @@ static void sip_config_read(LinphoneCore *lc) sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period); sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0)); sal_use_double_registrations(lc->sal,lp_config_get_int(lc->config,"sip","use_double_registrations",1)); + sal_set_dscp(lc->sal,linphone_core_get_sip_dscp(lc)); } static void rtp_config_read(LinphoneCore *lc) @@ -5112,3 +5113,74 @@ void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id) const char* linphone_core_get_device_identifier(const LinphoneCore *lc) { return lc->device_id; } + +/** + * Set the DSCP field for SIP signaling channel. + * + * @ingroup network_parameters + * * The DSCP defines the quality of service in IP packets. + * +**/ +void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp){ + sal_set_dscp(lc->sal,dscp); + if (linphone_core_ready(lc)) + lp_config_set_int_hex(lc->config,"sip","dscp",dscp); +} + +/** + * Get the DSCP field for SIP signaling channel. + * + * @ingroup network_parameters + * * The DSCP defines the quality of service in IP packets. + * +**/ +int linphone_core_get_sip_dscp(const LinphoneCore *lc){ + return lp_config_get_int(lc->config,"sip","dscp",0x1a); +} + +/** + * Set the DSCP field for outgoing audio streams. + * + * @ingroup network_parameters + * The DSCP defines the quality of service in IP packets. + * +**/ +void linphone_core_set_audio_dscp(LinphoneCore *lc, int dscp){ + if (linphone_core_ready(lc)) + lp_config_set_int_hex(lc->config,"rtp","audio_dscp",dscp); +} + +/** + * Get the DSCP field for outgoing audio streams. + * + * @ingroup network_parameters + * The DSCP defines the quality of service in IP packets. + * +**/ +int linphone_core_get_audio_dscp(const LinphoneCore *lc){ + return lp_config_get_int(lc->config,"rtp","audio_dscp",0x2e); +} + +/** + * Set the DSCP field for outgoing video streams. + * + * @ingroup network_parameters + * The DSCP defines the quality of service in IP packets. + * +**/ +void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp){ + if (linphone_core_ready(lc)) + lp_config_set_int_hex(lc->config,"rtp","video_dscp",dscp); + +} + +/** + * Get the DSCP field for outgoing video streams. + * + * @ingroup network_parameters + * The DSCP defines the quality of service in IP packets. + * +**/ +int linphone_core_get_video_dscp(const LinphoneCore *lc){ + return lp_config_get_int(lc->config,"rtp","video_dscp",0x2e); +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 009648be3..ef24f2c78 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1389,6 +1389,15 @@ LinphoneTunnel *linphone_core_get_tunnel(LinphoneCore *lc); void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy); +void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp); +int linphone_core_get_sip_dscp(const LinphoneCore *lc); + +void linphone_core_set_audio_dscp(LinphoneCore *lc, int dscp); +int linphone_core_get_audio_dscp(const LinphoneCore *lc); + +void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp); +int linphone_core_get_video_dscp(const LinphoneCore *lc); + #ifdef __cplusplus } #endif diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index 4cd7202cc..0efdc335e 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -273,7 +273,13 @@ const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value){ const char *str=lp_config_get_string(lpconfig,section,key,NULL); - if (str!=NULL) return atoi(str); + if (str!=NULL) { + int ret=0; + if (strstr(str,"0x")==str){ + sscanf(str,"%x",&ret); + }else ret=atoi(str); + return ret; + } else return default_value; } @@ -324,6 +330,12 @@ void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, lp_config_set_string(lpconfig,section,key,tmp); } +void lp_config_set_int_hex(LpConfig *lpconfig,const char *section, const char *key, int value){ + char tmp[30]; + snprintf(tmp,sizeof(tmp),"0x%x",value); + lp_config_set_string(lpconfig,section,key,tmp); +} + void lp_config_set_int64(LpConfig *lpconfig,const char *section, const char *key, int64_t value){ char tmp[30]; snprintf(tmp,sizeof(tmp),"%lli",(long long)value); diff --git a/coreapi/lpconfig.h b/coreapi/lpconfig.h index c1821d2aa..a27f7e39a 100644 --- a/coreapi/lpconfig.h +++ b/coreapi/lpconfig.h @@ -96,6 +96,14 @@ void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *ke * @ingroup misc **/ void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value); + +/** + * Sets an integer config item, but store it as hexadecimal + * + * @ingroup misc +**/ +void lp_config_set_int_hex(LpConfig *lpconfig,const char *section, const char *key, int value); + /** * Sets a 64 bits integer config item * diff --git a/coreapi/sal.h b/coreapi/sal.h index 9c3f6d61f..751cc6533 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -325,6 +325,7 @@ void sal_auth_info_delete(const SalAuthInfo* auth_info); 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); int sal_unlisten_ports(Sal *ctx); +void sal_set_dscp(Sal *ctx, int dscp); int sal_reset_transports(Sal *ctx); ortp_socket_t sal_get_socket(Sal *ctx); void sal_set_user_agent(Sal *ctx, const char *user_agent); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 30b0f286d..821e4ab39 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -283,6 +283,7 @@ Sal * sal_init(){ sal->rootCa = 0; sal->verify_server_certs=TRUE; sal->expire_old_contact=FALSE; + sal->dscp=-1; return sal; } @@ -380,6 +381,12 @@ static void set_tls_options(Sal *ctx){ #endif } +void sal_set_dscp(Sal *ctx, int dscp){ + ctx->dscp=dscp; + if (dscp!=-1) + eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp); +} + int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){ int err; bool_t ipv6; @@ -406,6 +413,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports); int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101); + sal_set_dscp(ctx,ctx->dscp); ipv6=strchr(addr,':')!=NULL; eXosip_enable_ipv6(ipv6); diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index ccc95d56a..71463854c 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -41,6 +41,7 @@ struct Sal{ int keepalive_period; void *up; /*user pointer*/ char* rootCa; /* File _or_ folder containing root CA */ + int dscp; bool_t one_matching_codec; bool_t double_reg; bool_t use_rports; diff --git a/gtk/Makefile.am b/gtk/Makefile.am index a4dceba61..ede08b900 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -9,7 +9,8 @@ UI_FILES= about.ui \ log.ui \ buddylookup.ui \ tunnel_config.ui \ - waiting.ui + waiting.ui \ + dscp_settings.ui PIXMAPS= \ stock_people.png diff --git a/gtk/dscp_settings.ui b/gtk/dscp_settings.ui new file mode 100644 index 000000000..4664768c6 --- /dev/null +++ b/gtk/dscp_settings.ui @@ -0,0 +1,178 @@ + + + + + + False + 5 + Dscp settings + True + dialog + + + + True + False + 2 + + + True + False + end + + + gtk-close + True + True + True + False + True + + + False + False + 0 + + + + + gtk-ok + True + True + True + False + True + + + False + False + 1 + + + + + False + True + end + 0 + + + + + True + False + 0 + none + + + True + False + 3 + 2 + True + + + True + True + + True + False + False + True + True + + + 1 + 2 + + + + + True + True + + True + False + False + True + True + + + 1 + 2 + 1 + 2 + + + + + True + True + + True + False + False + True + True + + + 1 + 2 + 2 + 3 + + + + + True + False + SIP + + + + + True + False + Audio RTP stream + + + 1 + 2 + + + + + True + False + Video RTP stream + + + 2 + 3 + + + + + + + True + False + <b>Set DSCP values (in hexadecimal)</b> + True + + + + + False + False + 1 + + + + + + button2 + button1 + + + diff --git a/gtk/parameters.ui b/gtk/parameters.ui index 9fc8538c0..7e76c385f 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -207,10 +207,10 @@ Set Maximum Transmission Unit: - False True True False + False True @@ -247,10 +247,10 @@ Send DTMFs as SIP info - False True True False + False True @@ -263,11 +263,11 @@ Use IPv6 instead of IPv4 - False True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -315,7 +315,7 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 + 6 2 @@ -377,23 +377,24 @@ Tunnel - 4 - 5 + 5 + 6 - edit - False + gtk-edit True True + False + True 1 2 - 4 - 5 + 5 + 6 @@ -462,6 +463,34 @@ 3 + + + True + False + DSCP fields + + + 4 + 5 + + + + + gtk-edit + True + True + True + False + True + + + + 1 + 2 + 4 + 5 + + @@ -496,10 +525,10 @@ Direct connection to the Internet - False True True False + False True True @@ -517,10 +546,10 @@ Behind NAT / Firewall (specify gateway IP below) - False True True False + False True True no_nat @@ -585,10 +614,10 @@ Behind NAT / Firewall (use STUN to resolve) - False True True False + False True no_nat @@ -602,10 +631,10 @@ Behind NAT / Firewall (use ICE) - False True True False + False True no_nat @@ -743,9 +772,6 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 6 2 - - - True @@ -767,11 +793,11 @@ gtk-media-play - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -944,10 +970,10 @@ Enable echo cancellation - False True True False + False True @@ -958,6 +984,9 @@ 6 + + + @@ -1293,10 +1322,10 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False True True True + False @@ -1340,11 +1369,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1388,11 +1417,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1436,11 +1465,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1484,9 +1513,9 @@ - False True True + False @@ -1573,11 +1602,11 @@ virtual network ! GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1759,11 +1788,11 @@ virtual network ! gtk-go-up - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -1776,11 +1805,11 @@ virtual network ! gtk-go-down - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -1792,11 +1821,11 @@ virtual network ! - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1840,11 +1869,11 @@ virtual network ! - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -2007,10 +2036,10 @@ virtual network ! Enable adaptive rate control - False True True False + False 0 True @@ -2162,10 +2191,10 @@ virtual network ! Show advanced settings - False True True False + False True @@ -2242,11 +2271,11 @@ virtual network ! end - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 6870e2786..31c76f93b 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -1131,3 +1131,55 @@ void linphone_gtk_tunnel_ok(GtkButton *button){ void linphone_gtk_tunnel_cancel(GtkButton *button){ } + +static void show_dscp(GtkWidget *entry, int val){ + char tmp[20]; + snprintf(tmp,sizeof(tmp),"0x%x",val); + gtk_entry_set_text(GTK_ENTRY(entry),tmp); + +} + +static int read_dscp(GtkWidget *entry){ + const char *val=gtk_entry_get_text(GTK_ENTRY(entry)); + const char *begin; + int ret=0; + if (val==NULL || val[0]=='\0') return 0; + /*skip potential 0x*/ + begin=strstr(val,"0x"); + if (begin) begin+=2; + else begin=val; + if (sscanf(begin,"%x",&ret)==1) + return ret; + return -1; +} + +void linphone_gtk_dscp_edit(){ + LinphoneCore *lc=linphone_gtk_get_core(); + GtkWidget *widget=linphone_gtk_create_window("dscp_settings"); + show_dscp(linphone_gtk_get_widget(widget,"sip_dscp"), + linphone_core_get_sip_dscp(lc)); + show_dscp(linphone_gtk_get_widget(widget,"audio_dscp"), + linphone_core_get_audio_dscp(lc)); + show_dscp(linphone_gtk_get_widget(widget,"video_dscp"), + linphone_core_get_video_dscp(lc)); + gtk_widget_show(widget); +} + +void linphone_gtk_dscp_edit_response(GtkWidget *dialog, guint response_id){ + LinphoneCore *lc=linphone_gtk_get_core(); + switch(response_id){ + case GTK_RESPONSE_OK: + linphone_core_set_sip_dscp(lc, + read_dscp(linphone_gtk_get_widget(dialog,"sip_dscp"))); + linphone_core_set_audio_dscp(lc, + read_dscp(linphone_gtk_get_widget(dialog,"audio_dscp"))); + linphone_core_set_video_dscp(lc, + read_dscp(linphone_gtk_get_widget(dialog,"video_dscp"))); + + break; + default: + break; + } + gtk_widget_destroy(dialog); +} + From efe7222f2efb7eae906b7337925fc080ce9d6b0e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 14 Sep 2012 17:59:57 +0200 Subject: [PATCH 44/51] save stun server and firewall policy immediately --- coreapi/linphonecore.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 6d81d8b71..42f11820c 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3652,6 +3652,8 @@ void linphone_core_set_stun_server(LinphoneCore *lc, const char *server){ if (server) lc->net_conf.stun_server=ms_strdup(server); else lc->net_conf.stun_server=NULL; + if (linphone_core_ready(lc)) + lp_config_set_string(lc->config,"net","stun_server",lc->net_conf.stun_server); } const char * linphone_core_get_stun_server(const LinphoneCore *lc){ @@ -3716,6 +3718,8 @@ const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc) void linphone_core_set_firewall_policy(LinphoneCore *lc, LinphoneFirewallPolicy pol){ lc->net_conf.firewall_policy=pol; if (lc->sip_conf.contact) update_primary_contact(lc); + if (linphone_core_ready(lc)) + lp_config_set_int(lc->config,"net","firewall_policy",pol); } LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc){ @@ -4449,7 +4453,6 @@ void net_config_uninit(LinphoneCore *lc) net_config_t *config=&lc->net_conf; if (config->stun_server!=NULL){ - lp_config_set_string(lc->config,"net","stun_server",config->stun_server); ms_free(lc->net_conf.stun_server); } if (config->nat_address!=NULL){ @@ -4459,7 +4462,6 @@ void net_config_uninit(LinphoneCore *lc) if (lc->net_conf.nat_address_ip !=NULL){ ms_free(lc->net_conf.nat_address_ip); } - lp_config_set_int(lc->config,"net","firewall_policy",config->firewall_policy); lp_config_set_int(lc->config,"net","mtu",config->mtu); } From e41b713dc3fa06515b5b67adf82908ddb251ad65 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 14 Sep 2012 18:26:44 +0200 Subject: [PATCH 45/51] fix compile warning --- coreapi/sal_eXosip2.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 821e4ab39..b09cae4ff 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -2261,21 +2261,23 @@ int sal_register(SalOp *h, const char *proxy, const char *from, int expires){ int sal_register_refresh(SalOp *op, int expires){ osip_message_t *msg=NULL; const char *contact=sal_op_get_contact(op); - int tries=0; if (op->rid==-1){ ms_error("Unexistant registration context, not possible to refresh."); return -1; } #ifdef HAVE_EXOSIP_TRYLOCK - /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever. - * In order to prevent this case that can occur when the exosip thread is busy with DNS while network isn't in a good shape, we try to take - * the exosip lock in a non blocking way, and give up if it takes too long*/ - while (eXosip_trylock()!=0){ - ms_usleep(100000); - if (tries>30) {/*after 3 seconds, give up*/ - ms_warning("Could not obtain exosip lock in a reasonable time, giving up."); - return -1; + { + int tries=0; + /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever. + * In order to prevent this case that can occur when the exosip thread is busy with DNS while network isn't in a good shape, we try to take + * the exosip lock in a non blocking way, and give up if it takes too long*/ + while (eXosip_trylock()!=0){ + ms_usleep(100000); + if (tries>30) {/*after 3 seconds, give up*/ + ms_warning("Could not obtain exosip lock in a reasonable time, giving up."); + return -1; + } } } #else From 8761f481d535f4cbb21e61b23d8409c3506357a4 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 15 Sep 2012 09:44:32 +0200 Subject: [PATCH 46/51] fix make distcheck --- po/POTFILES.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 01deec29e..ac50ac8aa 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,5 +1,4 @@ # List of source files containing translatable strings. -gtk/tunnel_config.ui gtk/calllogs.c gtk/conference.c gtk/logging.c @@ -25,6 +24,8 @@ gtk/loginframe.c [type: gettext/glade]gtk/parameters.ui [type: gettext/glade]gtk/buddylookup.ui [type: gettext/glade]gtk/waiting.ui +[type: gettext/glade]gtk/dscp_settings.ui +[type: gettext/glade]gtk/tunnel_config.ui coreapi/linphonecore.c coreapi/misc.c coreapi/presence.c From 249217a856fffe5c17f046bff6a6021f13d84590 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 17 Sep 2012 13:28:58 +0200 Subject: [PATCH 47/51] add documentation regarding android echo problems in javadoc --- java/common/org/linphone/core/package.html | 84 +++++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/java/common/org/linphone/core/package.html b/java/common/org/linphone/core/package.html index 65e82ddfe..d499e5d60 100644 --- a/java/common/org/linphone/core/package.html +++ b/java/common/org/linphone/core/package.html @@ -41,14 +41,18 @@ Liblinphone is a high level library for bringing SIP video call functionnality i LibLinphone package is organized in submodules. + +

Related Documentation

@@ -189,6 +193,80 @@ from a peer sip uri. System.out.println("Message ["+message+"] received from ["+from+"] "); } + + +

+Sound and echo cancellation settings +

+Sound levels +
+It is possible to tune the microphone input gain and speaker/receiver output gain by setting parameters into the linphonerc factory config file loaded when instanciating the {@link org.linphone.core.LinphoneCore LinphoneCore}. These gains are liblinphone's internal software gains and are unrelated to volume levels managed by the operating system. For example:
+
+[sound]
+#set the speaker or receiver playback gain in dbm0 (0 db = no change). 
+playback_gain_db=-3
+#set the microphone gain in linear scale:
+mic_gain=0.1
+
+
+ +
+ +Echo cancellation +
+On Android devices, echo is a problem, especially with low-end devices. The root cause is the unpredictable latency of Android's sound system. The liblinphone software {@link org.linphone.core.LinphoneCore#enableEchoCancellation echo canceller} that is operating well on desktop platforms (Mac, Linux, Windows) is unable to operate under Android platform. The situation is very heterogenous:
+
    +
  • On new (after 2011) high end devices, manufacturers often include a hardware echo cancellation. If available, liblinphone will make use of it and no software correction is required. + Source file linphone-android/submodules/linphone/mediastreamer2/java/src/org/linphone/mediastream/video/capture/hwconf/Hacks.java contains a method hasBuiltInEchoCanceller() that returns true if an hardware echo canceller is available, based on device model identifier. The current list is incomplete. +
  • +
  • On former models with decent CPU power (armv7), sound system behaves in a nearly predictive way so that it is possible to use {@link org.linphone.core.LinphoneCore#enableEchoLimiter echo limiter}. Echo limiter is a simple echo attenuation technique which consists in strongly attenuating the microphone input when speaker is playing voice, in order to cut the echo. The main drawback of echo limiter is that the conversation is perceived as half duplex by users, because they won't hear background noise from the remote side while they are speaking. +
  • +
  • On low class android devices or very old models (armv5 processor), no solution works. +
  • +
+ +
+In order to benefit from the best echo cancellation solution, we recommend applications to run the following algorithm, when it is run for the first time:
+First of {@link org.linphone.core.LinphoneCore#enableEchoCancellation echo canceller} should not be used, in any case. +
    +
  • Use the Hacks.hasBuiltInEchoCanceller() method to first check if the device has hardware echo canceller. If yes, then echo limiter must be turned off.
  • +
  • If no the hasBuiltInEchoCanceller() returned false, then it is possible to use the echo calibration procedure. If the calibration procedure fails, it means that + probably the phone performs hardware echo cancellation, so in this case echo limiter must be turned off.
  • +
  • If the echo calibration succeeded, then echo is present, so it is recommended to enable echo limiter. +
+ +
+Echo calibration procedure +
+The echo calibration procedure is a five second test which consists in playing small beeps to the speaker while the microphone input is recorded. +If the device is subject to echo (or doesn't have hardware echo cancellation), then beeps recorded by the microphone will be detected and a measurement of echo delay can be computed. +Echo calibration procedure can be started by calling {@link org.linphone.core.LinphoneCore#startEchoCalibration LinphoneCore.startEchoCalibration}. + +

+Echo limiter settings
+Echo limiter requires settings to be defined in linphonerc factory config file for correction operation. +Typical settings are: +
+
+[sound]
+el_type=mic
+#speaker energy threshold (linear scale) above which echo limiter decreases mic gain.
+el_thres=0.03
+#attenuation applied to mic gain (linear scale)
+el_force=100000
+#minimum time in milliseconds during which attenuation is applied
+el_sustain=600
+#double talk detection: threshold of ratio mic-energy/speaker-energy above which mic input is sent anyway.
+el_transmit_thres=1.7
+#noise gate floorgain (gain applied when no voice is detected).
+ng_floorgain=0.01
+
+
+ +Up to date settings must be found from linphone-android/res/raw/linphonerc file. + +
+ \ No newline at end of file From 9f14b4e9ddcf10ddfba0e82fe600c855a9f5c518 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 17 Sep 2012 14:40:35 +0200 Subject: [PATCH 48/51] javadoc fixes --- .../org/linphone/core/LinphoneCall.java | 2 +- .../org/linphone/core/LinphoneCore.java | 8 ++--- .../linphone/core/LinphoneCoreListener.java | 34 +++++++++---------- java/common/org/linphone/core/package.html | 7 +++- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index c42ebb740..6fe6704de 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -21,7 +21,7 @@ package org.linphone.core; import java.util.Vector; /** - * Object representing a Call. calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or passed to the application by listener {@link LinphoneCoreListener#callState(LinphoneCore, LinphoneCall, State, String)} + * Object representing a call. Calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or passed to the application by listener {@link LinphoneCoreListener#callState} * */ diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index dbe5611db..9e2af91b7 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -373,7 +373,7 @@ public interface LinphoneCore { * Accept an incoming call. * * Basically the application is notified of incoming calls within the - * {@link LinphoneCoreListener#inviteReceived(LinphoneCore, String)} listener. + * {@link LinphoneCoreListener#callState} listener method. * The application can later respond positively to the call using * this method. * @throws LinphoneCoreException @@ -384,7 +384,7 @@ public interface LinphoneCore { * Accept an incoming call. * * Basically the application is notified of incoming calls within the - * {@link LinphoneCoreListener#inviteReceived(LinphoneCore, String)} listener. + * {@link LinphoneCoreListener#callState} listener method. * The application can later respond positively to the call using * this method. * @throws LinphoneCoreException @@ -395,7 +395,7 @@ public interface LinphoneCore { * Accept call modifications initiated by other end. * * Basically the application is notified of incoming calls within the - * {@link LinphoneCoreListener#inviteReceived(LinphoneCore, String)} listener. + * {@link LinphoneCoreListener#callState} listener method. * The application can later respond positively to the call using * this method. * @throws LinphoneCoreException @@ -407,7 +407,7 @@ public interface LinphoneCore { * Prevent LinphoneCore from performing an automatic answer * * Basically the application is notified of incoming calls within the - * {@link LinphoneCoreListener#inviteReceived(LinphoneCore, String)} listener. + * {@link LinphoneCoreListener#callState} listener method. * The application can later respond positively to the call using * this method. * @throws LinphoneCoreException diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index ab9dd1ac3..150141ffe 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -24,27 +24,10 @@ package org.linphone.core; *This interface holds all callbacks that the application should implement. None is mandatory. */ public interface LinphoneCoreListener { - - /**< Notifies the application that it should show up - * @return */ - void show(LinphoneCore lc); - /**< Ask the application some authentication information * @return */ void authInfoRequested(LinphoneCore lc,String realm,String username); - /**< Callback that notifies various events with human readable text. - * @return */ - void displayStatus(LinphoneCore lc,String message); - - /**< Callback to display a message to the user - * @return */ - void displayMessage(LinphoneCore lc,String message); - - /** Callback to display a warning to the user - * @return */ - void displayWarning(LinphoneCore lc,String message); - /** General State notification * @param state LinphoneCore.State * @return @@ -121,5 +104,22 @@ public interface LinphoneCoreListener { * */ void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event); + + + /**< @Deprecated Notifies the application that it should show up + * @return */ + void show(LinphoneCore lc); + /**< @Deprecated Callback that notifies various events with human readable text. + * @return */ + void displayStatus(LinphoneCore lc,String message); + + /**< @Deprecated Callback to display a message to the user + * @return */ + void displayMessage(LinphoneCore lc,String message); + + /** @Deprecated Callback to display a warning to the user + * @return */ + void displayWarning(LinphoneCore lc,String message); + } diff --git a/java/common/org/linphone/core/package.html b/java/common/org/linphone/core/package.html index d499e5d60..8371def49 100644 --- a/java/common/org/linphone/core/package.html +++ b/java/common/org/linphone/core/package.html @@ -159,7 +159,12 @@ Any subsequente modifications to {@link org.linphone.core.LinphoneFriend} must b my_friend.enableSubscribes(true); /*disable subscription for this friend*/ my_friend.done(); /*commit changes triggering an UNSUBSCRIBE message*/ - + Do not display status messages +-J Pass directly to the runtime system + +Provided by Standard doclet: +-d Destination directory for output files +-use Publishing presence status
Local presence status can be changed using function {@link org.linphone.core.LinphoneCore#setPresenceInfo }.New status is propagated to all friends {@link org.linphone.core.LinphoneCore#addFriend(LinphoneFriend lf) previously added } to LinphoneCore. From 5a7090ccb0d58a13983c00fb09e50fd7fa1d3461 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 17 Sep 2012 14:50:02 +0200 Subject: [PATCH 49/51] fix parameters not written to config file immediately --- coreapi/linphonecore.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 42f11820c..152ccf80c 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3872,6 +3872,8 @@ const LinphoneVideoPolicy *linphone_core_get_video_policy(LinphoneCore *lc){ **/ void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val){ lc->video_conf.show_local=val; + if (linphone_core_ready(lc)) + lp_config_set_int(lc->config,"video","show_local",val); } /** @@ -3897,6 +3899,9 @@ void linphone_core_enable_self_view(LinphoneCore *lc, bool_t val){ if (call && call->videostream){ video_stream_enable_self_view(call->videostream,val); } + if (linphone_core_ready(lc)){ + lp_config_set_int(lc->config,"video","self_view",val); + } #endif } @@ -4529,7 +4534,7 @@ void rtp_config_uninit(LinphoneCore *lc) lp_config_set_int(lc->config,"rtp","video_jitt_comp_enabled",config->video_adaptive_jitt_comp_enabled); } -void sound_config_uninit(LinphoneCore *lc) +static void sound_config_uninit(LinphoneCore *lc) { sound_config_t *config=&lc->sound_conf; ms_free(config->cards); @@ -4541,13 +4546,11 @@ void sound_config_uninit(LinphoneCore *lc) ms_snd_card_manager_destroy(); } -void video_config_uninit(LinphoneCore *lc) +static void video_config_uninit(LinphoneCore *lc) { lp_config_set_string(lc->config,"video","size",video_size_get_name(linphone_core_get_preferred_video_size(lc))); lp_config_set_int(lc->config,"video","display",lc->video_conf.display); lp_config_set_int(lc->config,"video","capture",lc->video_conf.capture); - lp_config_set_int(lc->config,"video","show_local",linphone_core_video_preview_enabled(lc)); - lp_config_set_int(lc->config,"video","self_view",linphone_core_self_view_enabled(lc)); if (lc->video_conf.cams) ms_free(lc->video_conf.cams); } From c4086e989a6e600d1a1ccbc2ea1b09c0cc71cba5 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 17 Sep 2012 14:46:55 +0200 Subject: [PATCH 50/51] Add ICE state to the call stats. --- coreapi/linphonecall.c | 5 +++++ coreapi/linphonecore.h | 19 +++++++++++++++++++ coreapi/misc.c | 40 ++++++++++++++++++++++++++++++++++++++++ coreapi/private.h | 1 + 4 files changed, 65 insertions(+) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 5962badd3..9243be084 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -324,6 +324,7 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) { stats->type = type; stats->received_rtcp = NULL; stats->sent_rtcp = NULL; + stats->ice_state = LinphoneIceStateNotActivated; } static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){ @@ -1541,6 +1542,8 @@ void linphone_call_delete_ice_session(LinphoneCall *call){ call->ice_session = NULL; if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL; if (call->videostream != NULL) call->videostream->ice_check_list = NULL; + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated; + call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated; } } @@ -1766,6 +1769,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ if (ice_session_role(call->ice_session) == IR_Controlling) { ice_session_select_candidates(call->ice_session); linphone_core_update_call(call->core, call, &call->current_params); + linphone_core_update_ice_state_in_call_stats(call); } break; case IS_Failed: @@ -1774,6 +1778,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ /* At least one ICE session has succeeded, so perform a call update. */ ice_session_select_candidates(call->ice_session); linphone_core_update_call(call->core, call, &call->current_params); + linphone_core_update_ice_state_in_call_stats(call); } } break; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index ef24f2c78..acf81f1df 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -261,6 +261,24 @@ typedef struct _LinphoneCall LinphoneCall; #define LINPHONE_CALL_STATS_AUDIO 0 #define LINPHONE_CALL_STATS_VIDEO 1 +/** + * Enum describing ICE states. + * @ingroup initializing +**/ +enum _LinphoneIceState{ + LinphoneIceStateNotActivated, /**< ICE has not been activated for this call */ + LinphoneIceStateInProgress, /**< ICE process is in progress */ + LinphoneIceStateHostConnection, /**< ICE has established a direct connection to the remote host */ + LinphoneIceStateReflexiveConnection, /**< ICE has established a connection to the remote host through one or several NATs */ + LinphoneIceStateRelayConnection /**< ICE has established a connection through a relay */ +}; + +/** + * Enum describing Ice states. + * @ingroup initializing +**/ +typedef enum _LinphoneIceState LinphoneIceState; + /** * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. * @@ -285,6 +303,7 @@ struct _LinphoneCallStats { mblk_t* received_rtcp; /**audio_port, 1, NULL); ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port + 1, 2, NULL); + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress; if (call->params.has_video && (video_check_list != NULL)) { ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port, 1, NULL); ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port + 1, 2, NULL); + call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress; } ms_message("ICE: gathering candidate from [%s]",server); @@ -635,6 +637,44 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) return 0; } +void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call) +{ + IceCheckList *audio_check_list; + IceCheckList *video_check_list; + + if (call->ice_session == NULL) return; + audio_check_list = ice_session_check_list(call->ice_session, 0); + video_check_list = ice_session_check_list(call->ice_session, 1); + if (audio_check_list == NULL) return; + + switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) { + case ICT_HostCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection; + break; + case ICT_ServerReflexiveCandidate: + case ICT_PeerReflexiveCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection; + break; + case ICT_RelayedCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection; + break; + } + if (call->params.has_video && (video_check_list != NULL)) { + switch (ice_check_list_selected_valid_candidate_type(video_check_list)) { + case ICT_HostCandidate: + call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection; + break; + case ICT_ServerReflexiveCandidate: + case ICT_PeerReflexiveCandidate: + call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection; + break; + case ICT_RelayedCandidate: + call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection; + break; + } + } +} + void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session) { const char *rtp_addr, *rtcp_addr; diff --git a/coreapi/private.h b/coreapi/private.h index f26c6f106..f0b3b2c30 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -241,6 +241,7 @@ typedef struct StunCandidate{ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc); void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params); int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call); +void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call); void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session); void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md); void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md); From dabbcea87b12e4fd3c31ec7bfd391928798b2192 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 17 Sep 2012 15:11:35 +0200 Subject: [PATCH 51/51] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index a457709df..88b9146cc 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a457709df8daa72544fc36283c0053c4f09d0249 +Subproject commit 88b9146ccbd33c9d8d3317be92078f6211498907 diff --git a/oRTP b/oRTP index cbe444a60..b7c5f78d8 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit cbe444a6098346311b412a5723190107e77d9c42 +Subproject commit b7c5f78d83f8a310ba3700e93174c7eb1234d2d3