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