Commit fdd99cd2 authored by Simon Morlat's avatar Simon Morlat
Browse files

sal in progress, near to code complete.

parent 9fc1a85d
......@@ -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);
}
......
......@@ -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 */
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;
}
void linphone_friend_set_sid(LinphoneFriend *lf, int sid){
lf->sid=sid;
}
void linphone_friend_set_nid(LinphoneFriend *lf, int nid){
lf->nid=nid;
lf->inc_subscribe_pending=TRUE;
SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os){
switch(os){
case LINPHONE_STATUS_OFFLINE:
return SalPresenceOffline;
break;
case LINPHONE_STATUS_ONLINE:
return SalPresenceOnline;
break;
case LINPHONE_STATUS_BUSY:
return SalPresenceBusy;
break;
case LINPHONE_STATUS_BERIGHTBACK:
return SalPresenceBerightback;
break;
case LINPHONE_STATUS_AWAY:
return SalPresenceAway;
break;
case LINPHONE_STATUS_ONTHEPHONE:
return SalPresenceOnthephone;
break;
case LINPHONE_STATUS_OUTTOLUNCH:
return SalPresenceOuttolunch;
break;
case LINPHONE_STATUS_NOT_DISTURB:
return SalPresenceDonotdisturb;
break;
case LINPHONE_STATUS_MOVED:
return SalPresenceMoved;
break;
case LINPHONE_STATUS_ALT_SERVICE:
return SalPresenceAltService;
break;
case LINPHONE_STATUS_PENDING:
return SalPresenceOffline;
break;
default:
return SalPresenceOffline;
break;
}
return SalPresenceOffline;
}
void add_presence_body(osip_message_t *notify, LinphoneOnlineStatus online_status)
{
char buf[1000];
#ifdef SUPPORT_MSN
int atom_id = 1000;
#endif
char *contact_info;
osip_contact_t *ct=NULL;
osip_message_get_contact(notify,0,&ct);
osip_contact_to_str(ct,&contact_info);
#ifdef SUPPORT_MSN
if (online_status==LINPHONE_STATUS_ONLINE)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"online\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==LINPHONE_STATUS_BUSY)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"busy\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==LINPHONE_STATUS_BERIGHTBACK)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
<status status=\"inactive\" />\n\
<msnsubstatus substatus=\"berightback\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==LINPHONE_STATUS_AWAY)