]> sjero.net Git - linphone/commitdiff
sal in progress, near to code complete.
authorSimon Morlat <simon.morlat@linphone.org>
Fri, 5 Feb 2010 17:42:34 +0000 (18:42 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Fri, 5 Feb 2010 17:42:34 +0000 (18:42 +0100)
18 files changed:
coreapi/authentication.c
coreapi/callbacks.c
coreapi/chat.c
coreapi/friend.c
coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/misc.c
coreapi/presence.c
coreapi/private.h
coreapi/proxy.c
coreapi/sal.c
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2.h
coreapi/sal_eXosip2_presence.c
coreapi/sal_eXosip2_sdp.c
mediastreamer2
oRTP

index ee360ecfe0f966a86415f4f813a0771a87a04432..e55ab495a4aac80d1843fcf5fbd93133d1365e3c 100644 (file)
@@ -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--;
 }
 
 
index 08267a30d5205791481e69524d37655ba732f7f4..a95f3570dc142e05bc538380c6eb7addbe30382a 100644 (file)
@@ -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
 };
 
index 95526274c82b29da23b60811ae2fe81df98e0cc1..11c3c978f4106b85598c25a7110665e98d850f1a 100644 (file)
@@ -24,7 +24,6 @@
  
  #include "linphonecore.h"
  #include "private.h"
- #include <eXosip2/eXosip.h>
  
  LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to){
        LinphoneAddress *parsed_url=NULL;
  
 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);
 }
 
 
index 08f072de31b8309b6f86750d0273360f7fd4241b..5dd51bec55449d69b3384bd8fe10f8e4e6168b70 100644 (file)
@@ -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");
-       }
-       eXosip_lock();
-       eXosip_subscribe_build_initial_request(&msg,friend,from,route,"presence",600);
-       eXosip_subscribe_send_initial_request(msg);
-       eXosip_unlock();
+               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;
+       }
+       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;
-}
-
-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;
+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 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, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"open\" />\n\
-<msnsubstatus substatus=\"online\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", contact_info, atom_id, contact_info);
-
-    }
-  else if (online_status==LINPHONE_STATUS_BUSY)
-    {
-      sprintf(buf, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"inuse\" />\n\
-<msnsubstatus substatus=\"busy\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", contact_info, atom_id, contact_info);
-
-    }
-  else if (online_status==LINPHONE_STATUS_BERIGHTBACK)
-    {
-      sprintf(buf, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"inactive\" />\n\
-<msnsubstatus substatus=\"berightback\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", contact_info, atom_id, contact_info);
-
-    }
-  else if (online_status==LINPHONE_STATUS_AWAY)
-    {
-      sprintf(buf, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"inactive\" />\n\
-<msnsubstatus substatus=\"away\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", contact_info, atom_id, contact_info);
-
-    }
-  else if (online_status==LINPHONE_STATUS_ONTHEPHONE)
-    {
-      sprintf(buf, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"inuse\" />\n\
-<msnsubstatus substatus=\"onthephone\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", contact_info, atom_id, contact_info);
-
-    }
-  else if (online_status==LINPHONE_STATUS_OUTTOLUNCH)
-    {
-      sprintf(buf, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"inactive\" />\n\
-<msnsubstatus substatus=\"outtolunch\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", contact_info, atom_id, contact_info);
-
-    }
-  else
-    {
-      sprintf(buf, "<?xml version=\"1.0\"?>\n\
-<!DOCTYPE presence\n\
-PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
-<presence>\n\
-<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
-<atom id=\"%i\">\n\
-<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
-<status status=\"inactive\" />\n\
-<msnsubstatus substatus=\"away\" />\n\
-</address>\n\
-</atom>\n\
-</presence>", 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, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>online</note>\n\
-</tuple>\n\
-</presence>",
-             contact_info, contact_info);
-    }
-  else if (online_status==LINPHONE_STATUS_BUSY)
-    {
-      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>busy</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>busy</note>\n\
-</tuple>\n\
-</presence>",
-             contact_info, contact_info);
-    }
-  else if (online_status==LINPHONE_STATUS_BERIGHTBACK)
-    {
-      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>in-transit</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>be right back</note>\n\
-</tuple>\n\
-</presence>",
-             contact_info, contact_info);
-    }
-  else if (online_status==LINPHONE_STATUS_AWAY)
-    {
-      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>away</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>away</note>\n\
-</tuple>\n\
-</presence>",
-             contact_info, contact_info);
-    }
-  else if (online_status==LINPHONE_STATUS_ONTHEPHONE)
-    {
-      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>on-the-phone</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>on the phone</note>\n\
-</tuple>\n\
-</presence>",
-             contact_info, contact_info);
-    }
-  else if (online_status==LINPHONE_STATUS_OUTTOLUNCH)
-    {
-      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>meal</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>out to lunch</note>\n\
-</tuple>\n\
-</presence>",
-             contact_info, contact_info);
-    }
-  else
-    {
-      /* */
-      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-entity=\"%s\">\n%s",
-             contact_info,
-"<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>closed</basic>\n\
-<es:activities>\n\
-  <es:activity>permanent-absence</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-</tuple>\n\
-\n</presence>\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){
index 98f6d811fff509870a4cb2ac6fe4f6321a72470f..cf16e8da37171071bcbf01fc165cc4ace3f81029 100644 (file)
@@ -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)
index e277fc0df4f869b9dd88d1b56eeac41f7701dae4..2c2f5c582cba1cf319be6d4c3eeabc8549d32f28 100644 (file)
@@ -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 */
index 9bdb9042057ac5f495f327c3dc837a1af3868ec4..f0cf871fd2d38fbcb8fad537f25cf77e00ffe273 100644 (file)
@@ -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;
                                }
                        }
                }
