mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
sal is code complete !
This commit is contained in:
parent
40e4b5d421
commit
5f0a6d55d9
7 changed files with 793 additions and 38 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
118
coreapi/sal.c
Normal file
118
coreapi/sal.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
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;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
64
coreapi/sal_eXosip2.h
Normal file
64
coreapi/sal_eXosip2.h
Normal file
|
|
@ -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
|
||||
547
coreapi/sal_eXosip2_presence.c
Normal file
547
coreapi/sal_eXosip2_presence.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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]);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue