From fdd99cd205ebdc3d678696e7096ce50a7dc44faa Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 5 Feb 2010 18:42:34 +0100 Subject: [PATCH] sal in progress, near to code complete. --- coreapi/authentication.c | 2 - coreapi/callbacks.c | 133 +++++++--- coreapi/chat.c | 43 ++-- coreapi/friend.c | 432 +++++++-------------------------- coreapi/linphonecore.c | 100 ++++++-- coreapi/linphonecore.h | 13 +- coreapi/misc.c | 173 ++----------- coreapi/presence.c | 205 +++++++--------- coreapi/private.h | 19 +- coreapi/proxy.c | 423 ++++---------------------------- coreapi/sal.c | 8 + coreapi/sal.h | 32 ++- coreapi/sal_eXosip2.c | 67 ++++- coreapi/sal_eXosip2.h | 3 + coreapi/sal_eXosip2_presence.c | 201 ++++++++++++--- coreapi/sal_eXosip2_sdp.c | 35 ++- mediastreamer2 | 2 +- oRTP | 2 +- 18 files changed, 735 insertions(+), 1158 deletions(-) diff --git a/coreapi/authentication.c b/coreapi/authentication.c index ee360ecfe..e55ab495a 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -51,7 +51,6 @@ LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *useri if (ha1!=NULL && (strlen(ha1)>0)) obj->ha1=ms_strdup(ha1); if (realm!=NULL && (strlen(realm)>0)) obj->realm=ms_strdup(realm); obj->works=FALSE; - obj->first_time=TRUE; return obj; } @@ -252,7 +251,6 @@ void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info) } refresh_exosip_auth_info(lc); /* if the user was prompted, re-allow automatic_action */ - if (lc->automatic_action>0) lc->automatic_action--; } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 08267a30d..a95f3570d 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" #include "private.h" +#include "mediastreamer2/mediastream.h" static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){ if (lc->vtable.show) @@ -37,9 +38,8 @@ static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){ } static void call_received(SalOp *h){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); char *barmesg; - int err; LinphoneCall *call; const char *from,*to; char *tmp; @@ -62,34 +62,34 @@ static void call_received(SalOp *h){ sal_call_decline(h,SalReasonRedirect,lc->alt_contact); else sal_call_decline(h,SalReasonBusy,NULL); - sal_op_release(op); + sal_op_release(h); return; } if (lc->call!=NULL){/*busy*/ sal_call_decline(h,SalReasonBusy,NULL); - sal_op_release(op); + sal_op_release(h); return; } - from=sal_op_get_from(op); - to=sal_op_get_to(op); + from=sal_op_get_from(h); + to=sal_op_get_to(h); - call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),op); + call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),h); lc->call=call; - sal_call_set_local_media_description(op,call->localdesc); - call->resultdesc=sal_call_get_final_media_description(op); - if (call->resultdesc && sal_media_description_empty(call->resultdesc){ - sal_call_decline(op,SalReasonMedia,NULL); + sal_call_set_local_media_description(h,call->localdesc); + call->resultdesc=sal_call_get_final_media_description(h); + if (call->resultdesc && sal_media_description_empty(call->resultdesc)){ + sal_call_decline(h,SalReasonMedia,NULL); linphone_call_destroy(call); lc->call=NULL; return; } - from_parsed=linphone_address_new(sal_op_get_from(op)); + from_parsed=linphone_address_new(sal_op_get_from(h)); linphone_address_clean(from_parsed); tmp=linphone_address_as_string(from_parsed); linphone_address_destroy(from_parsed); gstate_new_state(lc, GSTATE_CALL_IN_INVITE, tmp); - barmesg=ortp_strdup_printf("%s %s",tmp,_("is contacting you.")); + barmesg=ortp_strdup_printf(_("%s is contacting you"),tmp); if (lc->vtable.show) lc->vtable.show(lc); if (lc->vtable.display_status) lc->vtable.display_status(lc,barmesg); @@ -100,7 +100,7 @@ static void call_received(SalOp *h){ lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard); } linphone_call_set_state(call,LCStateRinging); - sal_call_notify_ringing(op); + sal_call_notify_ringing(h); if (lc->vtable.inv_recv) lc->vtable.inv_recv(lc,tmp); ms_free(barmesg); @@ -108,7 +108,7 @@ static void call_received(SalOp *h){ } static void call_ringing(SalOp *h){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); LinphoneCall *call=lc->call; SalMediaDescription *md; if (call==NULL) return; @@ -145,18 +145,18 @@ static void call_ringing(SalOp *h){ } static void call_accepted(SalOp *op){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=lc->call; if (call==NULL){ ms_warning("No call to accept."); - return 0; + return ; } if (sal_op_get_user_pointer(op)!=lc->call){ ms_warning("call_accepted: ignoring."); return; } if (call->state==LCStateAVRunning){ - return 0; /*already accepted*/ + return ; /*already accepted*/ } if (lc->audiostream->ticker!=NULL){ /*case where we accepted early media */ @@ -176,8 +176,8 @@ static void call_accepted(SalOp *op){ } } -static void call_ack(SalOp *h){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); +static void call_ack(SalOp *op){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=lc->call; if (call==NULL){ ms_warning("No call to be ACK'd"); @@ -205,8 +205,9 @@ static void call_ack(SalOp *h){ } } -static void call_updated(SalOp *){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); +static void call_updated(SalOp *op){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); linphone_core_stop_media_streams(lc,call); linphone_core_init_media_streams(lc,call); if (call->resultdesc) @@ -217,8 +218,8 @@ static void call_updated(SalOp *){ } } -static void call_terminated(SalOp *h, const char *from){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); +static void call_terminated(SalOp *op, const char *from){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); if (sal_op_get_user_pointer(op)!=lc->call){ ms_warning("call_terminated: ignoring."); return; @@ -236,7 +237,7 @@ static void call_terminated(SalOp *h, const char *from){ LinphoneAddress *addr=linphone_address_new(from); char *tmp; linphone_address_clean(addr); - tmp=linphone_address_as_string(from); + tmp=linphone_address_as_string(addr); lc->vtable.bye_recv(lc,tmp); ms_free(tmp); linphone_address_destroy(addr); @@ -246,16 +247,14 @@ static void call_terminated(SalOp *h, const char *from){ } static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); - const char *reason=""; + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); char *msg486=_("User is busy."); char *msg480=_("User is temporarily unavailable."); /*char *retrymsg=_("%s. Retry after %i minute(s).");*/ char *msg600=_("User does not want to be disturbed."); char *msg603=_("Call declined."); - char* tmpmsg=msg486; - int code; LinphoneCall *call=lc->call; + if (sal_op_get_user_pointer(op)!=lc->call){ ms_warning("call_failure: ignoring."); return; @@ -263,10 +262,10 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de if (lc->vtable.show) lc->vtable.show(lc); if (error==SalErrorNoResponse){ - if (lc->vtale.display_status) + if (lc->vtable.display_status) lc->vtable.display_status(lc,_("No response.")); }else if (error==SalErrorProtocol){ - if (lc->vtale.display_status) + if (lc->vtable.display_status) lc->vtable.display_status(lc, details ? details : _("Error.")); }else if (error==SalErrorFailure){ switch(sr){ @@ -288,7 +287,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de break; case SalReasonNotFound: if (lc->vtable.display_status) - lc->vtable.display_status(lc,msg404); + lc->vtable.display_status(lc,_("Not found")); break; case SalReasonDoNotDisturb: if (lc->vtable.display_status) @@ -307,7 +306,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de ring_stop(lc->ringstream); lc->ringstream=NULL; } - linphone_core_stop_media_streams(lc); + linphone_core_stop_media_streams(lc,call); if (call!=NULL) { linphone_call_destroy(call); gstate_new_state(lc, GSTATE_CALL_ERROR, NULL); @@ -316,41 +315,94 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de } static void auth_requested(SalOp *h, const char *realm, const char *username){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_root(h)); - LinphoneAuthInfo *ai=linphone_core_find_auth_info(lc); + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); + LinphoneAuthInfo *ai=linphone_core_find_auth_info(lc,realm,username); + if (ai && (ai->works || ai->usecount<3)){ + SalAuthInfo sai; + sai.username=ai->username; + sai.userid=ai->userid; + sai.realm=ai->realm; + sai.password=ai->passwd; + sal_op_authenticate(h,&sai); + ai->usecount++; + }else{ + if (lc->vtable.auth_info_requested) + lc->vtable.auth_info_requested(lc,realm,username); + } } static void auth_success(SalOp *h, const char *realm, const char *username){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); + LinphoneAuthInfo *ai=linphone_core_find_auth_info(lc,realm,username); + if (ai) + ai->works=TRUE; } static void register_success(SalOp *op, bool_t registered){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op); + char *msg; + gstate_new_state(lc, GSTATE_REG_OK, NULL); + if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op)); + else msg=ms_strdup_printf(_("Unregistration on %s done."),sal_op_get_proxy(op)); + if (lc->vtable.display_status) + lc->vtable.display_status(lc,msg); + ms_free(msg); } static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op),(details!=NULL) ? details : _("no response timeout")); + if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); + gstate_new_state(lc, GSTATE_REG_FAILED, msg); + ms_free(msg); } static void vfu_request(SalOp *op){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); +#ifdef VIDEO_ENABLED + if (lc->videostream) + video_stream_send_vfu(lc->videostream); +#endif } static void dtmf_received(SalOp *op, char dtmf){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + if (lc->vtable.dtmf_received != NULL) + lc->vtable.dtmf_received(lc, dtmf); } -static void refer_received(SalOp *op, SalOp *op, const char *referto){ +static void refer_received(Sal *sal, SalOp *op, const char *referto){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); + if (lc->vtable.refer_received) + lc->vtable.refer_received(lc,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); } -static void presence_changed(SalOp *op, SalPresenceStatus status, const char *msg){ +static void notify(SalOp *op, SalSubscribeState ss, SalPresenceStatus status, const char *msg){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + linphone_notify_recv(lc,op,ss,status); } static void subscribe_received(SalOp *op, const char *from){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + linphone_subscription_new(lc,op,from); } -static void internal_message(SalOp *op, const char *msg){ +static void subscribe_closed(SalOp *op, const char *from){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + linphone_subscription_closed(lc,op); } - +static void internal_message(Sal *sal, const char *msg){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); + if (lc->vtable.show) + lc->vtable.show(lc); +} SalCallbacks linphone_sal_callbacks={ call_received, @@ -368,8 +420,9 @@ SalCallbacks linphone_sal_callbacks={ dtmf_received, refer_received, text_received, - presence_changed, + notify, subscribe_received, + subscribe_closed, internal_message }; diff --git a/coreapi/chat.c b/coreapi/chat.c index 95526274c..11c3c978f 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -24,7 +24,6 @@ #include "linphonecore.h" #include "private.h" - #include LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to){ LinphoneAddress *parsed_url=NULL; @@ -52,11 +51,10 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ const char *identity=linphone_core_get_identity(cr->lc); - osip_message_t *sip=NULL; - eXosip_message_build_request(&sip,"MESSAGE",cr->peer,identity,cr->route); - osip_message_set_content_type(sip,"text/plain"); - osip_message_set_body(sip,msg,strlen(msg)); - eXosip_message_send_request(sip); + SalOp *op=sal_op_new(cr->lc->sal); + + sal_op_set_route(op,cr->route); + sal_text_send(op,identity,cr->peer,msg); } bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *from){ @@ -69,40 +67,29 @@ void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, co if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, from, msg); } -void linphone_core_text_received(LinphoneCore *lc, eXosip_event_t *ev){ +void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg){ MSList *elem; - const char *msg; LinphoneChatRoom *cr=NULL; - char *from; - osip_from_t *from_url=ev->request->from; - osip_body_t *body=NULL; - LinphoneAddress *uri; + LinphoneAddress *addr; + char *cleanfrom; - 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(from_url,&from); - uri=linphone_address_new(from); - osip_free(from); - linphone_address_clean(uri); + addr=linphone_address_new(from); + linphone_address_clean(addr); for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){ cr=(LinphoneChatRoom*)elem->data; - if (linphone_chat_room_matches(cr,uri)){ + if (linphone_chat_room_matches(cr,addr)){ break; } cr=NULL; } - from=linphone_address_as_string(uri); + cleanfrom=linphone_address_as_string(addr); if (cr==NULL){ /* create a new chat room */ - cr=linphone_core_create_chat_room(lc,from); + cr=linphone_core_create_chat_room(lc,cleanfrom); } - linphone_address_destroy(uri); - linphone_chat_room_text_received(cr,lc,from,msg); - ms_free(from); + linphone_address_destroy(addr); + linphone_chat_room_text_received(cr,lc,cleanfrom,msg); + ms_free(cleanfrom); } diff --git a/coreapi/friend.c b/coreapi/friend.c index 08f072de3..5dd51bec5 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -31,9 +31,6 @@ const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){ const char *str=NULL; switch(ss){ - case LINPHONE_STATUS_UNKNOWN: - str=_("Unknown"); - break; case LINPHONE_STATUS_ONLINE: str=_("Online"); break; @@ -67,9 +64,6 @@ const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){ case LINPHONE_STATUS_PENDING: str=_("Pending"); break; - case LINPHONE_STATUS_CLOSED: - str=_("Closed"); - break; default: str=_("Unknown-bug"); } @@ -114,20 +108,20 @@ MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *friend, Linphone return res; } -LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid){ +LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op){ MSList *elem; for (elem=l;elem!=NULL;elem=elem->next){ LinphoneFriend *lf=(LinphoneFriend*)elem->data; - if (lf->nid==nid) return lf; + if (lf->insub==op) return lf; } return NULL; } -LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid){ +LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op){ MSList *elem; for (elem=l;elem!=NULL;elem=elem->next){ LinphoneFriend *lf=(LinphoneFriend*)elem->data; - if (lf->sid==sid) return lf; + if (lf->outsub==op) return lf; } return NULL; } @@ -136,30 +130,30 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){ char *friend=NULL; const char *route=NULL; const char *from=NULL; - osip_message_t *msg=NULL; + LinphoneProxyConfig *cfg; + friend=linphone_address_as_string(fr->uri); - if (fr->proxy!=NULL){ - route=fr->proxy->reg_route; - from=fr->proxy->reg_identity; + cfg=linphone_core_lookup_known_proxy(fr->lc,linphone_friend_get_address(fr)); + if (cfg!=NULL){ + route=linphone_proxy_config_get_route(cfg); + from=linphone_proxy_config_get_identity(cfg); }else from=linphone_core_get_primary_contact(fr->lc); - if (fr->sid<0){ + if (fr->outsub==NULL){ /* people for which we don't have yet an answer should appear as offline */ - fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr,friend,_("Gone"),"sip-closed.png"); + if (fr->lc->vtable.notify_recv) + fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr,friend,_("Gone"),"sip-closed.png"); + }else{ + sal_op_release(fr->outsub); + fr->outsub=NULL; } - eXosip_lock(); - eXosip_subscribe_build_initial_request(&msg,friend,from,route,"presence",600); - eXosip_subscribe_send_initial_request(msg); - eXosip_unlock(); + fr->outsub=sal_op_new(fr->lc->sal); + sal_op_set_route(fr->outsub,route); + sal_subscribe_presence(fr->outsub,from,friend); ms_free(friend); } - LinphoneFriend * linphone_friend_new(){ LinphoneFriend *obj=ms_new0(LinphoneFriend,1); - obj->out_did=-1; - obj->in_did=-1; - obj->nid=-1; - obj->sid=-1; obj->pol=LinphoneSPAccept; obj->status=LINPHONE_STATUS_OFFLINE; obj->subscribe=TRUE; @@ -214,6 +208,7 @@ int linphone_friend_set_sip_addr(LinphoneFriend *lf, const char *addr){ ms_warning("Invalid friend sip uri: %s",addr); return -1; } + linphone_address_clean(fr); if (lf->uri!=NULL) linphone_address_destroy(lf->uri); lf->uri=fr; return 0; @@ -240,335 +235,79 @@ int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscri return 0; } -int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg){ - fr->proxy=cfg; - return 0; +SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os){ + switch(os){ + case LINPHONE_STATUS_OFFLINE: + return SalPresenceOffline; + break; + case LINPHONE_STATUS_ONLINE: + return SalPresenceOnline; + break; + case LINPHONE_STATUS_BUSY: + return SalPresenceBusy; + break; + case LINPHONE_STATUS_BERIGHTBACK: + return SalPresenceBerightback; + break; + case LINPHONE_STATUS_AWAY: + return SalPresenceAway; + break; + case LINPHONE_STATUS_ONTHEPHONE: + return SalPresenceOnthephone; + break; + case LINPHONE_STATUS_OUTTOLUNCH: + return SalPresenceOuttolunch; + break; + case LINPHONE_STATUS_NOT_DISTURB: + return SalPresenceDonotdisturb; + break; + case LINPHONE_STATUS_MOVED: + return SalPresenceMoved; + break; + case LINPHONE_STATUS_ALT_SERVICE: + return SalPresenceAltService; + break; + case LINPHONE_STATUS_PENDING: + return SalPresenceOffline; + break; + default: + return SalPresenceOffline; + break; + } + return SalPresenceOffline; } -void linphone_friend_set_sid(LinphoneFriend *lf, int sid){ - lf->sid=sid; -} -void linphone_friend_set_nid(LinphoneFriend *lf, int nid){ - lf->nid=nid; - lf->inc_subscribe_pending=TRUE; -} - -void add_presence_body(osip_message_t *notify, LinphoneOnlineStatus online_status) -{ - char buf[1000]; -#ifdef SUPPORT_MSN - int atom_id = 1000; -#endif - char *contact_info; - - osip_contact_t *ct=NULL; - osip_message_get_contact(notify,0,&ct); - osip_contact_to_str(ct,&contact_info); - -#ifdef SUPPORT_MSN - - if (online_status==LINPHONE_STATUS_ONLINE) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - - } - else if (online_status==LINPHONE_STATUS_BUSY) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - - } - else if (online_status==LINPHONE_STATUS_BERIGHTBACK) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - - } - else if (online_status==LINPHONE_STATUS_AWAY) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - - } - else if (online_status==LINPHONE_STATUS_ONTHEPHONE) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - - } - else if (online_status==LINPHONE_STATUS_OUTTOLUNCH) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - - } - else - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); - } - - osip_message_set_body(notify, buf, strlen(buf)); - osip_message_set_content_type(notify, "application/xpidf+xml"); -#else - - if (online_status==LINPHONE_STATUS_ONLINE) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ -%s\n\ -online\n\ -\n\ -", - contact_info, contact_info); - } - else if (online_status==LINPHONE_STATUS_BUSY) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - busy\n\ -\n\ -\n\ -%s\n\ -busy\n\ -\n\ -", - contact_info, contact_info); - } - else if (online_status==LINPHONE_STATUS_BERIGHTBACK) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - in-transit\n\ -\n\ -\n\ -%s\n\ -be right back\n\ -\n\ -", - contact_info, contact_info); - } - else if (online_status==LINPHONE_STATUS_AWAY) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - away\n\ -\n\ -\n\ -%s\n\ -away\n\ -\n\ -", - contact_info, contact_info); - } - else if (online_status==LINPHONE_STATUS_ONTHEPHONE) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - on-the-phone\n\ -\n\ -\n\ -%s\n\ -on the phone\n\ -\n\ -", - contact_info, contact_info); - } - else if (online_status==LINPHONE_STATUS_OUTTOLUNCH) - { - sprintf(buf, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - meal\n\ -\n\ -\n\ -%s\n\ -out to lunch\n\ -\n\ -", - contact_info, contact_info); - } - else - { - /* */ - sprintf(buf, "\n\ -\n%s", - contact_info, -"\n\ -\n\ -closed\n\ -\n\ - permanent-absence\n\ -\n\ -\n\ -\n\ -\n\n"); - } - osip_message_set_body(notify, buf, strlen(buf)); - osip_message_set_content_type(notify, "application/pidf+xml"); - -#endif - osip_free(contact_info); -} - - -void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os){ +void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os){ //printf("Wish to notify %p, lf->nid=%i\n",lf,lf->nid); - if (lf->in_did!=-1){ - osip_message_t *msg=NULL; - const char *identity; - if (lf->proxy!=NULL) identity=lf->proxy->reg_identity; - else identity=linphone_core_get_primary_contact(lf->lc); - eXosip_lock(); - eXosip_insubscription_build_notify(lf->in_did,ss,0,&msg); - if (msg!=NULL){ - osip_message_set_contact(msg,identity); - add_presence_body(msg,os); - eXosip_insubscription_send_request(lf->in_did,msg); - }else ms_error("could not create notify for incoming subscription."); - eXosip_unlock(); + if (lf->insub!=NULL){ + sal_notify_presence(lf->insub,linphone_online_status_to_sal(os),NULL); } } static void linphone_friend_unsubscribe(LinphoneFriend *lf){ - if (lf->out_did!=-1) { - osip_message_t *msg=NULL; - eXosip_lock(); - eXosip_subscribe_build_refresh_request(lf->out_did,&msg); - if (msg){ - osip_message_set_expires(msg,"0"); - eXosip_subscribe_send_refresh_request(lf->out_did,msg); - }else ms_error("Could not build subscribe refresh request !"); - eXosip_unlock(); + if (lf->outsub!=NULL) { + sal_unsubscribe(lf->outsub); + sal_op_release(lf->outsub); + lf->outsub=NULL; } } void linphone_friend_destroy(LinphoneFriend *lf){ - linphone_friend_notify(lf,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED); + linphone_friend_notify(lf,LINPHONE_STATUS_OFFLINE); linphone_friend_unsubscribe(lf); + if (lf->insub){ + sal_notify_close(lf->insub); + sal_op_release(lf->insub); + } if (lf->uri!=NULL) linphone_address_destroy(lf->uri); if (lf->info!=NULL) buddy_info_free(lf->info); ms_free(lf); } -void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg){ - if (lf->proxy==cfg){ - lf->proxy=NULL; - } -} - const LinphoneAddress *linphone_friend_get_uri(const LinphoneFriend *lf){ return lf->uri; } - bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){ return lf->subscribe; } @@ -597,21 +336,21 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){ if (fr->inc_subscribe_pending){ switch(fr->pol){ case LinphoneSPWait: - linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_PENDING,LINPHONE_STATUS_PENDING); + linphone_friend_notify(fr,LINPHONE_STATUS_PENDING); break; case LinphoneSPAccept: if (fr->lc!=NULL) { - linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_ACTIVE,fr->lc->presence_mode); + linphone_friend_notify(fr,fr->lc->presence_mode); } break; case LinphoneSPDeny: - linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED); + linphone_friend_notify(fr,LINPHONE_STATUS_OFFLINE); break; } fr->inc_subscribe_pending=FALSE; } - if (fr->subscribe && fr->out_did==-1){ + if (fr->subscribe && fr->outsub==NULL){ __linphone_friend_do_subscribe(fr); } @@ -632,6 +371,14 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { ms_return_if_fail(lf->lc==NULL); ms_return_if_fail(lf->uri!=NULL); + if (ms_list_find(lc->friends,lf)!=NULL){ + char *tmp=NULL; + const LinphoneAddress *addr=linphone_friend_get_address(lf); + if (addr) tmp=linphone_address_as_string(addr); + ms_warning("Friend %s already in list, ignored.", tmp ? tmp : "unknown"); + if (tmp) ms_free(tmp); + return ; + } lc->friends=ms_list_append(lc->friends,lf); linphone_friend_apply(lf,lc); return ; @@ -667,7 +414,7 @@ static bool_t username_match(const char *u1, const char *u2){ return FALSE; } -LinphoneFriend *linphone_core_get_friend_by_uri(const LinphoneCore *lc, const char *uri){ +LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *uri){ LinphoneAddress *puri=linphone_address_new(uri); const MSList *elem; const char *username=linphone_address_get_username(puri); @@ -752,10 +499,6 @@ LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int inde a=lp_config_get_int(config,item,"subscribe",0); linphone_friend_send_subscribe(lf,a); - a=lp_config_get_int(config,item,"proxy",-1); - if (a!=-1) { - linphone_friend_set_proxy(lf,__index_to_proxy(lc,a)); - } linphone_friend_set_ref_key(lf,lp_config_get_string(config,item,"refkey",NULL)); return lf; } @@ -779,7 +522,6 @@ const char *__policy_enum_to_str(LinphoneSubscribePolicy pol){ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf, int index){ char key[50]; char *tmp; - int a; const char *refkey; sprintf(key,"friend_%i",index); @@ -798,10 +540,6 @@ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf, } lp_config_set_string(config,key,"pol",__policy_enum_to_str(lf->pol)); lp_config_set_int(config,key,"subscribe",lf->subscribe); - if (lf->proxy!=NULL){ - a=ms_list_index(lf->lc->sip_conf.proxies,lf->proxy); - lp_config_set_int(config,key,"proxy",a); - }else lp_config_set_int(config,key,"proxy",-1); refkey=linphone_friend_get_ref_key(lf); if (refkey){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 98f6d811f..cf16e8da3 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -650,28 +650,72 @@ static void rtp_config_read(LinphoneCore *lc) linphone_core_set_nortp_timeout(lc,nortp_timeout); } +static PayloadType * find_payload(RtpProfile *prof, const char *mime_type, int clock_rate, const char *recv_fmtp){ + PayloadType *candidate=NULL; + int i; + PayloadType *it; + for(i=0;i<127;++i){ + it=rtp_profile_get_payload(prof,i); + if (it!=NULL && strcasecmp(mime_type,it->mime_type)==0 + && (clock_rate==it->clock_rate || clock_rate<=0) ){ + if ( (recv_fmtp && it->recv_fmtp && strcasecmp(recv_fmtp,it->recv_fmtp)==0) || + (recv_fmtp==NULL && it->recv_fmtp==NULL) ){ + /*exact match*/ + return it; + }else candidate=it; + } + } + return candidate; +} -static PayloadType * get_codec(LpConfig *config, char* type,int index){ +static bool_t get_codec(LpConfig *config, char* type, int index, PayloadType **ret){ char codeckey[50]; const char *mime,*fmtp; int rate,enabled; PayloadType *pt; + *ret=NULL; snprintf(codeckey,50,"%s_%i",type,index); mime=lp_config_get_string(config,codeckey,"mime",NULL); - if (mime==NULL || strlen(mime)==0 ) return NULL; - - pt=payload_type_new(); - pt->mime_type=ms_strdup(mime); + if (mime==NULL || strlen(mime)==0 ) return FALSE; rate=lp_config_get_int(config,codeckey,"rate",8000); - pt->clock_rate=rate; fmtp=lp_config_get_string(config,codeckey,"recv_fmtp",NULL); - if (fmtp) pt->recv_fmtp=ms_strdup(fmtp); enabled=lp_config_get_int(config,codeckey,"enabled",1); - if (enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED; + pt=find_payload(&av_profile,mime,rate,fmtp); + if (pt && enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED; //ms_message("Found codec %s/%i",pt->mime_type,pt->clock_rate); - return pt; + if (pt==NULL) ms_warning("Ignoring codec config %s/%i with fmtp=%s because unsupported", + mime,rate,fmtp ? fmtp : ""); + *ret=pt; + return TRUE; +} + +static MSList *add_missing_codecs(SalStreamType mtype, MSList *l){ + int i; + for(i=0;i<127;++i){ + PayloadType *pt=rtp_profile_get_payload(&av_profile,i); + if (pt){ + if (mtype==SalVideo && pt->type!=PAYLOAD_VIDEO) + pt=NULL; + else if (mtype==SalAudio && (pt->type!=PAYLOAD_AUDIO_PACKETIZED + && pt->type!=PAYLOAD_AUDIO_CONTINUOUS)){ + pt=NULL; + } + if (pt && ms_filter_codec_supported(pt->mime_type)){ + if (ms_list_find(l,pt)==NULL){ + ms_message("Adding new codec %s/%i with fmtp %s", + pt->mime_type,pt->clock_rate,pt->recv_fmtp ? pt->recv_fmtp : ""); + if (strcasecmp(pt->mime_type,"speex")==0 || + strcasecmp(pt->mime_type,"MP4V-ES")==0 || + strcasecmp(pt->mime_type,"H264")==0) + l=ms_list_prepend(l,pt); + else l=ms_list_append(l,pt); + } + } + } + } + return l; } static void codecs_config_read(LinphoneCore *lc) @@ -680,23 +724,28 @@ static void codecs_config_read(LinphoneCore *lc) PayloadType *pt; MSList *audio_codecs=NULL; MSList *video_codecs=NULL; - for (i=0;;i++){ - pt=get_codec(lc->config,"audio_codec",i); - if (pt==NULL) break; - audio_codecs=ms_list_append(audio_codecs,(void *)pt); + for (i=0;get_codec(lc->config,"audio_codec",i,&pt);i++){ + if (pt){ + if (!ms_filter_codec_supported(pt->mime_type)){ + ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type); + }else audio_codecs=ms_list_append(audio_codecs,pt); + } } - for (i=0;;i++){ - pt=get_codec(lc->config,"video_codec",i); - if (pt==NULL) break; - video_codecs=ms_list_append(video_codecs,(void *)pt); + audio_codecs=add_missing_codecs(SalAudio,audio_codecs); + for (i=0;get_codec(lc->config,"video_codec",i,&pt);i++){ + if (pt){ + if (!ms_filter_codec_supported(pt->mime_type)){ + ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type); + }else video_codecs=ms_list_append(video_codecs,(void *)pt); + } } + video_codecs=add_missing_codecs(SalVideo,video_codecs); linphone_core_set_audio_codecs(lc,audio_codecs); linphone_core_set_video_codecs(lc,video_codecs); - linphone_core_setup_local_rtp_profile(lc); + linphone_core_update_allocated_audio_bandwidth(lc); } -static void video_config_read(LinphoneCore *lc) -{ +static void video_config_read(LinphoneCore *lc){ int capture, display, self_view; int enabled; const char *str; @@ -868,6 +917,9 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta gstate_new_state(lc, GSTATE_POWER_STARTUP, NULL); ortp_init(); + linphone_core_assign_payload_type(&payload_type_pcmu8000,0,NULL); + linphone_core_assign_payload_type(&payload_type_gsm,3,NULL); + linphone_core_assign_payload_type(&payload_type_pcma8000,8,NULL); linphone_core_assign_payload_type(&payload_type_lpc1015,115,NULL); linphone_core_assign_payload_type(&payload_type_speex_nb,110,"vbr=on"); linphone_core_assign_payload_type(&payload_type_speex_wb,111,"vbr=on"); @@ -1383,7 +1435,7 @@ static void proxy_update(LinphoneCore *lc, time_t curtime){ } static void assign_buddy_info(LinphoneCore *lc, BuddyInfo *info){ - LinphoneFriend *lf=linphone_core_get_friend_by_uri(lc,info->sip_uri); + LinphoneFriend *lf=linphone_core_get_friend_by_address(lc,info->sip_uri); if (lf!=NULL){ lf->info=info; ms_message("%s has a BuddyInfo assigned with image %p",info->sip_uri, info->image_data); @@ -1647,7 +1699,7 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L static char *get_fixed_contact(LinphoneCore *lc, const char *localip, LinphoneProxyConfig *dest_proxy){ LinphoneAddress *ctt; - if (dest_proxy){ + if (dest_proxy && dest_proxy->op){ const char *fixed_contact=sal_op_get_contact(dest_proxy->op); if (fixed_contact) { ms_message("Contact has been fixed using proxy to %s",fixed_contact); @@ -3178,10 +3230,6 @@ void codecs_config_uninit(LinphoneCore *lc) lp_config_set_string(lc->config,key,"recv_fmtp",pt->recv_fmtp); index++; } - if (lc->local_profile){ - rtp_profile_destroy(lc->local_profile); - lc->local_profile=NULL; - } } void ui_config_uninit(LinphoneCore* lc) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index e277fc0df..2c2f5c582 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -139,7 +139,7 @@ typedef enum{ }LinphoneSubscribePolicy; typedef enum _LinphoneOnlineStatus{ - LINPHONE_STATUS_UNKNOWN, + LINPHONE_STATUS_OFFLINE, LINPHONE_STATUS_ONLINE, LINPHONE_STATUS_BUSY, LINPHONE_STATUS_BERIGHTBACK, @@ -149,9 +149,7 @@ typedef enum _LinphoneOnlineStatus{ LINPHONE_STATUS_NOT_DISTURB, LINPHONE_STATUS_MOVED, LINPHONE_STATUS_ALT_SERVICE, - LINPHONE_STATUS_OFFLINE, LINPHONE_STATUS_PENDING, - LINPHONE_STATUS_CLOSED, LINPHONE_STATUS_END }LinphoneOnlineStatus; @@ -167,11 +165,10 @@ int linphone_friend_set_sip_addr(LinphoneFriend *fr, const char *uri); int linphone_friend_set_name(LinphoneFriend *fr, const char *name); int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val); int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol); -int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg); void linphone_friend_edit(LinphoneFriend *fr); void linphone_friend_done(LinphoneFriend *fr); void linphone_friend_destroy(LinphoneFriend *lf); -const LinphoneAddress *linphone_friend_get_uri(const LinphoneFriend *lf); +const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf); bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf); LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf); LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf); @@ -208,8 +205,8 @@ typedef struct _LinphoneProxyConfig LinphoneProxyConfig; LinphoneProxyConfig *linphone_proxy_config_new(void); int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr); -void linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity); -void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route); +int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity); +int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route); void linphone_proxy_config_expires(LinphoneProxyConfig *obj, int expires); void linphone_proxy_config_enable_register(LinphoneProxyConfig *obj, bool_t val); #define linphone_proxy_config_enableregister linphone_proxy_config_enable_register @@ -638,7 +635,7 @@ void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf); const MSList * linphone_core_get_friend_list(const LinphoneCore *lc); /* notify all friends that have subscribed */ void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os); -LinphoneFriend *linphone_core_get_friend_by_uri(const LinphoneCore *lc, const char *uri); +LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *addr); LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key); /* returns a list of LinphoneCallLog */ diff --git a/coreapi/misc.c b/coreapi/misc.c index 9bdb90420..f0cf871fd 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -295,152 +295,6 @@ bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType return ret; } -static PayloadType * find_payload(RtpProfile *prof, PayloadType *pt /*from config*/){ - PayloadType *candidate=NULL; - int i; - PayloadType *it; - for(i=0;i<127;++i){ - it=rtp_profile_get_payload(prof,i); - if (it!=NULL && strcasecmp(pt->mime_type,it->mime_type)==0 - && (pt->clock_rate==it->clock_rate || pt->clock_rate<=0) - && payload_type_get_user_data(it)==NULL ){ - if ( (pt->recv_fmtp && it->recv_fmtp && strcasecmp(pt->recv_fmtp,it->recv_fmtp)==0) || - (pt->recv_fmtp==NULL && it->recv_fmtp==NULL) ){ - /*exact match*/ - return it; - }else candidate=it; - } - } - return candidate; -} - -static bool_t check_h264_packmode(PayloadType *payload, MSFilterDesc *desc){ - if (payload->recv_fmtp==NULL || strstr(payload->recv_fmtp,"packetization-mode")==0){ - /*this is packetization-mode=0 H264, we only support it with a multislicing - enabled version of x264*/ - if (strstr(desc->text,"x264") && strstr(desc->text,"multislicing")==0){ - /*this is x264 without multisclicing*/ - ms_message("Disabling packetization-mode=0 H264 codec because " - "of lack of multislicing support"); - return FALSE; - } - } - return TRUE; -} - -static MSList *fix_codec_list(RtpProfile *prof, MSList *conflist) -{ - MSList *elem; - MSList *newlist=NULL; - PayloadType *payload,*confpayload; - - for (elem=conflist;elem!=NULL;elem=ms_list_next(elem)) - { - confpayload=(PayloadType*)elem->data; - payload=find_payload(prof,confpayload); - if (payload!=NULL){ - if (ms_filter_codec_supported(confpayload->mime_type)){ - MSFilterDesc *desc=ms_filter_get_encoder(confpayload->mime_type); - if (strcasecmp(confpayload->mime_type,"H264")==0){ - if (!check_h264_packmode(confpayload,desc)){ - continue; - } - } - payload_type_set_user_data(payload,(void*)desc->text); - payload_type_set_enable(payload,payload_type_enabled(confpayload)); - newlist=ms_list_append(newlist,payload); - } - } - else{ - ms_warning("Cannot support %s/%i: does not exist.",confpayload->mime_type, - confpayload->clock_rate); - } - } - return newlist; -} - - -void linphone_core_setup_local_rtp_profile(LinphoneCore *lc) -{ - int i; - MSList *audiopt,*videopt; - PayloadType *payload; - bool_t prepend; - lc->local_profile=rtp_profile_clone_full(&av_profile); - /* first look at the list given by configuration file to see if - it is correct */ - audiopt=fix_codec_list(lc->local_profile,lc->codecs_conf.audio_codecs); - videopt=fix_codec_list(lc->local_profile,lc->codecs_conf.video_codecs); - /* now find and add payloads that are not listed in the configuration - codec list */ - for (i=0;i<127;i++) - { - payload=rtp_profile_get_payload(lc->local_profile,i); - if (payload!=NULL){ - if (payload_type_get_user_data(payload)!=NULL) continue; - /* find a mediastreamer codec for this payload type */ - if (ms_filter_codec_supported(payload->mime_type)){ - MSFilterDesc *desc=ms_filter_get_encoder(payload->mime_type); - ms_message("Adding new codec %s/%i",payload->mime_type,payload->clock_rate); - payload_type_set_enable(payload,1); - payload_type_set_user_data(payload,(void *)desc->text); - prepend=FALSE; - /* by default, put speex, mpeg4, or h264 on top of list*/ - if (strcmp(payload->mime_type,"speex")==0) - prepend=TRUE; - else if (strcmp(payload->mime_type,"MP4V-ES")==0) - prepend=TRUE; - else if (strcasecmp(payload->mime_type,"H264")==0){ - if (check_h264_packmode(payload,desc)) - prepend=TRUE; - else continue; - } - switch (payload->type){ - case PAYLOAD_AUDIO_CONTINUOUS: - case PAYLOAD_AUDIO_PACKETIZED: - if (prepend) - audiopt=ms_list_prepend(audiopt,(void *)payload); - else - audiopt=ms_list_append(audiopt,(void *)payload); - break; - case PAYLOAD_VIDEO: - if (prepend) - videopt=ms_list_prepend(videopt,(void *)payload); - else - videopt=ms_list_append(videopt,(void *)payload); - break; - default: - ms_error("Unsupported rtp media type."); - } - } - } - } - ms_list_for_each(lc->codecs_conf.audio_codecs,(void (*)(void*))payload_type_destroy); - ms_list_for_each(lc->codecs_conf.video_codecs,(void (*)(void *))payload_type_destroy); - ms_list_free(lc->codecs_conf.audio_codecs); - ms_list_free(lc->codecs_conf.video_codecs); - /* set the fixed lists instead:*/ - lc->codecs_conf.audio_codecs=audiopt; - lc->codecs_conf.video_codecs=videopt; - linphone_core_update_allocated_audio_bandwidth(lc); -} - -int from_2char_without_params(osip_from_t *from,char **str) -{ - osip_from_t *tmpfrom=NULL; - osip_from_clone(from,&tmpfrom); - if (tmpfrom!=NULL){ - while(!osip_list_eol(&tmpfrom->gen_params,0)){ - osip_generic_param_t *param=(osip_generic_param_t*)osip_list_get(&tmpfrom->gen_params,0); - osip_generic_param_free(param); - osip_list_remove(&tmpfrom->gen_params,0); - } - }else return -1; - osip_from_to_str(tmpfrom,str); - osip_from_free(tmpfrom); - return 0; -} - bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){ #if !defined(_WIN32_WCE) FILE *f=popen(command,"r"); @@ -619,6 +473,11 @@ void 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; + + ac=&call->localdesc->streams[0].candidates[0]; + vc=&call->localdesc->streams[1].candidates[0]; + if (parse_stun_server_addr(server,&ss,&ss_len)<0){ ms_error("Fail to parser stun server address: %s",server); return; @@ -651,20 +510,20 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ usleep(10000); #endif - if (recvStunResponse(sock1,call->audio_params.natd_addr, - &call->audio_params.natd_port,&id)>0){ + if (recvStunResponse(sock1,ac->addr, + &ac->port,&id)>0){ ms_message("STUN test result: local audio port maps to %s:%i", - call->audio_params.natd_addr, - call->audio_params.natd_port); + ac->addr, + ac->port); if (id==11) cone_audio=TRUE; got_audio=TRUE; } - if (recvStunResponse(sock2,call->video_params.natd_addr, - &call->video_params.natd_port,&id)>0){ + if (recvStunResponse(sock2,vc->addr, + &vc->port,&id)>0){ ms_message("STUN test result: local video port maps to %s:%i", - call->video_params.natd_addr, - call->video_params.natd_port); + vc->addr, + vc->port); if (id==22) cone_video=TRUE; got_video=TRUE; @@ -678,7 +537,8 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ }else{ if (!cone_audio) { ms_warning("NAT is symmetric for audio port"); - call->audio_params.natd_port=0; + ac->addr[0]='\0'; + ac->port=0; } } if (sock2>=0){ @@ -687,7 +547,8 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ }else{ if (!cone_video) { ms_warning("NAT is symmetric for video port."); - call->video_params.natd_port=0; + vc->addr[0]='\0'; + vc->port=0; } } } diff --git a/coreapi/presence.c b/coreapi/presence.c index fc8f46b74..ffff0f209 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -18,26 +18,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "linphonecore.h" -#include -#include #include "private.h" extern const char *__policy_enum_to_str(LinphoneSubscribePolicy pol); -void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, int did, int nid){ +void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, SalOp *op){ LinphoneFriend *fl=linphone_friend_new_with_addr(subscriber); if (fl==NULL) return ; - fl->in_did=did; - linphone_friend_set_nid(fl,nid); + fl->insub=op; linphone_friend_set_inc_subscribe_policy(fl,LinphoneSPAccept); fl->inc_subscribe_pending=TRUE; lc->subscribers=ms_list_append(lc->subscribers,(void *)fl); if (lc->vtable.new_unknown_subscriber!=NULL) { - char *subscriber=linphone_address_as_string(fl->uri); - lc->vtable.new_unknown_subscriber(lc,fl,subscriber); - ms_free(subscriber); + char *tmp=linphone_address_as_string(fl->uri); + lc->vtable.new_unknown_subscriber(lc,fl,tmp); + ms_free(tmp); } } @@ -45,167 +42,131 @@ void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf){ linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPDeny); } -static void __do_notify(void * data, void * user_data){ - int *tab=(int*)user_data; - LinphoneFriend *lf=(LinphoneFriend*)data; - linphone_friend_notify(lf,tab[0],tab[1]); -} - -void __linphone_core_notify_all_friends(LinphoneCore *lc, int ss, int os){ - int tab[2]; - tab[0]=ss; - tab[1]=os; - ms_list_for_each2(lc->friends,__do_notify,(void *)tab); -} - void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os){ + MSList *elem; ms_message("Notifying all friends that we are in status %i",os); - __linphone_core_notify_all_friends(lc,EXOSIP_SUBCRSTATE_ACTIVE,os); + for(elem=lc->friends;elem!=NULL;elem=elem->next){ + LinphoneFriend *lf=(LinphoneFriend *)elem->data; + if (lf->insub){ + linphone_friend_notify(lf,os); + } + } } -/* check presence state before answering to call; returns TRUE if we can proceed, else answer the appropriate answer -to close the dialog*/ -bool_t linphone_core_check_presence(LinphoneCore *lc){ - return TRUE; -} - -void linphone_subscription_new(LinphoneCore *lc, eXosip_event_t *ev){ +void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ LinphoneFriend *lf=NULL; - osip_from_t *from=ev->request->from; char *tmp; - osip_message_t *msg=NULL; LinphoneAddress *uri; - osip_from_to_str(ev->request->from,&tmp); - uri=linphone_address_new(tmp); - ms_message("Receiving new subscription from %s.",tmp); + + uri=linphone_address_new(from); + linphone_address_clean(uri); + tmp=linphone_address_as_string(uri); + ms_message("Receiving new subscription from %s.",from); /* check if we answer to this subscription */ if (linphone_find_friend(lc->friends,uri,&lf)!=NULL){ - lf->in_did=ev->did; - linphone_friend_set_nid(lf,ev->nid); - eXosip_insubscription_build_answer(ev->tid,202,&msg); - eXosip_insubscription_send_answer(ev->tid,202,msg); - __eXosip_wakeup_event(); + lf->insub=op; + lf->inc_subscribe_pending=TRUE; + sal_subscribe_accept(op); linphone_friend_done(lf); /*this will do all necessary actions */ }else{ /* check if this subscriber is in our black list */ if (linphone_find_friend(lc->subscribers,uri,&lf)){ if (lf->pol==LinphoneSPDeny){ ms_message("Rejecting %s because we already rejected it once.",from); - eXosip_insubscription_send_answer(ev->tid,401,NULL); + sal_subscribe_decline(op); } else { /* else it is in wait for approval state, because otherwise it is in the friend list.*/ ms_message("New subscriber found in friend list, in %s state.",__policy_enum_to_str(lf->pol)); } }else { - eXosip_insubscription_build_answer(ev->tid,202,&msg); - eXosip_insubscription_send_answer(ev->tid,202,msg); - linphone_core_add_subscriber(lc,tmp,ev->did,ev->nid); + sal_subscribe_accept(op); + linphone_core_add_subscriber(lc,tmp,op); } } - osip_free(tmp); + ms_free(tmp); } -void linphone_notify_recv(LinphoneCore *lc, eXosip_event_t *ev) -{ +void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeState ss, SalPresenceStatus sal_status){ const char *status=_("Gone"); const char *img="sip-closed.png"; char *tmp; LinphoneFriend *lf; LinphoneAddress *friend=NULL; - osip_from_t *from=NULL; - osip_body_t *body=NULL; - LinphoneOnlineStatus estatus=LINPHONE_STATUS_UNKNOWN; - ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid); - if (ev->request!=NULL){ - from=ev->request->from; - osip_message_get_body(ev->request,0,&body); - if (body==NULL){ - ms_error("No body in NOTIFY"); - return; - } - if (strstr(body->body,"pending")!=NULL){ - status=_("Waiting for Approval"); - img="sip-wfa.png"; - estatus=LINPHONE_STATUS_PENDING; - }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) { - status=_("Online"); - img="sip-online.png"; - estatus=LINPHONE_STATUS_ONLINE; - }else if (strstr(body->body,"busy")!=NULL){ - status=_("Busy"); - img="sip-busy.png"; - estatus=LINPHONE_STATUS_BUSY; - }else if (strstr(body->body,"berightback")!=NULL - || strstr(body->body,"in-transit")!=NULL ){ - status=_("Be Right Back"); - img="sip-bifm.png"; - estatus=LINPHONE_STATUS_BERIGHTBACK; - }else if (strstr(body->body,"away")!=NULL){ - status=_("Away"); - img="sip-away.png"; - estatus=LINPHONE_STATUS_AWAY; - }else if (strstr(body->body,"onthephone")!=NULL - || strstr(body->body,"on-the-phone")!=NULL){ - status=_("On The Phone"); - img="sip-otp.png"; - estatus=LINPHONE_STATUS_ONTHEPHONE; - }else if (strstr(body->body,"outtolunch")!=NULL - || strstr(body->body,"meal")!=NULL){ - status=_("Out To Lunch"); - img="sip-otl.png"; - estatus=LINPHONE_STATUS_OUTTOLUNCH; - }else if (strstr(body->body,"closed")!=NULL){ - status=_("Closed"); - img="sip-away.png"; - estatus=LINPHONE_STATUS_CLOSED; - }else{ + LinphoneOnlineStatus estatus=LINPHONE_STATUS_OFFLINE; + + switch(sal_status){ + case SalPresenceOffline: status=_("Gone"); img="sip-closed.png"; estatus=LINPHONE_STATUS_OFFLINE; - } - ms_message("We are notified that sip:%s@%s has online status %s",from->url->username,from->url->host,status); + break; + case SalPresenceOnline: + status=_("Online"); + img="sip-online.png"; + estatus=LINPHONE_STATUS_ONLINE; + break; + case SalPresenceBusy: + status=_("Busy"); + img="sip-busy.png"; + estatus=LINPHONE_STATUS_BUSY; + break; + case SalPresenceBerightback: + status=_("Away"); + img="sip-away.png"; + estatus=LINPHONE_STATUS_AWAY; + break; + case SalPresenceAway: + status=_("Away"); + img="sip-away.png"; + estatus=LINPHONE_STATUS_AWAY; + break; + case SalPresenceOnthephone: + status=_("On The Phone"); + img="sip-otp.png"; + estatus=LINPHONE_STATUS_ONTHEPHONE; + break; + case SalPresenceOuttolunch: + status=_("Out To Lunch"); + img="sip-otl.png"; + estatus=LINPHONE_STATUS_OUTTOLUNCH; + break; + case SalPresenceDonotdisturb: + status=_("Busy"); + img="sip-busy.png"; + estatus=LINPHONE_STATUS_BUSY; + break; + case SalPresenceMoved: + case SalPresenceAltService: + status=_("Away"); + img="sip-away.png"; + estatus=LINPHONE_STATUS_AWAY; + break; } - lf=linphone_find_friend_by_sid(lc->friends,ev->sid); + lf=linphone_find_friend_by_out_subscribe(lc->friends,op); if (lf!=NULL){ friend=lf->uri; tmp=linphone_address_as_string(friend); lf->status=estatus; lc->vtable.notify_recv(lc,(LinphoneFriend*)lf,tmp,status,img); ms_free(tmp); - if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) { - lf->sid=-1; - lf->out_did=-1; - ms_message("Outgoing subscription terminated by remote."); - } }else{ ms_message("But this person is not part of our friend list, so we don't care."); } + if (ss==SalSubscribeTerminated){ + sal_op_release(op); + if (lf) + lf->outsub=NULL; + } } -void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev){ +void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){ LinphoneFriend *lf; - osip_from_t *from=ev->response->to; - char *tmp; - osip_from_to_str(from,&tmp); - LinphoneAddress *uri=linphone_address_new(tmp); - linphone_find_friend(lc->friends,uri,&lf); + lf=linphone_find_friend_by_inc_subscribe(lc->friends,op); + sal_op_release(op); if (lf!=NULL){ - lf->out_did=ev->did; - linphone_friend_set_sid(lf,ev->sid); + lf->insub=NULL; }else{ - ms_warning("Receiving answer for unknown subscribe sip:%s@%s", from->url->username,from->url->host); - } - ms_free(tmp); -} -void linphone_subscription_closed(LinphoneCore *lc,eXosip_event_t *ev){ - LinphoneFriend *lf; - osip_from_t *from=ev->request->from; - lf=linphone_find_friend_by_nid(lc->friends,ev->nid); - if (lf!=NULL){ - lf->in_did=-1; - linphone_friend_set_nid(lf,-1); - }else{ - ms_warning("Receiving unsuscribe for unknown in-subscribtion from sip:%s@%s", from->url->username, from->url->host); + ms_warning("Receiving unsuscribe for unknown in-subscribtion from %s", sal_op_get_from(op)); } } diff --git a/coreapi/private.h b/coreapi/private.h index 667fdb7ac..abea80b82 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -99,7 +99,10 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphoneOnlineS int linphone_online_status_to_eXosip(LinphoneOnlineStatus os); -void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os); +void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os); +LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op); +LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op); + int set_lock_file(); int get_lock_file(); @@ -107,7 +110,7 @@ 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_setup_local_rtp_profile(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); @@ -135,10 +138,11 @@ static inline void set_string(char **dest, const char *src){ #define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 +SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os); void linphone_process_authentication(LinphoneCore* lc, SalOp *op); void linphone_authentication_ok(LinphoneCore *lc, SalOp *op); -void linphone_subscription_new(LinphoneCore *lc, SalOp *op); -void linphone_notify_recv(LinphoneCore *lc, SalOp *op); +void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from); +void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeState ss, SalPresenceStatus status); void linphone_proxy_config_process_authentication_failure(LinphoneCore *lc, SalOp *op); void linphone_subscription_answered(LinphoneCore *lc, SalOp *op); @@ -164,7 +168,8 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len); -/*internal use only */ +void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg); + void linphone_core_start_media_streams(LinphoneCore *lc, struct _LinphoneCall *call); void linphone_core_stop_media_streams(LinphoneCore *lc, struct _LinphoneCall *call); const char * linphone_core_get_identity(LinphoneCore *lc); @@ -206,8 +211,8 @@ struct _LinphoneAuthInfo char *userid; char *passwd; char *ha1; + int usecount; bool_t works; - bool_t first_time; }; struct _LinphoneChatRoom{ @@ -224,7 +229,6 @@ struct _LinphoneFriend{ SalOp *outsub; LinphoneSubscribePolicy pol; LinphoneOnlineStatus status; - struct _LinphoneProxyConfig *proxy; struct _LinphoneCore *lc; BuddyInfo *info; char *refkey; @@ -356,7 +360,6 @@ struct _LinphoneCore struct _VideoStream *videostream; struct _VideoStream *previewstream; RtpTransport *a_rtp,*a_rtcp; - struct _RtpProfile *local_profile; MSList *bl_reqs; MSList *subscribers; /* unknown subscribers */ int minutes_away; diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 437c85e60..69ebc7634 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -20,8 +20,6 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) #include "linphonecore.h" #include "sipsetup.h" -#include -#include #include "lpconfig.h" #include "private.h" @@ -40,7 +38,6 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc){ void linphone_proxy_config_init(LinphoneProxyConfig *obj){ memset(obj,0,sizeof(LinphoneProxyConfig)); - obj->rid=-1; obj->expires=3600; } @@ -72,8 +69,8 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->ssctx!=NULL) sip_setup_context_free(obj->ssctx); if (obj->realm!=NULL) ms_free(obj->realm); if (obj->type!=NULL) ms_free(obj->type); - if (obj->contact_addr!=NULL) ms_free(obj->contact_addr); if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix); + if (obj->op) sal_op_release(obj->op); } /** @@ -83,79 +80,6 @@ bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj){ return obj->registered; } -void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port){ - if (cfg->registered){ - *ip=cfg->contact_addr; - *port=cfg->contact_port; - }else{ - *ip=NULL; - *port=0; - } -} - -static void update_contact(LinphoneProxyConfig *cfg, const char *ip, const char *port){ - if (cfg->contact_addr){ - ms_free(cfg->contact_addr); - } - cfg->contact_addr=ms_strdup(ip); - if (port!=NULL) - cfg->contact_port=atoi(port); - else cfg->contact_port=5060; -} - -bool_t linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyConfig *obj, osip_message_t *orig_request, osip_message_t *last_answer){ - osip_message_t *msg; - const char *rport,*received; - osip_via_t *via=NULL; - osip_generic_param_t *param=NULL; - osip_contact_t *ctt=NULL; - osip_message_get_via(last_answer,0,&via); - if (!via) return FALSE; - osip_via_param_get_byname(via,"rport",¶m); - if (param) rport=param->gvalue; - else return FALSE; - param=NULL; - osip_via_param_get_byname(via,"received",¶m); - if (param) received=param->gvalue; - else return FALSE; - osip_message_get_contact(orig_request,0,&ctt); - if (strcmp(ctt->url->host,received)==0){ - /*ip address matches, check ports*/ - const char *contact_port=ctt->url->port; - const char *via_rport=rport; - if (via_rport==NULL || strlen(via_rport)>0) - via_rport="5060"; - if (contact_port==NULL || strlen(contact_port)>0) - contact_port="5060"; - if (strcmp(contact_port,via_rport)==0){ - ms_message("Register has up to date contact, doing nothing."); - return FALSE; - }else ms_message("ports do not match, need to update the register (%s <> %s)", contact_port,via_rport); - } - eXosip_lock(); - msg=NULL; - eXosip_register_build_register(obj->rid,obj->expires,&msg); - if (msg==NULL){ - eXosip_unlock(); - ms_warning("Fail to create a contact updated register."); - return FALSE; - } - osip_message_get_contact(msg,0,&ctt); - if (ctt->url->host!=NULL){ - osip_free(ctt->url->host); - } - ctt->url->host=osip_strdup(received); - if (ctt->url->port!=NULL){ - osip_free(ctt->url->port); - } - ctt->url->port=osip_strdup(rport); - eXosip_register_send_register(obj->rid,msg); - eXosip_unlock(); - update_contact(obj,received,rport); - ms_message("Resending new register with updated contact %s:%s",received,rport); - return TRUE; -} - /** * Sets the proxy address * @@ -165,19 +89,18 @@ bool_t linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyCo * - hostnames : sip:sip.example.net **/ int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr){ - int err; - osip_from_t *url; + LinphoneAddress *addr; if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); obj->reg_proxy=NULL; if (server_addr!=NULL && strlen(server_addr)>0){ - osip_from_init(&url); - err=osip_from_parse(url,server_addr); - if (err==0 && url->url->host!=NULL){ + addr=linphone_address_new(server_addr); + if (addr){ obj->reg_proxy=ms_strdup(server_addr); + linphone_address_destroy(addr); }else{ ms_warning("Could not parse %s",server_addr); + return -1; } - osip_from_free(url); } return 0; } @@ -191,30 +114,30 @@ int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char * * The REGISTER messages will have from and to set to this identity. * **/ -void linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity){ - int err=0; - osip_from_t *url=NULL; +int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity){ + LinphoneAddress *addr; if (identity!=NULL && strlen(identity)>0){ - osip_from_init(&url); - err=osip_from_parse(url,identity); - if (err<0 || url->url->host==NULL || url->url->username==NULL){ - ms_warning("Could not parse %s",identity); - osip_from_free(url); - return; + addr=linphone_address_new(identity); + if (!addr || linphone_address_get_username(addr)==NULL){ + ms_warning("Invalid sip identity: %s",identity); + if (addr) + linphone_address_destroy(addr); + return -1; + }else{ + if (obj->reg_identity!=NULL) { + ms_free(obj->reg_identity); + obj->reg_identity=NULL; + } + obj->reg_identity=ms_strdup(identity); + if (obj->realm){ + ms_free(obj->realm); + } + obj->realm=ms_strdup(linphone_address_get_domain(addr)); + linphone_address_destroy(addr); + return 0; } - } else err=-2; - if (obj->reg_identity!=NULL) { - ms_free(obj->reg_identity); - obj->reg_identity=NULL; } - if (err==-2) obj->reg_identity=NULL; - else { - obj->reg_identity=ms_strdup(identity); - if (obj->realm) - ms_free(obj->realm); - obj->realm=ms_strdup(url->url->host); - } - if (url) osip_from_free(url); + return -1; } const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){ @@ -226,37 +149,14 @@ const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){ * When a route is set, all outgoing calls will go to the route's destination if this proxy * is the default one (see linphone_core_set_default_proxy() ). **/ -void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route) +int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route) { - int err; - osip_uri_param_t *lr_param=NULL; - osip_route_t *rt=NULL; - char *tmproute=NULL; - if (route!=NULL && strlen(route)>0){ - osip_route_init(&rt); - err=osip_route_parse(rt,route); - if (err<0){ - ms_warning("Could not parse %s",route); - osip_route_free(rt); - return ; - } - if (obj->reg_route!=NULL) { - ms_free(obj->reg_route); - obj->reg_route=NULL; - } - - /* check if the lr parameter is set , if not add it */ - osip_uri_uparam_get_byname(rt->url, "lr", &lr_param); - if (lr_param==NULL){ - osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL); - osip_route_to_str(rt,&tmproute); - obj->reg_route=ms_strdup(tmproute); - osip_free(tmproute); - }else obj->reg_route=ms_strdup(route); - }else{ - if (obj->reg_route!=NULL) ms_free(obj->reg_route); + if (obj->reg_route!=NULL){ + ms_free(obj->reg_route); obj->reg_route=NULL; } + obj->reg_route=ms_strdup(route); + return 0; } bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *obj){ @@ -304,15 +204,10 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){ * linphone_proxy_config_done() to commit the changes. **/ void linphone_proxy_config_edit(LinphoneProxyConfig *obj){ - obj->auth_failures=0; if (obj->reg_sendregister){ /* unregister */ if (obj->registered) { - osip_message_t *msg; - eXosip_lock(); - eXosip_register_build_register(obj->rid,0,&msg); - eXosip_register_send_register(obj->rid,msg); - eXosip_unlock(); + sal_unregister(obj->op); obj->registered=FALSE; } } @@ -329,13 +224,10 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ if (obj->reg_identity!=NULL) id_str=obj->reg_identity; else id_str=linphone_core_get_primary_contact(obj->lc); if (obj->reg_sendregister){ - char *ct=NULL; - osip_message_t *msg=NULL; - eXosip_lock(); - obj->rid=eXosip_register_build_initial_register(id_str,obj->reg_proxy,NULL,obj->expires,&msg); - eXosip_register_send_register(obj->rid,msg); - eXosip_unlock(); - if (ct!=NULL) osip_free(ct); + if (obj->op) + sal_op_release(obj->op); + obj->op=sal_op_new(obj->lc->sal); + sal_register(obj->op,obj->reg_proxy,obj->reg_identity,obj->expires); } } @@ -484,170 +376,13 @@ void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm } int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, - LinphoneOnlineStatus presence_mode) -{ - osip_message_t *pub; - int i; - const char *from=NULL; - char buf[5000]; - - if (proxy->publish==FALSE) return 0; - - if (proxy!=NULL) { - from=linphone_proxy_config_get_identity(proxy); - } - if (from==NULL) from=linphone_core_get_primary_contact(proxy->lc); - - if (presence_mode==LINPHONE_STATUS_ONLINE) - { - snprintf(buf, 5000, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ -%s\n\ -online\n\ -\n\ -", - from, from); - } - else if (presence_mode==LINPHONE_STATUS_BUSY - ||presence_mode==LINPHONE_STATUS_NOT_DISTURB) - { - snprintf(buf, 5000, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - busy\n\ -\n\ -\n\ -%s\n\ -busy\n\ -\n\ -", - from, from); - } - else if (presence_mode==LINPHONE_STATUS_BERIGHTBACK) - { - snprintf(buf, 5000, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - in-transit\n\ -\n\ -\n\ -%s\n\ -be right back\n\ -\n\ -", - from,from); - } - else if (presence_mode==LINPHONE_STATUS_AWAY - ||presence_mode==LINPHONE_STATUS_MOVED - ||presence_mode==LINPHONE_STATUS_ALT_SERVICE) - { - snprintf(buf, 5000, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - away\n\ -\n\ -\n\ -%s\n\ -away\n\ -\n\ -", - from, from); - } - else if (presence_mode==LINPHONE_STATUS_ONTHEPHONE) - { - snprintf(buf, 5000, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - on-the-phone\n\ -\n\ -\n\ -%s\n\ -on the phone\n\ -\n\ -", - from, from); - } - else if (presence_mode==LINPHONE_STATUS_OUTTOLUNCH) - { - snprintf(buf, 5000, "\n\ -\n\ -\n\ -\n\ -open\n\ -\n\ - meal\n\ -\n\ -\n\ -%s\n\ -out to lunch\n\ -\n\ -", - from, from); - } - else if (presence_mode==LINPHONE_STATUS_OFFLINE) - { - /* */ - snprintf(buf, 5000, "\n\ -\n%s", - from, -"\n\ -\n\ -closed\n\ -\n\ - permanent-absence\n\ -\n\ -\n\ -\n\ -\n\n"); - } - - i = eXosip_build_publish(&pub, (char *)from, (char *)from, NULL, "presence", "1800", "application/pidf+xml", buf); - - if (i<0) - { - ms_message("Failed to build publish request."); - return -1; - } - - eXosip_lock(); - i = eXosip_publish(pub, from); /* should update the sip-if-match parameter - from sip-etag from last 200ok of PUBLISH */ - eXosip_unlock(); - if (i<0) - { - ms_message("Failed to send publish request."); - return -1; - } - return 0; + LinphoneOnlineStatus presence_mode){ + int err; + SalOp *op=sal_op_new(proxy->lc->sal); + err=sal_publish(op,linphone_proxy_config_get_identity(proxy), + linphone_proxy_config_get_identity(proxy),linphone_online_status_to_sal(presence_mode)); + sal_op_release(op); + return err; } @@ -657,13 +392,15 @@ entity=\"%s\">\n%s", **/ int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ if (!linphone_proxy_config_check(lc,cfg)) return -1; + if (ms_list_find(lc->sip_conf.proxies,cfg)!=NULL){ + ms_warning("ProxyConfig already entered, ignored."); + return 0; + } lc->sip_conf.proxies=ms_list_append(lc->sip_conf.proxies,(void *)cfg); linphone_proxy_config_apply(cfg,lc); return 0; } -extern void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg); - /** * Removes a proxy configuration. * @@ -671,7 +408,6 @@ extern void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, Linphone * on a deleted list. For that reason, a removed proxy does NOT need to be freed. **/ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ - MSList *elem; lc->sip_conf.proxies=ms_list_remove(lc->sip_conf.proxies,(void *)cfg); /* add to the list of destroyed proxies, so that the possible unREGISTER request can succeed authentication */ lc->sip_conf.deleted_proxies=ms_list_append(lc->sip_conf.deleted_proxies,(void *)cfg); @@ -680,11 +416,6 @@ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cf if (lc->default_proxy==cfg){ lc->default_proxy=NULL; } - /* invalidate all references to this proxy in our friend list */ - for (elem=lc->friends;elem!=NULL;elem=ms_list_next(elem)){ - linphone_friend_check_for_removed_proxy((LinphoneFriend*)elem->data,cfg); - } - } /** * Erase all proxies from config. @@ -735,23 +466,6 @@ int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **conf return pos; } -static int rid_compare(const void *pcfg,const void *prid){ - const LinphoneProxyConfig *cfg=(const LinphoneProxyConfig*)pcfg; - const int *rid=(const int*)prid; - ms_message("cfg= %s, cfg->rid=%i, rid=%i",cfg->reg_proxy, cfg->rid, *rid); - return cfg->rid-(*rid); -} - -LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid){ - MSList *elem=ms_list_find_custom(lc->sip_conf.proxies,rid_compare, &rid); - if (elem==NULL){ - ms_message("linphone_core_get_proxy_config_from_rid: searching in deleted proxies..."); - elem=ms_list_find_custom(lc->sip_conf.deleted_proxies,rid_compare, &rid); - } - if (elem==NULL) return NULL; - else return (LinphoneProxyConfig*)elem->data; -} - /** * Returns an unmodifiable list of entered proxy configurations. **/ @@ -759,47 +473,6 @@ const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc){ return lc->sip_conf.proxies; } - -void linphone_proxy_config_process_authentication_failure(LinphoneCore *lc, int code, eXosip_event_t *ev){ - if (code==403) { - LinphoneProxyConfig *cfg=linphone_core_get_proxy_config_from_rid(lc, ev->rid); - if (cfg){ - cfg->auth_failures++; - /*restart a new register so that the user gets a chance to be prompted for a password*/ - if (cfg->auth_failures==1){ - linphone_proxy_config_register(cfg); - } - } - } else { - //unknown error (possibly timeout) - char *prx_realm=NULL,*www_realm=NULL; - osip_proxy_authenticate_t *prx_auth; - osip_www_authenticate_t *www_auth; - osip_message_t *req=ev->request; - char *username; - username=osip_uri_get_username(req->from->url); - prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&req->proxy_authenticates,0); - www_auth=(osip_proxy_authenticate_t*)osip_list_get(&req->www_authenticates,0); - if (prx_auth!=NULL) - prx_realm=osip_proxy_authenticate_get_realm(prx_auth); - if (www_auth!=NULL) - www_realm=osip_www_authenticate_get_realm(www_auth); - - if (prx_realm==NULL && www_realm==NULL){ - ms_warning("No realm in the client request."); - return; - } - LinphoneAuthInfo *as=NULL; - /* see if we already have this auth information , not to ask it everytime to the user */ - if (prx_realm!=NULL) - as=linphone_core_find_auth_info(lc,prx_realm,username); - if (www_realm!=NULL) - as=linphone_core_find_auth_info(lc,www_realm,username); - - if (as) as->first_time=TRUE; - } -} - void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyConfig *obj, int index) { char key[50]; diff --git a/coreapi/sal.c b/coreapi/sal.c index 6ff25bc10..d33124e8a 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -99,6 +99,10 @@ void sal_op_set_user_pointer(SalOp *op, void *up){ ((SalOpBase*)op)->user_pointer=up; } +Sal *sal_op_get_sal(const SalOp *op){ + return ((SalOpBase*)op)->root; +} + const char *sal_op_get_from(const SalOp *op){ return ((SalOpBase*)op)->from; } @@ -119,6 +123,10 @@ void *sal_op_get_user_pointer(const SalOp *op){ return ((SalOpBase*)op)->user_pointer; } +const char *sal_op_get_proxy(const SalOp *op){ + return ((SalOpBase*)op)->route; +} + void __sal_op_init(SalOp *b, Sal *sal){ memset(b,0,sizeof(SalOpBase)); ((SalOpBase*)b)->root=sal; diff --git a/coreapi/sal.h b/coreapi/sal.h index ebd8bc1e0..5dc91efd7 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -82,6 +82,13 @@ typedef enum{ SalProtoRtpSavp }SalMediaProto; +typedef struct SalEndpointCandidate{ + char addr[64]; + int port; +}SalEndpointCandidate; + +#define SAL_ENDPOINT_CANDIDATE_MAX 2 + typedef struct SalStreamDescription{ SalMediaProto proto; SalStreamType type; @@ -90,6 +97,7 @@ typedef struct SalStreamDescription{ MSList *payloads; //user_data=(void*)((long)n); #define payload_type_get_number(pt) ((int)(long)(pt)->user_data) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 6056533b9..88e502751 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -55,6 +55,39 @@ static void sal_remove_register(Sal *sal, int rid){ } } +static void sal_add_pending_auth(Sal *sal, SalOp *op){ + sal->pending_auths=ms_list_append(sal->pending_auths,op); +} + + +static void sal_remove_pending_auth(Sal *sal, SalOp *op){ + sal->pending_auths=ms_list_remove(sal->pending_auths,op); +} + +void sal_exosip_fix_route(SalOp *op){ + if (sal_op_get_route(op)!=NULL){ + osip_route_t *rt=NULL; + osip_uri_param_t *lr_param=NULL; + + osip_route_init(&rt); + if (osip_route_parse(rt,sal_op_get_route(op))<0){ + ms_warning("Bad route %s!",sal_op_get_route(op)); + sal_op_set_route(op,NULL); + }else{ + /* check if the lr parameter is set , if not add it */ + osip_uri_uparam_get_byname(rt->url, "lr", &lr_param); + if (lr_param==NULL){ + char *tmproute; + osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL); + osip_route_to_str(rt,&tmproute); + sal_op_set_route(op,tmproute); + osip_free(tmproute); + } + } + osip_route_free(rt); + } +} + SalOp * sal_op_new(Sal *sal){ SalOp *op=ms_new(SalOp,1); __sal_op_init(op,sal); @@ -78,6 +111,9 @@ void sal_op_release(SalOp *op){ if (op->cid!=-1){ eXosip_call_set_reference(op->cid,NULL); } + if (op->pending_auth){ + sal_remove_pending_auth(op->base.root,op); + } __sal_op_free(op); } @@ -174,8 +210,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){ ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub; if (ctx->callbacks.dtmf_received==NULL) ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub; - if (ctx->callbacks.presence_changed==NULL) - ctx->callbacks.presence_changed=(SalOnPresenceChanged)unimplemented_stub; + if (ctx->callbacks.notify==NULL) + ctx->callbacks.notify=(SalOnNotify)unimplemented_stub; if (ctx->callbacks.subscribe_received==NULL) ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub; if (ctx->callbacks.text_received==NULL) @@ -215,6 +251,10 @@ void sal_use_session_timers(Sal *ctx, int expires){ ctx->session_expires=expires; } +MSList *sal_get_pending_auths(Sal *sal){ + return ms_list_copy(sal->pending_auths); +} + static void set_sdp(osip_message_t *sip,sdp_message_t *msg){ int sdplen; @@ -277,7 +317,8 @@ int sal_call(SalOp *h, const char *from, const char *to){ osip_message_t *invite=NULL; sal_op_set_from(h,from); sal_op_set_to(h,to); - err=eXosip_call_build_initial_invite(&invite,to,from,h->base.route,"Phone call"); + sal_exosip_fix_route(h); + err=eXosip_call_build_initial_invite(&invite,to,from,sal_op_get_route(h),"Phone call"); if (err!=0){ ms_error("Could not create call."); return -1; @@ -625,6 +666,13 @@ static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **us return 0; } +int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){ + if (op->pending_auth){ + return get_auth_data(op->pending_auth,realm,username); + } + return -1; +} + static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){ SalOp *op; const char *username,*realm; @@ -637,6 +685,7 @@ static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){ if (op->pending_auth!=NULL) eXosip_event_free(op->pending_auth); op->pending_auth=ev; + sal_add_pending_auth (sal,op); sal->callbacks.auth_requested(op,realm,username); return FALSE; } @@ -1129,6 +1178,8 @@ int sal_iterate(Sal *sal){ int sal_register(SalOp *h, const char *proxy, const char *from, int expires){ osip_message_t *msg; + sal_op_set_route(h,proxy); + sal_exosip_fix_route(h); if (h->rid==-1){ eXosip_lock(); h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(h),expires,&msg); @@ -1143,6 +1194,16 @@ int sal_register(SalOp *h, const char *proxy, const char *from, int expires){ return 0; } +int sal_unregister(SalOp *h){ + osip_message_t *msg=NULL; + eXosip_lock(); + eXosip_register_build_register(h->rid,0,&msg); + if (msg) eXosip_register_send_register(h->rid,msg); + else ms_warning("Could not build unREGISTER !"); + eXosip_unlock(); + return 0; +} + SalAddress * sal_address_new(const char *uri){ diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index a2bae79f4..4e5d81240 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -33,6 +33,7 @@ struct Sal{ MSList *registers;/*MSList of SalOp */ MSList *out_subscribes;/*MSList of SalOp */ MSList *in_subscribes;/*MSList of SalOp */ + MSList *pending_auths;/*MSList of SalOp */ int running; int session_expires; void *up; @@ -60,5 +61,7 @@ void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev); void sal_exosip_notify_recv(Sal *sal,eXosip_event_t *ev); void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev); +void sal_exosip_fix_route(SalOp *op); + #endif diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index d6ecc8839..d4ab7ba41 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -97,6 +97,7 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to){ sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); + sal_exosip_fix_route(op); eXosip_lock(); eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op), sal_op_get_route(op),"presence",600); @@ -142,31 +143,6 @@ int sal_subscribe_decline(SalOp *op){ return 0; } -static eXosip_ss_status_t sal_presence_to_exosip(SalPresenceStatus s){ - switch(s){ - case SalPresenceOffline: - return EXOSIP_NOTIFY_CLOSED; - case SalPresenceOnline: - return EXOSIP_NOTIFY_ONLINE; - case SalPresenceBusy: - return EXOSIP_NOTIFY_BUSY; - case SalPresenceBerightback: - return EXOSIP_NOTIFY_BERIGHTBACK; - case SalPresenceAway: - return EXOSIP_NOTIFY_AWAY; - case SalPresenceOnthephone: - return EXOSIP_NOTIFY_ONTHEPHONE; - case SalPresenceOuttolunch: - return EXOSIP_NOTIFY_OUTTOLUNCH; - case SalPresenceDonotdisturb: - return EXOSIP_NOTIFY_BUSY; - case SalPresenceMoved: - case SalPresenceAltService: - default: - return EXOSIP_NOTIFY_AWAY; - } -} - static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status) { char buf[1000]; @@ -435,14 +411,14 @@ entity=\"%s\">\n%s", int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){ osip_message_t *msg; - eXosip_ss_status_t ss; + eXosip_ss_t ss=EXOSIP_SUBCRSTATE_ACTIVE; if (op->nid==-1){ ms_warning("Cannot notify, subscription was closed."); return -1; } - ss=sal_presence_to_exosip(status); + eXosip_lock(); - eXosip_insubscription_build_notify(op->did,ss,0,&msg); + eXosip_insubscription_build_notify(op->did,ss,DEACTIVATED,&msg); if (msg!=NULL){ const char *identity=sal_op_get_contact(op); if (identity==NULL) identity=sal_op_get_to(op); @@ -454,6 +430,172 @@ int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_ return 0; } +int sal_notify_close(SalOp *op){ + osip_message_t *msg; + eXosip_lock(); + eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg); + if (msg!=NULL){ + const char *identity=sal_op_get_contact(op); + if (identity==NULL) identity=sal_op_get_to(op); + osip_message_set_contact(msg,identity); + eXosip_insubscription_send_request(op->did,msg); + }else ms_error("could not create notify for incoming subscription."); + eXosip_unlock(); + return 0; +} + +int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus presence_mode){ + osip_message_t *pub; + int i; + char buf[1024]; + + if (presence_mode==SalPresenceOnline) + { + snprintf(buf, sizeof(buf), "\n\ + \n\ + \n\ + \n\ + open\n\ + \n\ + %s\n\ + online\n\ + \n\ + ", + from, from); + } + else if (presence_mode==SalPresenceBusy + ||presence_mode==SalPresenceDonotdisturb) + { + snprintf(buf, sizeof(buf), "\n\ + \n\ + \n\ + \n\ + open\n\ + \n\ + busy\n\ + \n\ + \n\ + %s\n\ + busy\n\ + \n\ + ", + from, from); + } + else if (presence_mode==SalPresenceBerightback) + { + snprintf(buf, sizeof(buf), "\n\ + \n\ + \n\ + \n\ + open\n\ + \n\ + in-transit\n\ + \n\ + \n\ + %s\n\ + be right back\n\ + \n\ + ", + from,from); + } + else if (presence_mode==SalPresenceAway + ||presence_mode==SalPresenceMoved) + { + snprintf(buf, sizeof(buf), "\n\ + \n\ + \n\ + \n\ + open\n\ + \n\ + away\n\ + \n\ + \n\ + %s\n\ + away\n\ + \n\ + ", + from, from); + } + else if (presence_mode==SalPresenceOnthephone) + { + snprintf(buf, sizeof(buf), "\n\ + \n\ + \n\ + \n\ + open\n\ + \n\ + on-the-phone\n\ + \n\ + \n\ + %s\n\ + on the phone\n\ + \n\ + ", + from, from); + } + else if (presence_mode==SalPresenceOuttolunch) + { + snprintf(buf, sizeof(buf), "\n\ + \n\ + \n\ + \n\ + open\n\ + \n\ + meal\n\ + \n\ + \n\ + %s\n\ + out to lunch\n\ + \n\ + ", + from, from); + } + else{ + /* offline */ + snprintf(buf, sizeof(buf), "\n\ + \n%s", + from, + "\n\ + \n\ + closed\n\ + \n\ + permanent-absence\n\ + \n\ + \n\ + \n\ + \n\n"); + } + + i = eXosip_build_publish(&pub,from, to, NULL, "presence", "1800", "application/pidf+xml", buf); + if (i<0){ + ms_warning("Failed to build publish request."); + return -1; + } + + eXosip_lock(); + i = eXosip_publish(pub, to); /* should update the sip-if-match parameter + from sip-etag from last 200ok of PUBLISH */ + eXosip_unlock(); + if (i<0){ + ms_message("Failed to send publish request."); + return -1; + } + return 0; +} + void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){ SalOp *op=sal_op_new(sal); char *tmp; @@ -521,7 +663,7 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){ op->did=-1; ms_message("And outgoing subscription terminated by remote."); } - sal->callbacks.presence_changed(op,estatus,NULL); + sal->callbacks.notify(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL); osip_free(tmp); } @@ -545,3 +687,4 @@ void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){ op->did=0; } + diff --git a/coreapi/sal_eXosip2_sdp.c b/coreapi/sal_eXosip2_sdp.c index 2aed6283a..d517a7222 100644 --- a/coreapi/sal_eXosip2_sdp.c +++ b/coreapi/sal_eXosip2_sdp.c @@ -153,10 +153,29 @@ static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt) static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){ - const char *mt=desc->type==SAL_AUDIO ? "audio" : "video"; + const char *mt=desc->type==SalAudio ? "audio" : "video"; const MSList *elem; + const char *addr; + int port; + if (desc->candidates[0].addr[0]!='\0'){ + addr=desc->candidates[0].addr; + port=desc->candidates[0].port; + }else{ + addr=desc->addr; + port=desc->port; + } + /*only add a c= line within the stream description if address are differents*/ + if (strcmp(addr,sdp_message_c_addr_get(msg, -1, 0))!=0){ + bool_t inet6; + if (strchr(addr,':')!=NULL){ + inet6=TRUE; + }else inet6=FALSE; + sdp_message_c_connection_add (msg, lineno, + osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"), + osip_strdup (addr), NULL, NULL); + } sdp_message_m_media_add (msg, osip_strdup (mt), - int_2char (desc->port), NULL, + int_2char (port), NULL, osip_strdup ("RTP/AVP")); sdp_message_b_bandwidth_add (msg, lineno, osip_strdup ("AS"), int_2char(desc->bandwidth)); @@ -222,12 +241,12 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){ mtype = sdp_message_m_media_get(msg, i); proto = sdp_message_m_proto_get (msg, i); port = sdp_message_m_port_get(msg, i); - stream->proto=SAL_PROTO_UNKNOWN; + stream->proto=SalProtoUnknown; if (proto){ if (strcasecmp(proto,"RTP/AVP")==0) - stream->proto=SAL_PROTO_RTP_AVP; + stream->proto=SalProtoRtpAvp; else if (strcasecmp(proto,"RTP/SAVP")==0){ - stream->proto=SAL_PROTO_RTP_SAVP; + stream->proto=SalProtoRtpSavp; } } addr = sdp_message_c_addr_get (msg, i, 0); @@ -235,10 +254,10 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){ strncpy(stream->addr,addr,sizeof(stream->addr)); stream->ptime=_sdp_message_get_a_ptime(msg,i); if (strcasecmp("audio", mtype) == 0){ - stream->type=SAL_AUDIO; + stream->type=SalAudio; }else if (strcasecmp("video", mtype) == 0){ - stream->type=SAL_VIDEO; - }else stream->type=SAL_OTHER; + stream->type=SalVideo; + }else stream->type=SalOther; for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){ if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth); } diff --git a/mediastreamer2 b/mediastreamer2 index a11023fbc..8dae09b11 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a11023fbcc2ba355d40d474cc6b863e29a4960fb +Subproject commit 8dae09b11ee8a0fe29674944b207b5e06fb0f4ed diff --git a/oRTP b/oRTP index fd65d8401..da176d2f4 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit fd65d84014c4cb3c500952c2f4b42dc4630ac37d +Subproject commit da176d2f439f990012a1bf47b39fb72070dbd580