index fc8f46b74a7fe01c4102ba44b5a1f8f667501be3..ffff0f20925b85aa9280c3c2ff5c2d9319731e4e 100644 (file)
@@ -18,26 +18,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
 #include "linphonecore.h"
-#include <eXosip2/eXosip.h>
-#include <osipparser2/osip_message.h>
 #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);
-}
-
-/* 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;
+       for(elem=lc->friends;elem!=NULL;elem=elem->next){
+               LinphoneFriend *lf=(LinphoneFriend *)elem->data;
+               if (lf->insub){
+                       linphone_friend_notify(lf,os);
+               }
+       }
 }
 
-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)) {
+       LinphoneOnlineStatus estatus=LINPHONE_STATUS_OFFLINE;
+       
+       switch(sal_status){
+               case SalPresenceOffline:
+                       status=_("Gone");
+                       img="sip-closed.png";
+                       estatus=LINPHONE_STATUS_OFFLINE;
+               break;
+               case SalPresenceOnline:
                        status=_("Online");
                        img="sip-online.png";
                        estatus=LINPHONE_STATUS_ONLINE;
-               }else if (strstr(body->body,"busy")!=NULL){
+               break;
+               case SalPresenceBusy:
                        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){
+               break;
+               case SalPresenceBerightback:
                        status=_("Away");
                        img="sip-away.png";
                        estatus=LINPHONE_STATUS_AWAY;
-               }else if (strstr(body->body,"onthephone")!=NULL
-                       || strstr(body->body,"on-the-phone")!=NULL){
+               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;
-               }else if (strstr(body->body,"outtolunch")!=NULL
-                               || strstr(body->body,"meal")!=NULL){
+               break;
+               case SalPresenceOuttolunch:
                        status=_("Out To Lunch");
                        img="sip-otl.png";
                        estatus=LINPHONE_STATUS_OUTTOLUNCH;
-               }else if (strstr(body->body,"closed")!=NULL){
-                       status=_("Closed");
+               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_CLOSED;
-               }else{
-                       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);
+                       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.");
        }
-}
-
-void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev){
-       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);
-       if (lf!=NULL){
-               lf->out_did=ev->did;
-               linphone_friend_set_sid(lf,ev->sid);
-       }else{
-               ms_warning("Receiving answer for unknown subscribe sip:%s@%s", from->url->username,from->url->host);
+       if (ss==SalSubscribeTerminated){
+               sal_op_release(op);
+               if (lf)
+                       lf->outsub=NULL;
        }
-       ms_free(tmp);
 }
-void linphone_subscription_closed(LinphoneCore *lc,eXosip_event_t *ev){
+
+void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){
        LinphoneFriend *lf;
-       osip_from_t *from=ev->request->from;
-       lf=linphone_find_friend_by_nid(lc->friends,ev->nid);
+       lf=linphone_find_friend_by_inc_subscribe(lc->friends,op);
+       sal_op_release(op);
        if (lf!=NULL){
-               lf->in_did=-1;
-               linphone_friend_set_nid(lf,-1);
+               lf->insub=NULL;
        }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));
        }
 }
index 667fdb7ac06ce7a6bd9300031cad6b1dcbeebae4..abea80b8292b642567ff82ee41b1dee387bdf7bd 100644 (file)
@@ -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;
index 437c85e60eac472a9254f0074cbab57cd6a5efa6..69ebc76344a9ed9e49cff75c23a67bc729190d5c 100644 (file)
@@ -20,8 +20,6 @@ Copyright (C) 2000  Simon MORLAT (simon.morlat@linphone.org)
  
 #include "linphonecore.h"
 #include "sipsetup.h"
-#include <eXosip2/eXosip.h>
-#include <osipparser2/osip_message.h>
 #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",&param);
-       if (param) rport=param->gvalue;
-       else return FALSE;
-       param=NULL;
-       osip_via_param_get_byname(via,"received",&param);
-       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, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>online</note>\n\
-</tuple>\n\
-</presence>",
-              from, from);
-    }
-  else if (presence_mode==LINPHONE_STATUS_BUSY
-          ||presence_mode==LINPHONE_STATUS_NOT_DISTURB)
-    {
-      snprintf(buf, 5000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>busy</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>busy</note>\n\
-</tuple>\n\
-</presence>",
-             from, from);
-    }
-  else if (presence_mode==LINPHONE_STATUS_BERIGHTBACK)
-    {
-      snprintf(buf, 5000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>in-transit</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>be right back</note>\n\
-</tuple>\n\
-</presence>",
-             from,from);
-    }
-  else if (presence_mode==LINPHONE_STATUS_AWAY
-          ||presence_mode==LINPHONE_STATUS_MOVED
-          ||presence_mode==LINPHONE_STATUS_ALT_SERVICE)
-    {
-      snprintf(buf, 5000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>away</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>away</note>\n\
-</tuple>\n\
-</presence>",
-             from, from);
-    }
-  else if (presence_mode==LINPHONE_STATUS_ONTHEPHONE)
-    {
-      snprintf(buf, 5000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>on-the-phone</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>on the phone</note>\n\
-</tuple>\n\
-</presence>",
-             from, from);
-    }
-  else if (presence_mode==LINPHONE_STATUS_OUTTOLUNCH)
-    {
-      snprintf(buf, 5000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-          entity=\"%s\">\n\
-<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>open</basic>\n\
-<es:activities>\n\
-  <es:activity>meal</es:activity>\n\
-</es:activities>\n\
-</status>\n\
-<contact priority=\"0.8\">%s</contact>\n\
-<note>out to lunch</note>\n\
-</tuple>\n\
-</presence>",
-             from, from);
-    }
-  else if (presence_mode==LINPHONE_STATUS_OFFLINE)
-    {
-      /* */
-      snprintf(buf, 5000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
-xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
-entity=\"%s\">\n%s",
-             from,
-"<tuple id=\"sg89ae\">\n\
-<status>\n\
-<basic>closed</basic>\n\
-<es:activities>\n\
-  <es:activity>permanent-absence</e:activity>\n\
-</es:activities>\n\
-</status>\n\
-</tuple>\n\
-\n</presence>\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];
index 6ff25bc10dd45fe23341896a16faaaa79c97f174..d33124e8a4216316de90acf9af7ad4c11d75dacb 100644 (file)
@@ -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;
index ebd8bc1e0342993ae1683af56b357346b034a721..5dc91efd756188fe51563410ee5055544f190475 100644 (file)
@@ -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; //<list of PayloadType
        int bandwidth;
        int ptime;
+       SalEndpointCandidate candidates[SAL_ENDPOINT_CANDIDATE_MAX];
 } SalStreamDescription;
 
 #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4
