]> sjero.net Git - linphone/commitdiff
sal is code complete !
authorSimon Morlat <simon.morlat@linphone.org>
Wed, 27 Jan 2010 15:20:03 +0000 (16:20 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Wed, 27 Jan 2010 15:20:03 +0000 (16:20 +0100)
coreapi/Makefile.am
coreapi/sal.c [new file with mode: 0644]
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2.h [new file with mode: 0644]
coreapi/sal_eXosip2_presence.c [new file with mode: 0644]
coreapi/sal_eXosip2_sdp.c

index e46d0c492d6e55e602e96fce61e30281c87a896c..16623244825dc0551c80e02a4140dbd7d09f8157 100644 (file)
@@ -18,8 +18,9 @@ liblinphone_la_SOURCES=\
        exevents.c exevents.h \
        offeranswer.c offeranswer.h\
        sal.c sal.h \
-       sal_eXosip2.c \
+       sal_eXosip2.c sal_eXosip2.h\
        sal_eXosip2_sdp.c \
+       sal_eXosip2_presence.c \
        misc.c  \
        address.c \
        enum.c enum.h \
diff --git a/coreapi/sal.c b/coreapi/sal.c
new file mode 100644 (file)
index 0000000..7351d92
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+linphone
+Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*/
+
+/** 
+ This header files defines the Signaling Abstraction Layer.
+ The purpose of this layer is too allow experiment different call signaling 
+ protocols and implementations under linphone, for example SIP, JINGLE...
+**/
+
+#include "sal.h"
+
+SalMediaDescription *sal_media_description_new(){
+       return ms_new0(SalMediaDescription,1);
+}
+
+void sal_media_description_destroy(SalMediaDescription *md){
+       int i;
+       for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
+               ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
+               ms_list_free(md->streams[i].payloads);
+       }
+       ms_free(md);
+}
+
+static void assign_string(char **str, const char *arg){
+       if (*str){
+               ms_free(*str);
+               *str=NULL;
+       }
+       if (arg)
+               *str=ms_strdup(arg);
+}
+
+void sal_op_set_contact(SalOp *op, const char *contact){
+       assign_string(&((SalOpBase*)op)->contact,contact);
+}
+
+void sal_op_set_route(SalOp *op, const char *route){
+       assign_string(&((SalOpBase*)op)->route,route);
+}
+
+void sal_op_set_from(SalOp *op, const char *from){
+       assign_string(&((SalOpBase*)op)->from,from);
+}
+
+void sal_op_set_to(SalOp *op, const char *to){
+       assign_string(&((SalOpBase*)op)->to,to);
+}
+
+void sal_op_set_user_pointer(SalOp *op, void *up){
+       ((SalOpBase*)op)->user_pointer=up;
+}
+
+const char *sal_op_get_from(const SalOp *op){
+       return ((SalOpBase*)op)->from;
+}
+
+const char *sal_op_get_to(const SalOp *op){
+       return ((SalOpBase*)op)->to;
+}
+
+const char *sal_op_get_contact(const SalOp *op){
+       return ((SalOpBase*)op)->contact;
+}
+
+const char *sal_op_get_route(const SalOp *op){
+       return ((SalOpBase*)op)->route;
+}
+
+void *sal_op_get_user_pointer(const SalOp *op){
+       return ((SalOpBase*)op)->user_pointer;
+}
+
+void __sal_op_init(SalOp *b, Sal *sal){
+       memset(b,0,sizeof(SalOpBase));
+       ((SalOpBase*)b)->root=sal;
+}
+
+void __sal_op_free(SalOp *op){
+       SalOpBase *b=(SalOpBase *)op;
+       if (b->from) {
+               ms_free(b->from);
+               b->from=NULL;
+       }
+       if (b->to) {
+               ms_free(b->to);
+               b->to=NULL;
+       }
+       if (b->route) {
+               ms_free(b->route);
+               b->route=NULL;
+       }
+       if (b->contact) {
+               ms_free(b->contact);
+               b->contact=NULL;
+       }
+       if (b->local_media)
+               sal_media_description_destroy(b->local_media);
+       if (b->remote_media)
+               sal_media_description_destroy(b->remote_media);
+       ms_free(op);
+}
index a613cf71ebdc5601495bcec6e5c0a7f8b36a887a..ba1778e045304b6fb785aa81917e5d06c1169dac 100644 (file)
@@ -111,6 +111,7 @@ typedef struct SalOpBase{
        char *to;
        SalMediaDescription *local_media;
        SalMediaDescription *remote_media;
+       void *user_pointer;
 } SalOpBase;
 
 
