Merge branch 'master' of git.savannah.nongnu.org:/srv/git/linphone

This commit is contained in:
Jehan Monnier 2010-11-04 16:45:14 +01:00
commit ff5f959ae3
11 changed files with 435 additions and 378 deletions

View file

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT([linphone],[3.3.99.7],[linphone-developers@nongnu.org])
AC_INIT([linphone],[3.3.99.9],[linphone-developers@nongnu.org])
AC_CANONICAL_SYSTEM
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])

View file

@ -110,7 +110,6 @@ static void call_received(SalOp *h){
linphone_address_clean(from_parsed);
tmp=linphone_address_as_string(from_parsed);
linphone_address_destroy(from_parsed);
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
barmesg=ortp_strdup_printf("%s %s%s",tmp,_("is contacting you"),
(sal_call_autoanswer_asked(h)) ?_(" and asked autoanswer."):_("."));
if (lc->vtable.show) lc->vtable.show(lc);
@ -146,6 +145,11 @@ static void call_received(SalOp *h){
#endif
ms_free(barmesg);
ms_free(tmp);
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){
linphone_core_accept_call(lc,call);
}
}
static void call_ringing(SalOp *h){
@ -444,8 +448,10 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
}
linphone_call_stop_media_streams (call);
if (sr!=SalReasonDeclined) linphone_call_set_state(call,LinphoneCallError,msg);
else linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
else{
call->reason=LinphoneReasonDeclined;
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
}
}
static void auth_requested(SalOp *h, const char *realm, const char *username){
@ -485,7 +491,7 @@ static void register_success(SalOp *op, bool_t registered){
char *msg;
cfg->registered=registered;
linphone_proxy_config_set_error(cfg,LinphoneErrorNone);
linphone_proxy_config_set_error(cfg,LinphoneReasonNone);
linphone_proxy_config_set_state(cfg, registered ? LinphoneRegistrationOk : LinphoneRegistrationCleared ,
registered ? "Registration sucessful" : "Unregistration done");
if (lc->vtable.display_status){
@ -514,9 +520,9 @@ static void register_failure(SalOp *op, SalError error, SalReason reason, const
ms_free(msg);
}
if (error== SalErrorFailure && reason == SalReasonForbidden) {
linphone_proxy_config_set_error(cfg, LinphoneErrorBadCredentials);
linphone_proxy_config_set_error(cfg, LinphoneReasonBadCredentials);
} else if (error == SalErrorNoResponse) {
linphone_proxy_config_set_error(cfg, LinphoneErrorNoResponse);
linphone_proxy_config_set_error(cfg, LinphoneReasonNoResponse);
}
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details);
}

View file

@ -46,13 +46,13 @@ static void stop(int signum){
/**
* presence state change notification callback
*/
static void notify_presence_recv_updated (struct _LinphoneCore *lc, LinphoneFriend *friend) {
static void notify_presence_recv_updated (LinphoneCore *lc, LinphoneFriend *friend) {
const LinphoneAddress* friend_address = linphone_friend_get_address(friend);
printf("New state state [%s] for user id [%s] \n"
,linphone_online_status_to_string(linphone_friend_get_status(friend))
,linphone_address_as_string (friend_address));
}
static void new_subscription_request (struct _LinphoneCore *lc, LinphoneFriend *friend, const char* url) {
static void new_subscription_request (LinphoneCore *lc, LinphoneFriend *friend, const char* url) {
const LinphoneAddress* friend_address = linphone_friend_get_address(friend);
printf(" [%s] wants to see your status, accepting\n"
,linphone_address_as_string (friend_address));

View file

@ -216,7 +216,10 @@ static void linphone_call_set_terminated(LinphoneCall *call){
linphone_core_update_allocated_audio_bandwidth(lc);
if (call->state==LinphoneCallEnd){
status=LinphoneCallSuccess;
if (call->reason==LinphoneReasonDeclined){
status=LinphoneCallDeclined;
}
else status=LinphoneCallSuccess;
}
linphone_call_log_completed(call->log,call, status);
@ -384,6 +387,13 @@ LinphoneCallState linphone_call_get_state(const LinphoneCall *call){
return call->state;
}
/**
* Returns the reason for a call termination (either error or normal termination)
**/
LinphoneReason linphone_call_get_reason(const LinphoneCall *call){
return call->reason;
}
/**
* Get the user_pointer in the LinphoneCall
*
@ -797,7 +807,7 @@ static void _linphone_call_start_media_streams(LinphoneCall *call, bool_t send_e
recfile,
playcard,
captcard,
send_early_media ? FALSE : linphone_core_echo_cancellation_enabled(lc));
captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc));
post_configure_audio_streams(call);
if (send_early_media) setup_ring_player(lc,call);
audio_stream_set_rtcp_information(call->audiostream, cname, tool);

View file

@ -946,6 +946,14 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
linphone_core_assign_payload_type(&payload_type_ilbc,113,"mode=30");
linphone_core_assign_payload_type(&payload_type_amr,114,"octet-align=1");
#if defined(ANDROID) || defined (__IPHONE_OS_VERSION_MIN_REQUIRED)
/*shorten the DNS lookup time and send more retransmissions on mobiles:
- to workaround potential packet losses
- to avoid hanging for 30 seconds when the network doesn't work despite the phone thinks it does.
*/
_linphone_core_configure_resolver();
#endif
#ifdef ENABLE_NONSTANDARD_GSM
{
PayloadType *pt;
@ -2332,7 +2340,9 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
call = the_call;
}
sal_call_terminate(call->op);
if (call->state==LinphoneCallIncomingReceived){
call->reason=LinphoneReasonDeclined;
}
/*stop ringing*/
if (lc->ringstream!=NULL) {
ring_stop(lc->ringstream);
@ -4011,14 +4021,16 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l
return p;
}
const char *linphone_error_to_string(LinphoneError err){
const char *linphone_error_to_string(LinphoneReason err){
switch(err){
case LinphoneErrorNone:
case LinphoneReasonNone:
return "No error";
case LinphoneErrorNoResponse:
case LinphoneReasonNoResponse:
return "No response";
case LinphoneErrorBadCredentials:
case LinphoneReasonBadCredentials:
return "Bad credentials";
case LinphoneReasonDeclined:
return "Call declined";
}
return "unknown error";
}

View file

@ -131,7 +131,8 @@ typedef enum _LinphoneCallDir LinphoneCallDir;
typedef enum _LinphoneCallStatus {
LinphoneCallSuccess, /**< The call was sucessful*/
LinphoneCallAborted, /**< The call was aborted */
LinphoneCallMissed /**< The call was missed (unanswered)*/
LinphoneCallMissed, /**< The call was missed (unanswered)*/
LinphoneCallDeclined /**< The call was declined, either locally or by remote end*/
} LinphoneCallStatus;
/**
@ -182,15 +183,16 @@ void linphone_call_params_destroy(LinphoneCallParams *cp);
/**
* Enum describing failure reasons.
**/
enum _LinphoneError{
LinphoneErrorNone,
LinphoneErrorNoResponse, /**<No response received from remote*/
LinphoneErrorBadCredentials /**<Authentication failed due to bad or missing credentials*/
enum _LinphoneReason{
LinphoneReasonNone,
LinphoneReasonNoResponse, /**<No response received from remote*/
LinphoneReasonBadCredentials, /**<Authentication failed due to bad or missing credentials*/
LinphoneReasonDeclined, /**<The call has been declined*/
};
typedef enum _LinphoneError LinphoneError;
typedef enum _LinphoneReason LinphoneReason;
const char *linphone_error_to_string(LinphoneError err);
const char *linphone_reason_to_string(LinphoneReason err);
/**
* The LinphoneCall object represents a call issued or received by the LinphoneCore
@ -200,21 +202,21 @@ typedef struct _LinphoneCall LinphoneCall;
typedef enum _LinphoneCallState{
LinphoneCallIdle,
LinphoneCallIncomingReceived,
LinphoneCallOutgoingInit,
LinphoneCallOutgoingProgress,
LinphoneCallOutgoingRinging,
LinphoneCallOutgoingEarlyMedia,
LinphoneCallConnected,
LinphoneCallStreamsRunning,
LinphoneCallPausing,
LinphoneCallPaused,
LinphoneCallResuming,
LinphoneCallRefered,
LinphoneCallError,
LinphoneCallEnd,
LinphoneCallPausedByRemote,
LinphoneCallUpdatedByRemote /**<used when video is asked by remote */
LinphoneCallIncomingReceived, /**<This is a new incoming call */
LinphoneCallOutgoingInit, /**<An outgoing call is started */
LinphoneCallOutgoingProgress, /**<An outgoing call is in progress */
LinphoneCallOutgoingRinging, /**<An outgoing call is ringing at remote end */
LinphoneCallOutgoingEarlyMedia, /**<An outgoing call is proposed early media */
LinphoneCallConnected, /**<Connected, the call is answered */
LinphoneCallStreamsRunning, /**<The media streams are established and running*/
LinphoneCallPausing, /**<The call is pausing at the initiative of local end */
LinphoneCallPaused, /**< The call is paused, remote end has accepted the pause */
LinphoneCallResuming, /**<The call is being resumed by local end*/
LinphoneCallRefered, /**<The call is being transfered to another party, resulting in a new outgoing call to follow immediately*/
LinphoneCallError, /**<The call encountered an error*/
LinphoneCallEnd, /**<The call ended normally*/
LinphoneCallPausedByRemote, /**<The call is paused by remote end*/
LinphoneCallUpdatedByRemote /**<The call's parameters are updated, used for example when video is asked by remote */
} LinphoneCallState;
const char *linphone_call_state_to_string(LinphoneCallState cs);
@ -236,7 +238,7 @@ const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *
void linphone_call_enable_camera(LinphoneCall *lc, bool_t enabled);
bool_t linphone_call_camera_enabled(const LinphoneCall *lc);
int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file);
LinphoneError linphone_call_get_error(const LinphoneCall *call);
LinphoneReason linphone_call_get_reason(const LinphoneCall *call);
const char *linphone_call_get_remote_user_agent(LinphoneCall *call);
void *linphone_call_get_user_pointer(LinphoneCall *call);
void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
@ -315,7 +317,7 @@ struct _LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig
bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg);
const char * linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg);
LinphoneError linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg);
LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg);
/* destruction is called automatically when removing the proxy config */
void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg);

View file

@ -775,3 +775,28 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
else dest="2a00:1450:8002::68";
return get_local_ip_for_with_connect(type,dest,result);
}
#ifndef WIN32
#include <resolv.h>
void _linphone_core_configure_resolver(){
/*bionic declares _res but does not define nor export it !!*/
#ifdef ANDROID
/*timeout and attempts are the same as retrans and retry, but are android specific names.*/
setenv("RES_OPTIONS","timeout:1 attempts:2 retrans:1 retry:2",1);
#else
res_init();
_res.retrans=1; /*retransmit every second*/
_res.retry=2; /*only two times per DNS server*/
#endif
}
#else
void _linphone_core_configure_resolver(){
}
#endif