@@ -112,7 +120,7 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
 /*this structure must be at the first byte of the SalOp structure defined by implementors*/
 typedef struct SalOpBase{
        Sal *root;
-       char *route;
+       char *route; /*or request-uri for REGISTER*/
        char *contact;
        char *from;
        char *to;
@@ -154,6 +162,11 @@ typedef enum SalPresenceStatus{
        SalPresenceAltService,
 }SalPresenceStatus;
 
+typedef enum SalSubscribeState{
+       SalSubscribeActive,
+       SalSubscribeTerminated
+}SalSubscribeState;
+
 typedef void (*SalOnCallReceived)(SalOp *op);
 typedef void (*SalOnCallRinging)(SalOp *op);
 typedef void (*SalOnCallAccepted)(SalOp *op);
@@ -169,8 +182,9 @@ 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 (*SalOnPresenceChanged)(SalOp *op, SalPresenceStatus status, const char *msg);
-typedef void (*SalOnSubscribeReceived)(SalOp *sal, const char *from);
+typedef void (*SalOnNotify)(SalOp *op, SalSubscribeState ss, SalPresenceStatus status, const char *msg);
+typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *from);
+typedef void (*SalOnSubscribeClosed)(SalOp *salop, const char *from);
 typedef void (*SalOnInternalMsg)(Sal *sal, const char *msg);
 
 typedef struct SalCallbacks{
@@ -189,8 +203,9 @@ typedef struct SalCallbacks{
        SalOnDtmfReceived dtmf_received;
        SalOnRefer refer_received;
        SalOnTextReceived text_received;
-       SalOnPresenceChanged presence_changed;
+       SalOnNotify notify;
        SalOnSubscribeReceived subscribe_received;
+       SalOnSubscribeClosed subscribe_closed;
        SalOnInternalMsg internal_message;
 }SalCallbacks;
 
@@ -207,11 +222,13 @@ void sal_set_user_agent(Sal *ctx, const char *user_agent);
 void sal_masquerade(Sal *ctx, const char *ip);
 void sal_use_session_timers(Sal *ctx, int expires);
 int sal_iterate(Sal *sal);
+MSList * sal_get_pending_auths(Sal *sal);
 
 /*create an operation */
 SalOp * sal_op_new(Sal *sal);
 
 /*generic SalOp API, working for all operations */
+Sal *sal_op_get_sal(const SalOp *op);
 void sal_op_set_contact(SalOp *op, const char *contact);
 void sal_op_set_route(SalOp *op, const char *route);
 void sal_op_set_from(SalOp *op, const char *from);
@@ -219,10 +236,12 @@ void sal_op_set_to(SalOp *op, const char *to);
 void sal_op_release(SalOp *h);
 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
 void sal_op_set_user_pointer(SalOp *h, void *up);
+int sal_op_get_auth_requested(SalOp *h, const char **realm, const char **username);
 const char *sal_op_get_from(const SalOp *op);
 const char *sal_op_get_to(const SalOp *op);
 const char *sal_op_get_contact(const SalOp *op);
 const char *sal_op_get_route(const SalOp *op);
+const char *sal_op_get_proxy(const SalOp *op);
 void *sal_op_get_user_pointer(const SalOp *op);
 
 /*Call API*/
@@ -238,16 +257,21 @@ int sal_call_terminate(SalOp *h);
 
 /*Registration*/
 int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
+int sal_unregister(SalOp *h);
 
 /*Messaging */
 int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
 
 /*presence Subscribe/notify*/
 int sal_subscribe_presence(SalOp *op, const char *from, const char *to);
+int sal_unsubscribe(SalOp *op);
 int sal_subscribe_accept(SalOp *op);
 int sal_subscribe_decline(SalOp *op);
 int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message);