@@ -160,7 +161,8 @@ 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)(Sal *sal, const char *from, SalPresenceStatus status);
+typedef void (*SalOnPresenceChanged)(SalOp *op, SalPresenceStatus status, const char *msg);
+typedef void (*SalOnSubscribeReceived)(SalOp *sal, const char *from);
 typedef void (*SalOnInternalMsg)(Sal *sal, const char *msg);
 
 typedef struct SalCallbacks{
@@ -180,6 +182,7 @@ typedef struct SalCallbacks{
        SalOnRefer refer_received;
        SalOnTextReceived text_received;
        SalOnPresenceChanged presence_changed;
+       SalOnSubscribeReceived subscribe_received;
        SalOnInternalMsg internal_message;
 }SalCallbacks;
 
@@ -206,10 +209,12 @@ void sal_op_set_from(SalOp *op, const char *from);
 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);
 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);
+void *sal_op_get_user_pointer(const SalOp *op);
 
 /*Call API*/
 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
@@ -219,8 +224,18 @@ int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optio
 const SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
 int sal_call_terminate(SalOp *h);
 
+/*Registration*/
 int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
 
+/*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_subscribe_accept(SalOp *op);
+int sal_subscribe_decline(SalOp *op);
+int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message);
+
 
 #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 d3a706d3b329d6f802edb3bfaf082b0198db4b93..efd082431331f789b10f52194fb0ef288a26f9af 100644 (file)
@@ -17,40 +17,41 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
-#include "sal.h"
-#include <eXosip2/eXosip.h>
+#include "sal_eXosip2.h"
 
 #include "offeranswer.h"
 
-extern sdp_message_t *media_description_to_sdp(const SalMediaDescription *sal);
-extern int sdp_to_media_description(sdp_message_t *sdp, SalMediaDescription *desc);
-
-struct Sal{
-       SalCallbacks callbacks;
-       int running;
-       int session_expires;
-       int automatic_action;
-};
-
-struct SalOp{
-       SalOpBase base;
-       int cid;
-       int did;
-       int tid;
-       int rid;
-       int expires;
-       SalMediaDescription *result;
-       sdp_message_t *sdp_answer;
-       eXosip_event_t *pending_auth;
-       bool_t supports_session_timers;
-       bool_t sdp_offering;
-       bool_t reinvite;
-};
+
+static SalOp * sal_find_register(Sal *sal, int rid){
+       const MSList *elem;
+       SalOp *op;
+       for(elem=sal->registers;elem!=NULL;elem=elem->next){
+               op=(SalOp*)elem->data;
+               if (op->rid==rid) return op;
+       }
+       return NULL;
+}
+
+static void sal_add_register(Sal *sal, SalOp *op){
+       sal->registers=ms_list_append(sal->registers,op);
+}
+
+static void sal_remove_register(Sal *sal, int rid){
+       MSList *elem;
+       SalOp *op;
+       for(elem=sal->registers;elem!=NULL;elem=elem->next){
+               op=(SalOp*)elem->data;
+               if (op->rid==rid) {
+                       sal->registers=ms_list_remove_link(sal->registers,elem);
+                       return;
+               }
+       }
+}
 
 SalOp * sal_op_new(Sal *sal){
        SalOp *op=ms_new(SalOp,1);
        __sal_op_init(op,sal);
-       op->cid=op->did=op->tid=-1;
+       op->cid=op->did=op->tid=op->rid=op->nid=op->sid-1;
        op->supports_session_timers=FALSE;
        op->sdp_offering=TRUE;
        op->pending_auth=NULL;
@@ -64,6 +65,9 @@ void sal_op_release(SalOp *op){
                sdp_message_free(op->sdp_answer);
        if (op->pending_auth)
                eXosip_event_free(op->pending_auth);
+       if( op->rid!=-1){
+               sal_remove_register(op->base.root,op->rid);
+       }
        __sal_op_free(op);
 }
 
@@ -107,6 +111,10 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
                ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
        if (ctx->callbacks.presence_changed==NULL)
                ctx->callbacks.presence_changed=(SalOnPresenceChanged)unimplemented_stub;
+       if (ctx->callbacks.subscribe_received==NULL)
+               ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
+       if (ctx->callbacks.text_received==NULL)
+               ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
        if (ctx->callbacks.internal_message==NULL)
                ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub;
 }
@@ -805,7 +813,7 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori
 }
 
 static void registration_success(Sal *sal, eXosip_event_t *ev){
-       SalOp *op=(SalOp*)ev->external_reference;
+       SalOp *op=sal_find_register(sal,ev->rid);
        osip_header_t *h=NULL;
        bool_t registered;
        if (op==NULL){
@@ -824,7 +832,7 @@ static void registration_success(Sal *sal, eXosip_event_t *ev){
 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
        int status_code=0;
        const char *reason=NULL;
-       SalOp *op=(SalOp*)ev->external_reference;
+       SalOp *op=sal_find_register(sal,ev->rid);
        SalReason sr=SalReasonUnknown;
        SalError se=SalErrorUnknown;
        
@@ -914,22 +922,23 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
                        }
                        break;
                case EXOSIP_IN_SUBSCRIPTION_NEW:
-                       ms_message("CALL_SUBSCRIPTION_NEW or UPDATE");
-                       linphone_subscription_new(lc,ev);
+                       ms_message("CALL_SUBSCRIPTION_NEW ");
+                       sal_exosip_subscription_recv(sal,ev);
                        break;
                case EXOSIP_SUBSCRIPTION_UPDATE:
+                       ms_message("CALL_SUBSCRIPTION_UPDATE");
                        break;
                case EXOSIP_SUBSCRIPTION_NOTIFY:
                        ms_message("CALL_SUBSCRIPTION_NOTIFY");
-                       linphone_notify_recv(lc,ev);
+                       sal_exosip_notify_recv(sal,ev);
                        break;
                case EXOSIP_SUBSCRIPTION_ANSWERED:
                        ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid);
-                       linphone_subscription_answered(lc,ev);
+                       sal_exosip_subscription_answered(sal,ev);
                        break;
                case EXOSIP_SUBSCRIPTION_CLOSED:
                        ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
-                       linphone_subscription_closed(lc,ev);
+                       sal_exosip_subscription_closed(sal,ev);
                        break;
                case EXOSIP_CALL_RELEASED:
                        ms_message("CALL_RELEASED\n");
@@ -971,20 +980,22 @@ int sal_iterate(Sal *sal){
                        eXosip_unlock();
                }
        }
+       return 0;
 }
 
 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
        osip_message_t *msg;
        if (h->rid==-1){
                eXosip_lock();
-               h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(op),expires,&msg);
+               h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(h),expires,&msg);
+               sal_add_register(h->base.root,h);
        }else{
                eXosip_lock();
                eXosip_register_build_register(h->rid,expires,&msg);    
        }
        eXosip_register_send_register(h->rid,msg);
        eXosip_unlock();
-       op->expires=expires;
+       h->expires=expires;
        return 0;
 }
 
diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h
new file mode 100644 (file)
index 0000000..c0d32fe
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+linphone
+Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*/
+
+#ifndef sal_exosip2_h
+#define sal_exosip2_h
+
+#include "sal.h"
+#include <eXosip2/eXosip.h>
+
+
+
+sdp_message_t *media_description_to_sdp(const SalMediaDescription *sal);
+int sdp_to_media_description(sdp_message_t *sdp, SalMediaDescription *desc);
+
+struct Sal{
+       SalCallbacks callbacks;
+       MSList *registers;/*MSList of SalOp */
+       MSList *out_subscribes;/*MSList of SalOp */
+       MSList *in_subscribes;/*MSList of SalOp */
+       int running;
+       int session_expires;
+       int automatic_action;
+};
+
+struct SalOp{
+       SalOpBase base;
+       int cid;
+       int did;
+       int tid;
+       int rid;
+       int sid;
+       int nid;
+       int expires;
+       SalMediaDescription *result;
+       sdp_message_t *sdp_answer;
+       eXosip_event_t *pending_auth;
+       bool_t supports_session_timers;
+       bool_t sdp_offering;
+       bool_t reinvite;
+};
+
+void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev);
+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);
+
+
+#endif
diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c
new file mode 100644 (file)
index 0000000..d6ecc88
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+linphone
+Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*/
+
+
+#include "sal_eXosip2.h"
+
+
+static SalOp * sal_find_out_subscribe(Sal *sal, int sid){
+       const MSList *elem;
+       SalOp *op;
+       for(elem=sal->out_subscribes;elem!=NULL;elem=elem->next){
+               op=(SalOp*)elem->data;
+               if (op->sid==sid) return op;
+       }
+       return NULL;
+}
+
+static void sal_add_out_subscribe(Sal *sal, SalOp *op){
+       sal->out_subscribes=ms_list_append(sal->out_subscribes,op);
+}
+
+static void sal_remove_out_subscribe(Sal *sal, int sid){
+       MSList *elem;
+       SalOp *op;
+       for(elem=sal->out_subscribes;elem!=NULL;elem=elem->next){
+               op=(SalOp*)elem->data;
+               if (op->sid==sid) {
+                       sal->out_subscribes=ms_list_remove_link(sal->out_subscribes,elem);
+                       return;
+               }
+       }
+}
+
+static SalOp * sal_find_in_subscribe(Sal *sal, int nid){
+       const MSList *elem;
+       SalOp *op;
+       for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
+               op=(SalOp*)elem->data;
+               if (op->nid==nid) return op;
+       }
+       return NULL;
+}
+
+static void sal_add_in_subscribe(Sal *sal, SalOp *op){
+       sal->in_subscribes=ms_list_append(sal->in_subscribes,op);
+}
+
+static void sal_remove_in_subscribe(Sal *sal, int nid){
+       MSList *elem;
+       SalOp *op;
+       for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
+               op=(SalOp*)elem->data;
+               if (op->nid==nid) {
+                       sal->in_subscribes=ms_list_remove_link(sal->in_subscribes,elem);
+                       return;
+               }
+       }
+}
+
+int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
+       osip_message_t *sip=NULL;
+       if (from)
+               sal_op_set_from(op,from);
+       if (to)
+               sal_op_set_to(op,to);
+
+       eXosip_lock();
+       eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
+           sal_op_get_from(op),sal_op_get_route(op));
+       osip_message_set_content_type(sip,"text/plain");
+       osip_message_set_body(sip,msg,strlen(msg));
+       eXosip_message_send_request(sip);
+       eXosip_unlock();
+       return 0;
+}
+
+/*presence Subscribe/notify*/
+int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
+       osip_message_t *msg;
+       if (from)
+               sal_op_set_from(op,from);
+       if (to)
+               sal_op_set_to(op,to);
+       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);
+       op->sid=eXosip_subscribe_send_initial_request(msg);
+       eXosip_unlock();
+       if (op->sid==-1){
+               osip_message_free(msg);
+               return -1;
+       }
+       sal_add_out_subscribe(op->base.root,op);
+       return 0;
+}
+
+int sal_unsubscribe(SalOp *op){
+       osip_message_t *msg=NULL;
+       if (op->did==-1){
+               ms_error("cannot unsubscribe, no dialog !");
+               return -1;
+       }
+       eXosip_lock();
+       eXosip_subscribe_build_refresh_request(op->did,&msg);
+       if (msg){
+               osip_message_set_expires(msg,"0");
+               eXosip_subscribe_send_refresh_request(op->did,msg);
+       }else ms_error("Could not build subscribe refresh request !");
+       eXosip_unlock();
+       return 0;
+}
+
+int sal_subscribe_accept(SalOp *op){
+       osip_message_t *msg;
+       eXosip_lock();
+       eXosip_insubscription_build_answer(op->tid,202,&msg);
+       eXosip_insubscription_send_answer(op->tid,202,msg);
+       eXosip_unlock();
+       return 0;
+}
+
+int sal_subscribe_decline(SalOp *op){
+       eXosip_lock();
+       eXosip_insubscription_send_answer(op->tid,401,NULL);
+       eXosip_unlock();
+       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];
+#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==SalPresenceOnline)
+    {
+      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==SalPresenceBusy)
+    {
+      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==SalPresenceBerightback)
+    {
+      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==SalPresenceAway)
+    {
+      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==SalPresenceOnthephone)
+    {
+      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==SalPresenceOuttolunch)
+    {
+      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==SalPresenceOnline)
+    {
+      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==SalPresenceBusy)
+    {
+      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==SalPresenceBerightback)
+    {
+      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==SalPresenceAway)
+    {
+      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==SalPresenceOnthephone)
+    {
+      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==SalPresenceOuttolunch)
+    {
+      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);
+}
+
+
+int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
+       osip_message_t *msg;
+       eXosip_ss_status_t ss;
+       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);
+       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);
+               add_presence_body(msg,status);
+               eXosip_insubscription_send_request(op->did,msg);
+       }else ms_error("could not create notify for incoming subscription.");
+       eXosip_unlock();
+       return 0;
+}
+
+void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
+       SalOp *op=sal_op_new(sal);
+       char *tmp;
+       op->did=ev->did;
+       op->tid=ev->tid;
+       op->nid=ev->nid;
+       osip_from_to_str(ev->request->from,&tmp);
+       sal_op_set_from(op,tmp);
+       ms_free(tmp);
+       osip_from_to_str(ev->request->to,&tmp);
+       sal_op_set_to(op,tmp);
+       ms_free(tmp);
+       sal_add_in_subscribe(sal,op);
+       sal->callbacks.subscribe_received(op,sal_op_get_from(op));
+}
+
+void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
+       SalOp *op=sal_find_out_subscribe(sal,ev->sid);
+       char *tmp;
+       osip_from_t *from=NULL;
+       osip_body_t *body=NULL;
+       SalPresenceStatus estatus=SalPresenceOffline;
+       
+       ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
+
+       if (op==NULL){
+               ms_error("No operation related to this notify !");
+               return;
+       }
+       if (ev->request==NULL) return;
+
+       from=ev->request->from;
+       osip_message_get_body(ev->request,0,&body);
+       if (body==NULL){
+               ms_error("No body in NOTIFY");
+               return;
+       }
+       osip_from_to_str(from,&tmp);
+       if (strstr(body->body,"pending")!=NULL){
+               estatus=SalPresenceOffline;
+       }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
+               estatus=SalPresenceOnline;
+       }else if (strstr(body->body,"busy")!=NULL){
+               estatus=SalPresenceBusy;
+       }else if (strstr(body->body,"berightback")!=NULL
+                       || strstr(body->body,"in-transit")!=NULL ){
+               estatus=SalPresenceBerightback;
+       }else if (strstr(body->body,"away")!=NULL){
+               estatus=SalPresenceAway;
+       }else if (strstr(body->body,"onthephone")!=NULL
+               || strstr(body->body,"on-the-phone")!=NULL){
+               estatus=SalPresenceOnthephone;
+       }else if (strstr(body->body,"outtolunch")!=NULL
+                       || strstr(body->body,"meal")!=NULL){
+               estatus=SalPresenceOuttolunch;
+       }else if (strstr(body->body,"closed")!=NULL){
+               estatus=SalPresenceOffline;
+       }else{
+               estatus=SalPresenceOffline;
+       }
+       ms_message("We are notified that %s has online status %i",tmp,estatus);
+       if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
+               sal_remove_out_subscribe(sal,op->sid);
+               op->sid=-1;
+               op->did=-1;
+               ms_message("And outgoing subscription terminated by remote.");
+       }
+       sal->callbacks.presence_changed(op,estatus,NULL);
+       osip_free(tmp);
+}
+
+void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev){
+       SalOp *op=sal_find_out_subscribe(sal,ev->sid);
+       if (op==NULL){
+               ms_error("Subscription answered but no associated op !");
+               return;
+       }
+       op->did=ev->did;
+}
+
+void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){
+       SalOp *op=sal_find_in_subscribe(sal,ev->sid);
+       if (op==NULL){
+               ms_error("Subscription closed but no associated op !");
+               return;
+       }
+       sal_remove_in_subscribe(sal,op->nid);
+       op->nid=-1;
+       op->did=0;
+}
+
index 68c6fd241448f79d00204bb79e6389f85093c2dd..2aed6283a010a915ff00c67d0f0b9f9494a1cddf 100644 (file)
@@ -167,7 +167,6 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
 
 sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc){
        int i;
-       char *tmp;
        sdp_message_t *msg=create_generic_sdp(desc);
        for(i=0;i<desc->nstreams;++i){
                add_line(msg,i,&desc->streams[i]);