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;
}
}
refresh_exosip_auth_info(lc);
/* if the user was prompted, re-allow automatic_action */
- if (lc->automatic_action>0) lc->automatic_action--;
}
#include "linphonecore.h"
#include "private.h"
+#include "mediastreamer2/mediastream.h"
static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){
if (lc->vtable.show)
}
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;
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);
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);
}
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;
}
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 */
}
}
-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");
}
}
-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)
}
}
-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;
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);
}
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;
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){
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)
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);
}
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,
dtmf_received,
refer_received,
text_received,
- presence_changed,
+ notify,
subscribe_received,
+ subscribe_closed,
internal_message
};
#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){
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);
}
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;
case LINPHONE_STATUS_PENDING:
str=_("Pending");
break;
- case LINPHONE_STATUS_CLOSED:
- str=_("Closed");
- break;
default:
str=_("Unknown-bug");
}
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;
}
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;
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;
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;
}
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);
}
{
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 ;
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);
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;
}
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);
}
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){
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)
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;
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");
}
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);
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);
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)
}LinphoneSubscribePolicy;
typedef enum _LinphoneOnlineStatus{
- LINPHONE_STATUS_UNKNOWN,
+ LINPHONE_STATUS_OFFLINE,
LINPHONE_STATUS_ONLINE,
LINPHONE_STATUS_BUSY,
LINPHONE_STATUS_BERIGHTBACK,
LINPHONE_STATUS_NOT_DISTURB,
LINPHONE_STATUS_MOVED,
LINPHONE_STATUS_ALT_SERVICE,
- LINPHONE_STATUS_OFFLINE,
LINPHONE_STATUS_PENDING,
- LINPHONE_STATUS_CLOSED,
LINPHONE_STATUS_END
}LinphoneOnlineStatus;
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);
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
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 */
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");
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;
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;
}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){
}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;
}
}
}
*/
#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);
}
}
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));
}
}
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();
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);
#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);
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);
char *userid;
char *passwd;
char *ha1;
+ int usecount;
bool_t works;
- bool_t first_time;
};
struct _LinphoneChatRoom{
SalOp *outsub;
LinphoneSubscribePolicy pol;
LinphoneOnlineStatus status;
- struct _LinphoneProxyConfig *proxy;
struct _LinphoneCore *lc;
BuddyInfo *info;
char *refkey;
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;
#include "linphonecore.h"
#include "sipsetup.h"
-#include <eXosip2/eXosip.h>
-#include <osipparser2/osip_message.h>
#include "lpconfig.h"
#include "private.h"
void linphone_proxy_config_init(LinphoneProxyConfig *obj){
memset(obj,0,sizeof(LinphoneProxyConfig));
- obj->rid=-1;
obj->expires=3600;
}
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);
}
/**
return obj->registered;
}
-void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port){
- if (cfg->registered){
- *ip=cfg->contact_addr;
- *port=cfg->contact_port;
- }else{
- *ip=NULL;
- *port=0;
- }
-}
-
-static void update_contact(LinphoneProxyConfig *cfg, const char *ip, const char *port){
- if (cfg->contact_addr){
- ms_free(cfg->contact_addr);
- }
- cfg->contact_addr=ms_strdup(ip);
- if (port!=NULL)
- cfg->contact_port=atoi(port);
- else cfg->contact_port=5060;
-}
-
-bool_t linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyConfig *obj, osip_message_t *orig_request, osip_message_t *last_answer){
- osip_message_t *msg;
- const char *rport,*received;
- osip_via_t *via=NULL;
- osip_generic_param_t *param=NULL;
- osip_contact_t *ctt=NULL;
- osip_message_get_via(last_answer,0,&via);
- if (!via) return FALSE;
- osip_via_param_get_byname(via,"rport",¶m);
- if (param) rport=param->gvalue;
- else return FALSE;
- param=NULL;
- osip_via_param_get_byname(via,"received",¶m);
- if (param) received=param->gvalue;
- else return FALSE;
- osip_message_get_contact(orig_request,0,&ctt);
- if (strcmp(ctt->url->host,received)==0){
- /*ip address matches, check ports*/
- const char *contact_port=ctt->url->port;
- const char *via_rport=rport;
- if (via_rport==NULL || strlen(via_rport)>0)
- via_rport="5060";
- if (contact_port==NULL || strlen(contact_port)>0)
- contact_port="5060";
- if (strcmp(contact_port,via_rport)==0){
- ms_message("Register has up to date contact, doing nothing.");
- return FALSE;
- }else ms_message("ports do not match, need to update the register (%s <> %s)", contact_port,via_rport);
- }
- eXosip_lock();
- msg=NULL;
- eXosip_register_build_register(obj->rid,obj->expires,&msg);
- if (msg==NULL){
- eXosip_unlock();
- ms_warning("Fail to create a contact updated register.");
- return FALSE;
- }
- osip_message_get_contact(msg,0,&ctt);
- if (ctt->url->host!=NULL){
- osip_free(ctt->url->host);
- }
- ctt->url->host=osip_strdup(received);
- if (ctt->url->port!=NULL){
- osip_free(ctt->url->port);
- }
- ctt->url->port=osip_strdup(rport);
- eXosip_register_send_register(obj->rid,msg);
- eXosip_unlock();
- update_contact(obj,received,rport);
- ms_message("Resending new register with updated contact %s:%s",received,rport);
- return TRUE;
-}
-
/**
* Sets the proxy address
*
* - 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;
}
* 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){
* 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){
* 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;
}
}
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);
}
}
}
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;
}
**/
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.
*
* 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);
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.
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.
**/
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];
((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;
}
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;
SalProtoRtpSavp
}SalMediaProto;
+typedef struct SalEndpointCandidate{
+ char addr[64];
+ int port;
+}SalEndpointCandidate;
+
+#define SAL_ENDPOINT_CANDIDATE_MAX 2
+
typedef struct SalStreamDescription{
SalMediaProto proto;
SalStreamType type;
MSList *payloads; //<list of PayloadType
int bandwidth;
int ptime;
+ SalEndpointCandidate candidates[SAL_ENDPOINT_CANDIDATE_MAX];
} SalStreamDescription;
#define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4
/*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;
SalPresenceAltService,
}SalPresenceStatus;
+typedef enum SalSubscribeState{
+ SalSubscribeActive,
+ SalSubscribeTerminated
+}SalSubscribeState;
+
typedef void (*SalOnCallReceived)(SalOp *op);
typedef void (*SalOnCallRinging)(SalOp *op);
typedef void (*SalOnCallAccepted)(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{
SalOnDtmfReceived dtmf_received;
SalOnRefer refer_received;
SalOnTextReceived text_received;
- SalOnPresenceChanged presence_changed;
+ SalOnNotify notify;
SalOnSubscribeReceived subscribe_received;
+ SalOnSubscribeClosed subscribe_closed;
SalOnInternalMsg internal_message;
}SalCallbacks;
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);
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*/
/*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)
}
}
+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);
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);
}
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)
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;
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;
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;
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;
}
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);
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){
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;
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
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);
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];
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);
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;
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);
}
op->did=0;
}
+
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));
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);
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);
}
-Subproject commit a11023fbcc2ba355d40d474cc6b863e29a4960fb
+Subproject commit 8dae09b11ee8a0fe29674944b207b5e06fb0f4ed
-Subproject commit fd65d84014c4cb3c500952c2f4b42dc4630ac37d
+Subproject commit da176d2f439f990012a1bf47b39fb72070dbd580