+int sal_notify_close(SalOp *op);
 
+/*presence publish */
+int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status);
 
 #define payload_type_set_number(pt,n)  (pt)->user_data=(void*)((long)n);
 #define payload_type_get_number(pt)            ((int)(long)(pt)->user_data)
index 6056533b953e3e0629a6e56c0d88041f1af6da05..88e5027518209c051af2693f9e03d6acff39200a 100644 (file)
@@ -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){
index a2bae79f4678d5c2b1ca3a85714d35ebda123388..4e5d8124015719daf1d920627a6557d7c3700d64 100644 (file)
@@ -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
index d6ecc8839e0211a3b766aa30b8d7fd52066c5c02..d4ab7ba4181efc5749bae00b24471ecb0527e1ab 100644 (file)
@@ -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), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+                 entity=\"%s\">\n\
+       <tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>open</basic>\n\
+       </status>\n\
+       <contact priority=\"0.8\">%s</contact>\n\
+       <note>online</note>\n\
+       </tuple>\n\
+       </presence>",
+                  from, from);
+       }
+       else if (presence_mode==SalPresenceBusy
+          ||presence_mode==SalPresenceDonotdisturb)
+       {
+         snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+                 xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
+                 entity=\"%s\">\n\
+       <tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>open</basic>\n\
+       <es:activities>\n\
+       <es:activity>busy</es:activity>\n\
+       </es:activities>\n\
+       </status>\n\
+       <contact priority=\"0.8\">%s</contact>\n\
+       <note>busy</note>\n\
+       </tuple>\n\
+       </presence>",
+                 from, from);
+       }
+       else if (presence_mode==SalPresenceBerightback)
+       {
+               snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+                 xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
+                 entity=\"%s\">\n\
+       <tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>open</basic>\n\
+       <es:activities>\n\
+       <es:activity>in-transit</es:activity>\n\
+       </es:activities>\n\
+       </status>\n\
+       <contact priority=\"0.8\">%s</contact>\n\
+       <note>be right back</note>\n\
+       </tuple>\n\
+       </presence>",
+                 from,from);
+       }
+       else if (presence_mode==SalPresenceAway
+          ||presence_mode==SalPresenceMoved)
+       {
+               snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+                 xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
+                 entity=\"%s\">\n\
+       <tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>open</basic>\n\
+       <es:activities>\n\
+       <es:activity>away</es:activity>\n\
+       </es:activities>\n\
+       </status>\n\
+       <contact priority=\"0.8\">%s</contact>\n\
+       <note>away</note>\n\
+       </tuple>\n\
+       </presence>",
+                 from, from);
+       }
+       else if (presence_mode==SalPresenceOnthephone)
+       {
+         snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+                 xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
+                 entity=\"%s\">\n\
+       <tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>open</basic>\n\
+       <es:activities>\n\
+       <es:activity>on-the-phone</es:activity>\n\
+       </es:activities>\n\
+       </status>\n\
+       <contact priority=\"0.8\">%s</contact>\n\
+       <note>on the phone</note>\n\
+       </tuple>\n\
+       </presence>",
+                 from, from);
+       }
+       else if (presence_mode==SalPresenceOuttolunch)
+       {
+         snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+                 xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
+                 entity=\"%s\">\n\
+       <tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>open</basic>\n\
+       <es:activities>\n\
+       <es:activity>meal</es:activity>\n\
+       </es:activities>\n\
+       </status>\n\
+       <contact priority=\"0.8\">%s</contact>\n\
+       <note>out to lunch</note>\n\
+       </tuple>\n\
+       </presence>",
+                 from, from);
+       }
+       else{ 
+         /* offline */
+         snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+       <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
+       xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
+       entity=\"%s\">\n%s",
+                 from,
+       "<tuple id=\"sg89ae\">\n\
+       <status>\n\
+       <basic>closed</basic>\n\
+       <es:activities>\n\
+       <es:activity>permanent-absence</e:activity>\n\
+       </es:activities>\n\
+       </status>\n\
+       </tuple>\n\
+       \n</presence>\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;
 }
 
+
index 2aed6283a010a915ff00c67d0f0b9f9494a1cddf..d517a7222c46758beabefdaabed2f4911e067d53 100644 (file)
@@ -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);
                }
index a11023fbcc2ba355d40d474cc6b863e29a4960fb..8dae09b11ee8a0fe29674944b207b5e06fb0f4ed 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a11023fbcc2ba355d40d474cc6b863e29a4960fb
+Subproject commit 8dae09b11ee8a0fe29674944b207b5e06fb0f4ed
diff --git a/oRTP b/oRTP
index fd65d84014c4cb3c500952c2f4b42dc4630ac37d..da176d2f439f990012a1bf47b39fb72070dbd580 160000 (submodule)
--- a/oRTP
+++ b/oRTP
@@ -1 +1 @@
-Subproject commit fd65d84014c4cb3c500952c2f4b42dc4630ac37d
+Subproject commit da176d2f439f990012a1bf47b39fb72070dbd580