View file

@ -77,6 +77,7 @@ struct _LinphoneCall
time_t start_time; /*time at which the call was initiated*/
time_t media_start_time; /*time at which it was accepted, media streams established*/
LinphoneCallState state;
LinphoneReason reason;
int refcnt;
void * user_pointer;
int audio_port;
@ -199,7 +200,7 @@ void linphone_core_stop_waiting(LinphoneCore *lc);
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy);
void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call);
extern SalCallbacks linphone_sal_callbacks;
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg,LinphoneError error);
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg, LinphoneReason error);
struct _LinphoneProxyConfig
{
@ -224,7 +225,7 @@ struct _LinphoneProxyConfig
bool_t dial_escape_plus;
void* user_data;
time_t deletion_date;
LinphoneError error;
LinphoneReason error;
};
struct _LinphoneAuthInfo
@ -439,6 +440,7 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc,
LinphoneCall *call, bool_t with_video, bool_t only_one_codec);
#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
void _linphone_core_configure_resolver();
#define HOLD_OFF (0)
#define HOLD_ON (1)

View file

@ -841,10 +841,12 @@ LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyCon
}
return NULL;
}
LinphoneError linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg) {
LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg) {
return cfg->error;
}
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg,LinphoneError error) {
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg,LinphoneReason error) {
cfg->error = error;
}

View file

@ -20,6 +20,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "sal_eXosip2.h"
typedef enum {
PIDF = 0,
RFCxxxx = 1,
MSOLDPRES = 2
} presence_type_t;
/*
* REVISIT: this static variable forces every dialog to use the same presence description type depending
* on what is received on a single dialog...
*/
static presence_type_t presence_style = PIDF;
SalOp * sal_find_out_subscribe(Sal *sal, int sid){
const MSList *elem;
@ -175,268 +186,372 @@ int sal_subscribe_decline(SalOp *op){
return 0;
}
static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
{
char buf[1000];
#ifdef SUPPORT_MSN
int atom_id = 1000;
#endif
char *contact_info;
static void mk_presence_body (const SalPresenceStatus online_status, const char *contact_info,
char *buf, size_t buflen, presence_type_t ptype) {
switch (ptype) {
case RFCxxxx: {
/* definition from http://msdn.microsoft.com/en-us/library/cc246202%28PROT.10%29.aspx */
int atom_id = 1000;
osip_from_t *from=NULL;
from=osip_message_get_from(notify);
osip_uri_to_str(from->url,&contact_info);
#ifdef SUPPORT_MSN
if (online_status==SalPresenceOnline)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
if (online_status==SalPresenceOnline)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"online\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceBusy)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
}
else if (online_status == SalPresenceBusy ||
online_status == SalPresenceDonotdisturb)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"busy\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
</atom>\n</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
}
else if (online_status==SalPresenceBerightback)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"berightback\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceAway)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
}
else if (online_status == SalPresenceAway ||
online_status == SalPresenceMoved)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"away\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
}
else if (online_status==SalPresenceOnthephone)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"onthephone\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
sprintf(buf, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence\n\
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
}
else if (online_status==SalPresenceOuttolunch)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"outtolunch\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence 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\" priority=\"0.800000\">\n\
<status status=\"closed\" />\n\
<msnsubstatus substatus=\"away\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
break;
}
case MSOLDPRES: {
/* Couldn't find schema http://schemas.microsoft.com/2002/09/sip/presence
* so messages format has been taken from Communigate that can send notify
* requests with this schema
*/
int atom_id = 1000;
if (online_status==SalPresenceOnline)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"online\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status == SalPresenceBusy ||
online_status == SalPresenceDonotdisturb)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"busy\" />\n\
</address>\n\
</atom>\n</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inactive\" />\n\
<msnsubstatus substatus=\"berightback\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status == SalPresenceAway ||
online_status == SalPresenceMoved)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inactive\" />\n\
<msnsubstatus substatus=\"idle\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"onthephone\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\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\
}
else
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\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 uri=\"%s\">\n\
<status status=\"closed\" />\n\
<msnsubstatus substatus=\"offline\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
}
}
break;
}
default: { /* use pidf+xml as default format, rfc4479, rfc4480, rfc3863 */
osip_message_set_body(notify, buf, strlen(buf));
osip_message_set_content_type(notify, "application/xpidf+xml");
#else
if (online_status==SalPresenceOnline)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status == SalPresenceBusy ||
online_status == SalPresenceDonotdisturb)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:busy/></rpid:activities>\n\
</dm:person>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:in-transit/></rpid:activities>\n\
</dm:person>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status == SalPresenceAway ||
online_status == SalPresenceMoved)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:away/></rpid:activities>\n\
</dm:person>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:on-the-phone/></rpid:activities>\n\
</dm:person>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"7777\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"78787878\">\n\
<rpid:activities><rpid:meal/></rpid:activities>\n\
<rpid:note>Out to lunch</rpid:note> \n\
</dm:person>\n\
</presence>",
contact_info, contact_info);
}
else
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>closed</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
</presence>\n", contact_info, contact_info);
}
break;
}
} // switch
if (online_status==SalPresenceOnline)
{
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>open</basic>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>online</note>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceBusy)
{
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>open</basic>\n\
<es:activities>\n\
<es:activity>busy</es:activity>\n\
</es:activities>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>busy</note>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>open</basic>\n\
<es:activities>\n\
<es:activity>in-transit</es:activity>\n\
</es:activities>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>be right back</note>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceAway)
{
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>open</basic>\n\
<es:activities>\n\
<es:activity>away</es:activity>\n\
</es:activities>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>away</note>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>open</basic>\n\
<es:activities>\n\
<es:activity>on-the-phone</es:activity>\n\
</es:activities>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>on the phone</note>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>open</basic>\n\
<es:activities>\n\
<es:activity>meal</es:activity>\n\
</es:activities>\n\
</status>\n\
<contact priority=\"0.8\">%s</contact>\n\
<note>out to lunch</note>\n\
</tuple>\n\
</presence>",
contact_info, contact_info);
}
else
{
/* */
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
entity=\"%s\">\n%s",
contact_info,
"<tuple id=\"sg89ae\">\n\
<status>\n\
<basic>closed</basic>\n\
<es:activities>\n\
<es:activity>permanent-absence</es:activity>\n\
</es:activities>\n\
</status>\n\
</tuple>\n\
\n</presence>\n");
}
osip_message_set_body(notify, buf, strlen(buf));
osip_message_set_content_type(notify, "application/pidf+xml");
}
static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
{
char buf[1000];
char *contact_info;
osip_from_t *from=NULL;
from=osip_message_get_from(notify);
osip_uri_to_str(from->url,&contact_info);
mk_presence_body (online_status, contact_info, buf, sizeof (buf), presence_style);
osip_message_set_body(notify, buf, strlen(buf));
osip_message_set_content_type(notify,
presence_style ? "application/xpidf+xml" : "application/pidf+xml");
#endif
osip_free(contact_info);
}
@ -483,137 +598,10 @@ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus p
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");
}
mk_presence_body (presence_mode, from, buf, sizeof (buf), presence_style);
i = eXosip_build_publish(&pub,from, to, NULL, "presence", "1800", "application/pidf+xml", buf);
i = eXosip_build_publish(&pub,from, to, NULL, "presence", "300",
presence_style ? "application/xpidf+xml" : "application/pidf+xml", buf);
if (i<0){
ms_warning("Failed to build publish request.");
return -1;
@ -699,7 +687,8 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
}else if (strstr(body->body,"berightback")!=NULL
|| strstr(body->body,"in-transit")!=NULL ){
estatus=SalPresenceBerightback;
}else if (strstr(body->body,"away")!=NULL){
}else if (strstr(body->body,"away")!=NULL
|| strstr(body->body,"idle")){
estatus=SalPresenceAway;
}else if (strstr(body->body,"onthephone")!=NULL
|| strstr(body->body,"on-the-phone")!=NULL){
@ -722,6 +711,15 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
ms_message("And outgoing subscription terminated by remote.");
}
sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
/* try to detect presence message style used by server,
* and switch our presence messages to servers style */
if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) {
presence_style = RFCxxxx;
} else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) {
presence_style = MSOLDPRES;
}
osip_free(tmp);
}

@ -1 +1 @@
Subproject commit dcf3eba1afa5615cb01b52b1136d8aa0d224aca2
Subproject commit ffacf56718c198cb80a290f7a65975916d8a9b6b