mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
implement presence
This commit is contained in:
parent
6c323ddc08
commit
510f3b7200
13 changed files with 817 additions and 49 deletions
|
|
@ -59,7 +59,7 @@
|
|||
<folderInfo id="0.2131511368.593515799." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1930099439" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.MachO64" id="org.eclipse.cdt.build.core.prefbase.toolchain.1930099439.714963030" name=""/>
|
||||
<builder arguments="CFLAGS="-g -Wall -Werror -Wno-deprecated-declarations" V=1" command="make" id="org.eclipse.cdt.build.core.settings.default.builder.896899734" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<builder arguments="CFLAGS="-g -Wall -Werror -Wno-deprecated-declarations -Wno-unused-function" V=1" command="make" id="org.eclipse.cdt.build.core.settings.default.builder.896899734" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1682581923" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.730520342" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.552841386" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
|
|||
bellesip_sal/sal_op_call.c \
|
||||
bellesip_sal/sal_op_registration.c \
|
||||
bellesip_sal/sal_sdp.c \
|
||||
bellesip_sal/sal_op_message.c
|
||||
bellesip_sal/sal_op_message.c \
|
||||
bellesip_sal/sal_op_presence.c
|
||||
else
|
||||
liblinphone_la_SOURCES+= sal_eXosip2.c sal_eXosip2.h\
|
||||
sal_eXosip2_sdp.c \
|
||||
|
|
|
|||
|
|
@ -35,12 +35,28 @@ static void sal_add_pending_auth(Sal *sal, SalOp *op){
|
|||
}
|
||||
|
||||
void sal_process_authentication(SalOp *op, belle_sip_response_t *response) {
|
||||
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(op->request),BELLE_SIP_AUTHORIZATION);
|
||||
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(op->request),BELLE_SIP_PROXY_AUTHORIZATION);
|
||||
if (belle_sip_provider_add_authorization(op->base.root->prov,op->request,response)) {
|
||||
sal_op_resend_request(op,op->request);
|
||||
belle_sip_request_t* request;
|
||||
bool_t is_within_dialog=FALSE;
|
||||
if (op->dialog && belle_sip_dialog_get_state(op->dialog)==BELLE_SIP_DIALOG_CONFIRMED) {
|
||||
request = belle_sip_dialog_create_request_from(op->dialog,(const belle_sip_request_t *)op->request);
|
||||
is_within_dialog=TRUE;
|
||||
} else {
|
||||
request=op->request;
|
||||
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION);
|
||||
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION);
|
||||
|
||||
}
|
||||
if (belle_sip_provider_add_authorization(op->base.root->prov,request,response)) {
|
||||
if (is_within_dialog) {
|
||||
sal_op_resend_request(op,request);
|
||||
} else {
|
||||
sal_op_send_request(op,request);
|
||||
}
|
||||
}else {
|
||||
ms_message("No auth info found for [%s]",sal_op_get_from(op));
|
||||
if (is_within_dialog) {
|
||||
belle_sip_object_unref(request);
|
||||
}
|
||||
sal_add_pending_auth(op->base.root,op);
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +92,10 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
|
|||
op=sal_op_new((Sal*)sal);
|
||||
op->dir=SalOpDirIncoming;
|
||||
sal_op_call_fill_cbs(op);
|
||||
} else if (strcmp("SUBSCRIBE",belle_sip_request_get_method(req))==0) {
|
||||
op=sal_op_new((Sal*)sal);
|
||||
op->dir=SalOpDirIncoming;
|
||||
sal_op_presence_fill_cbs(op);
|
||||
} else if (strcmp("MESSAGE",belle_sip_request_get_method(req))==0) {
|
||||
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
|
||||
if (content_type
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ struct SalOp{
|
|||
bool_t supports_session_timers;
|
||||
SalOpSate_t state;
|
||||
SalOpDir_t dir;
|
||||
belle_sip_refresher_t* refresher;
|
||||
};
|
||||
|
||||
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *sal);
|
||||
|
|
@ -80,4 +81,9 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request);
|
|||
void sal_op_resend_request(SalOp* op, belle_sip_request_t* request);
|
||||
void sal_process_authentication(SalOp *op, belle_sip_response_t *response);
|
||||
|
||||
bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,SalReason* sal_reason,char* reason, size_t reason_size);
|
||||
|
||||
/*presence*/
|
||||
void sal_op_presence_fill_cbs(SalOp*op);
|
||||
|
||||
#endif /* SAL_IMPL_H_ */
|
||||
|
|
|
|||
|
|
@ -88,40 +88,6 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
|
|||
|
||||
|
||||
|
||||
|
||||
/*presence Subscribe/notify*/
|
||||
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
|
||||
ms_fatal("sal_subscribe_presence not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
int sal_unsubscribe(SalOp *op){
|
||||
ms_fatal("sal_unsubscribe not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
int sal_subscribe_accept(SalOp *op){
|
||||
ms_fatal("sal_subscribe_accept not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
int sal_subscribe_decline(SalOp *op){
|
||||
ms_fatal("sal_subscribe_decline not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
|
||||
ms_fatal("sal_notify_presence not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
int sal_notify_close(SalOp *op){
|
||||
ms_fatal("sal_notify_close not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*presence publish */
|
||||
int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status){
|
||||
ms_fatal("sal_publish not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*ping: main purpose is to obtain its own contact address behind firewalls*/
|
||||
int sal_ping(SalOp *op, const char *from, const char *to){
|
||||
ms_fatal("sal_ping not implemented yet");
|
||||
|
|
@ -141,6 +107,11 @@ void sal_op_resend_request(SalOp* op, belle_sip_request_t* request) {
|
|||
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
|
||||
sal_op_send_request(op,request);
|
||||
}
|
||||
static bool_t is_request_creating_dialog(belle_sip_request_t* request) {
|
||||
return strcmp("INVITE",belle_sip_request_get_method(request))==0
|
||||
||
|
||||
strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0;
|
||||
}
|
||||
int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
|
||||
belle_sip_client_transaction_t* client_transaction;
|
||||
belle_sip_provider_t* prov=op->base.root->prov;
|
||||
|
|
@ -155,7 +126,7 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
|
|||
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
|
||||
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),op);
|
||||
/*in case DIALOG is in state NULL create a new dialog*/
|
||||
if (!op->dialog && strcmp("INVITE",belle_sip_request_get_method(request))==0) {
|
||||
if (!op->dialog && is_request_creating_dialog(request)) {
|
||||
op->dialog=belle_sip_provider_create_dialog(prov,BELLE_SIP_TRANSACTION(client_transaction));
|
||||
op->pending_inv_client_trans=client_transaction; /*update pending inv for being able to cancel*/
|
||||
belle_sip_dialog_set_application_data(op->dialog,op);
|
||||
|
|
@ -167,3 +138,65 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
|
|||
return belle_sip_client_transaction_send_request(client_transaction);
|
||||
|
||||
}
|
||||
/*return TRUE if error code*/
|
||||
bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,SalReason* sal_reason,char* reason, size_t reason_size) {
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
|
||||
*sal_err=SalErrorUnknown;
|
||||
*sal_reason = SalReasonUnknown;
|
||||
|
||||
if (reason_header){
|
||||
snprintf(reason
|
||||
,reason_size
|
||||
,"%s %s"
|
||||
,belle_sip_response_get_reason_phrase(response)
|
||||
,belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(reason_header)));
|
||||
} else {
|
||||
strncpy(reason,belle_sip_response_get_reason_phrase(response),reason_size);
|
||||
}
|
||||
if (code >=400) {
|
||||
switch(code) {
|
||||
case 400:
|
||||
*sal_err=SalErrorUnknown;
|
||||
break;
|
||||
case 404:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonNotFound;
|
||||
break;
|
||||
case 415:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonMedia;
|
||||
break;
|
||||
case 422:
|
||||
ms_error ("422 not implemented yet");;
|
||||
break;
|
||||
case 480:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonTemporarilyUnavailable;
|
||||
break;
|
||||
case 486:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonBusy;
|
||||
break;
|
||||
case 487:
|
||||
break;
|
||||
case 600:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonDoNotDisturb;
|
||||
break;
|
||||
case 603:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonDeclined;
|
||||
break;
|
||||
default:
|
||||
if (code>0){
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonUnknown;
|
||||
}else *sal_err=SalErrorNoResponse;
|
||||
/* no break */
|
||||
}
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
628
coreapi/bellesip_sal/sal_op_presence.c
Normal file
628
coreapi/bellesip_sal/sal_op_presence.c
Normal file
|
|
@ -0,0 +1,628 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2012 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "sal_impl.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;
|
||||
|
||||
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;
|
||||
|
||||
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\" 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 ||
|
||||
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\" priority=\"0.800000\">\n\
|
||||
<status status=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"busy\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceBerightback)
|
||||
{
|
||||
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=\"open\" />\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 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=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"away\" />\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 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=\"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 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=\"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
|
||||
{
|
||||
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=\"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 */
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
static void add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status) {
|
||||
char buf[1000];
|
||||
char *contact_info;
|
||||
size_t content_length;
|
||||
|
||||
belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(notify,belle_sip_header_from_t);
|
||||
|
||||
contact_info=belle_sip_uri_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from)));
|
||||
mk_presence_body (online_status, contact_info, buf, sizeof (buf), presence_style);
|
||||
|
||||
|
||||
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
|
||||
,BELLE_SIP_HEADER(belle_sip_header_content_type_create("application",presence_style?"xpidf+xml":"pidf+xml")));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
|
||||
,BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length=strlen(buf))));
|
||||
belle_sip_message_set_body(BELLE_SIP_MESSAGE(notify),buf,content_length);
|
||||
ms_free(contact_info);
|
||||
}
|
||||
|
||||
static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
|
||||
ms_error("presence_process_io_error not implemented yet");
|
||||
}
|
||||
static void presence_process_dialog_terminated(void *op, const belle_sip_dialog_terminated_event_t *event) {
|
||||
if (((SalOp*)op)->dialog) ((SalOp*)op)->dialog=NULL;
|
||||
}
|
||||
|
||||
static void presence_response_event(void *op_base, const belle_sip_response_event_t *event){
|
||||
SalOp* op = (SalOp*)op_base;
|
||||
belle_sip_dialog_state_t dialog_state;
|
||||
belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
|
||||
belle_sip_response_t* response=belle_sip_response_event_get_response(event);
|
||||
belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
char reason[256]={0};
|
||||
SalError error=SalErrorUnknown;
|
||||
SalReason sr=SalReasonUnknown;
|
||||
belle_sip_header_expires_t* expires;
|
||||
if (sal_compute_sal_errors(response,&error,&sr,reason, sizeof(reason))) {
|
||||
ms_error("subscription to [%s] rejected reason [%s]",sal_op_get_to(op),reason[0]!=0?reason:sal_reason_to_string(sr));
|
||||
op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, SalPresenceOffline,NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
dialog_state=belle_sip_dialog_get_state(op->dialog);
|
||||
|
||||
|
||||
switch(dialog_state) {
|
||||
|
||||
case BELLE_SIP_DIALOG_NULL:
|
||||
case BELLE_SIP_DIALOG_EARLY: {
|
||||
ms_error("op [%p] receive an unexpected answer [%i]",op,code);
|
||||
break;
|
||||
}
|
||||
case BELLE_SIP_DIALOG_CONFIRMED: {
|
||||
if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0) {
|
||||
expires=belle_sip_message_get_header_by_type(request,belle_sip_header_expires_t);
|
||||
if(op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_object_unref(op->refresher);
|
||||
}
|
||||
if (expires>0){
|
||||
op->refresher=belle_sip_client_transaction_create_refresher(client_transaction);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BELLE_SIP_DIALOG_TERMINATED:
|
||||
if (op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_object_unref(op->refresher);
|
||||
op->refresher=NULL;
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
ms_error("op [%p] receive answer [%i] not implemented",op,code);
|
||||
}
|
||||
/* no break */
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
static void presence_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
|
||||
ms_error("presence_process_timeout not implemented yet");
|
||||
}
|
||||
static void presence_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
|
||||
ms_error("presence_process_timeout not implemented yet");
|
||||
}
|
||||
static void presence_process_request_event(void *op_base, const belle_sip_request_event_t *event) {
|
||||
SalOp* op = (SalOp*)op_base;
|
||||
belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
|
||||
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
|
||||
belle_sip_dialog_state_t dialog_state;
|
||||
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
|
||||
belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);;
|
||||
const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
|
||||
SalPresenceStatus estatus=SalPresenceOffline;
|
||||
SalSubscribeState sub_state;
|
||||
belle_sip_response_t* resp;
|
||||
belle_sip_object_ref(server_transaction);
|
||||
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
|
||||
op->pending_server_trans=server_transaction;
|
||||
|
||||
if (!op->dialog) {
|
||||
op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction));
|
||||
belle_sip_dialog_set_application_data(op->dialog,op);
|
||||
ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
|
||||
}
|
||||
dialog_state=belle_sip_dialog_get_state(op->dialog);
|
||||
switch(dialog_state) {
|
||||
|
||||
case BELLE_SIP_DIALOG_NULL: {
|
||||
op->base.root->callbacks.subscribe_received(op,sal_op_get_from(op));
|
||||
break;
|
||||
}
|
||||
case BELLE_SIP_DIALOG_EARLY:
|
||||
ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",belle_sip_request_get_method(req),op->dialog);
|
||||
break;
|
||||
|
||||
case BELLE_SIP_DIALOG_CONFIRMED:
|
||||
if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) {
|
||||
if (body==NULL){
|
||||
ms_error("No body in NOTIFY received from [%s]",sal_op_get_from(op));
|
||||
return;
|
||||
}
|
||||
if (strstr(body,"pending")!=NULL){
|
||||
estatus=SalPresenceOffline;
|
||||
}else if (strstr(body,"busy")!=NULL){
|
||||
estatus=SalPresenceBusy;
|
||||
}else if (strstr(body,"berightback")!=NULL
|
||||
|| strstr(body,"in-transit")!=NULL ){
|
||||
estatus=SalPresenceBerightback;
|
||||
}else if (strstr(body,"away")!=NULL
|
||||
|| strstr(body,"idle")){
|
||||
estatus=SalPresenceAway;
|
||||
}else if (strstr(body,"onthephone")!=NULL
|
||||
|| strstr(body,"on-the-phone")!=NULL){
|
||||
estatus=SalPresenceOnthephone;
|
||||
}else if (strstr(body,"outtolunch")!=NULL
|
||||
|| strstr(body,"meal")!=NULL){
|
||||
estatus=SalPresenceOuttolunch;
|
||||
}else if (strstr(body,"closed")!=NULL){
|
||||
estatus=SalPresenceOffline;
|
||||
}else if ((strstr(body,"online")!=NULL) || (strstr(body,"open")!=NULL)) {
|
||||
estatus=SalPresenceOnline;
|
||||
}else{
|
||||
estatus=SalPresenceOffline;
|
||||
}
|
||||
ms_message("We are notified that [%s] has online status %i",sal_op_get_from(op),estatus);
|
||||
if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) {
|
||||
sub_state=SalSubscribeTerminated;
|
||||
ms_message("And outgoing subscription terminated by remote [%s]",sal_op_get_to(op));
|
||||
} else
|
||||
sub_state=SalSubscribeActive;
|
||||
|
||||
op->base.root->callbacks.notify_presence(op,sub_state, estatus,NULL);
|
||||
resp=belle_sip_response_create_from_request(req,200);
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
} else if (strcmp("SUBSCRIBE",belle_sip_request_get_method(req))==0) {
|
||||
/*either a refresh of an unsubscribe*/
|
||||
if (expires && belle_sip_header_expires_get_expires(expires)>0) {
|
||||
op->base.root->callbacks.subscribe_received(op,sal_op_get_from(op));
|
||||
} else if(expires) {
|
||||
ms_message("Unsubscribe received from [%s]",sal_op_get_from(op));
|
||||
resp=belle_sip_response_create_from_request(req,200);
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
|
||||
}
|
||||
/* no break */
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void sal_op_presence_fill_cbs(SalOp*op) {
|
||||
op->callbacks.process_io_error=presence_process_io_error;
|
||||
op->callbacks.process_response_event=presence_response_event;
|
||||
op->callbacks.process_timeout=presence_process_timeout;
|
||||
op->callbacks.process_transaction_terminated=presence_process_transaction_terminated;
|
||||
op->callbacks.process_request_event=presence_process_request_event;
|
||||
op->callbacks.process_dialog_terminated=presence_process_dialog_terminated;
|
||||
}
|
||||
|
||||
/*presence publish */
|
||||
int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status){
|
||||
ms_fatal("sal_publish not implemented yet");
|
||||
return -1;
|
||||
}
|
||||
/*presence Subscribe/notify*/
|
||||
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
|
||||
belle_sip_request_t *req=NULL;
|
||||
if (from)
|
||||
sal_op_set_from(op,from);
|
||||
if (to)
|
||||
sal_op_set_to(op,to);
|
||||
|
||||
sal_op_presence_fill_cbs(op);
|
||||
|
||||
/*???sal_exosip_fix_route(op); make sure to ha ;lr*/
|
||||
req=sal_op_build_request(op,"SUBSCRIBE");
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","Presence"));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
|
||||
|
||||
return sal_op_send_request(op,req);
|
||||
}
|
||||
int sal_unsubscribe(SalOp *op){
|
||||
belle_sip_request_t* req=belle_sip_dialog_create_request(op->dialog,"SUBSCRIBE");
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","Presence"));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(0)));
|
||||
return sal_op_send_request(op,req);
|
||||
}
|
||||
int sal_subscribe_accept(SalOp *op){
|
||||
belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans));
|
||||
belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
|
||||
belle_sip_response_t* resp = belle_sip_response_create_from_request(req,200);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires));
|
||||
belle_sip_server_transaction_send_response(op->pending_server_trans,resp);
|
||||
return 0;
|
||||
}
|
||||
int sal_subscribe_decline(SalOp *op){
|
||||
belle_sip_response_t* resp = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),403);
|
||||
belle_sip_server_transaction_send_response(op->pending_server_trans,resp);
|
||||
return 0;
|
||||
}
|
||||
int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
|
||||
belle_sip_request_t* notify=belle_sip_dialog_create_request(op->dialog,"NOTIFY");
|
||||
/* belle_sip_header_address_t* identity=sal_op_get_contact_address(op);
|
||||
if (identity==NULL) identity=sal_op_get_to_address(op);
|
||||
_osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
|
||||
osip_message_set_contact(msg,identity);*/
|
||||
add_presence_info(BELLE_SIP_MESSAGE(notify),status); /*FIXME, what about expires ??*/
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
|
||||
,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,600)));
|
||||
return sal_op_send_request(op,notify);
|
||||
}
|
||||
int sal_notify_close(SalOp *op){
|
||||
belle_sip_request_t* notify=belle_sip_dialog_create_request(op->dialog,"NOTIFY");
|
||||
add_presence_info(BELLE_SIP_MESSAGE(notify),SalPresenceOffline); /*FIXME, what about expires ??*/
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
|
||||
,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,-1)));
|
||||
return sal_op_send_request(op,notify);
|
||||
}
|
||||
|
|
@ -30,11 +30,7 @@ static void register_refresh(SalOp* op) {
|
|||
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
|
||||
sal_op_send_request(op,op->request);
|
||||
}
|
||||
static bool_t is_contact_equal(belle_sip_header_contact_t* a,belle_sip_header_contact_t* b) {
|
||||
if (!a | !b) return FALSE;
|
||||
return !belle_sip_uri_equals(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(a))
|
||||
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(b)));
|
||||
}
|
||||
|
||||
static void register_response_event(void *user_ctx, const belle_sip_response_event_t *event){
|
||||
belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
|
||||
SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
|
||||
|
|
@ -52,7 +48,7 @@ static void register_response_event(void *user_ctx, const belle_sip_response_eve
|
|||
|
||||
contact_header_list = belle_sip_message_get_headers(BELLE_SIP_MESSAGE(response),BELLE_SIP_CONTACT);
|
||||
if (contact_header_list) {
|
||||
contact_header_list = belle_sip_list_find_custom((belle_sip_list_t*)contact_header_list,(belle_sip_compare_func)is_contact_equal, (const void*)sal_op_get_contact_address(op));
|
||||
contact_header_list = belle_sip_list_find_custom((belle_sip_list_t*)contact_header_list,(belle_sip_compare_func)belle_sip_header_contact_equals, (const void*)sal_op_get_contact_address(op));
|
||||
if (!contact_header_list) {
|
||||
ms_error("no matching contact for [%s]", sal_op_get_contact(op));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -338,8 +338,8 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
|
|||
ms_warning("No sip url defined.");
|
||||
return;
|
||||
}
|
||||
fr->lc=lc;
|
||||
|
||||
|
||||
linphone_core_write_friends_config(lc);
|
||||
|
||||
if (fr->inc_subscribe_pending){
|
||||
|
|
@ -390,6 +390,7 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
|
|||
return ;
|
||||
}
|
||||
lc->friends=ms_list_append(lc->friends,lf);
|
||||
lf->lc=lc;
|
||||
if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc);
|
||||
else lf->commit=TRUE;
|
||||
return ;
|
||||
|
|
|
|||
|
|
@ -414,3 +414,18 @@ const char* sal_stream_dir_to_string(SalStreamDir type) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
const char* sal_reason_to_string(const SalReason reason) {
|
||||
switch (reason) {
|
||||
case SalReasonDeclined : return "SalReasonDeclined";
|
||||
case SalReasonBusy: return "SalReasonBusy";
|
||||
case SalReasonRedirect: return "SalReasonRedirect";
|
||||
case SalReasonTemporarilyUnavailable: return "SalReasonTemporarilyUnavailable";
|
||||
case SalReasonNotFound: return "SalReasonNotFound";
|
||||
case SalReasonDoNotDisturb: return "SalReasonDoNotDisturb";
|
||||
case SalReasonMedia: return "SalReasonMedia";
|
||||
case SalReasonForbidden: return "SalReasonForbidden";
|
||||
case SalReasonUnknown: return "SalReasonUnknown";
|
||||
default: return "Unkown reason";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,6 +201,8 @@ typedef enum SalReason{
|
|||
SalReasonUnknown
|
||||
}SalReason;
|
||||
|
||||
const char* sal_reason_to_string(const SalReason reason);
|
||||
|
||||
typedef enum SalPresenceStatus{
|
||||
SalPresenceOffline,
|
||||
SalPresenceOnline,
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ typedef struct _stats {
|
|||
int number_of_LinphoneCallReleased;
|
||||
|
||||
int number_of_LinphoneMessageReceived;
|
||||
|
||||
int number_of_NewSubscriptionRequest;
|
||||
int number_of_NotifyReceived;
|
||||
}stats;
|
||||
static stats global_stat;
|
||||
|
||||
|
|
@ -296,7 +299,6 @@ static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCal
|
|||
}
|
||||
|
||||
static void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message) {
|
||||
|
||||
char* from=linphone_address_as_string(from_address);
|
||||
ms_message("Message from [%s] is [%s]",from,message);
|
||||
ms_free(from);
|
||||
|
|
@ -304,6 +306,21 @@ static void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, cons
|
|||
counters->number_of_LinphoneMessageReceived++;
|
||||
}
|
||||
|
||||
void new_subscribtion_request(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
|
||||
char* from=linphone_address_as_string(linphone_friend_get_address(lf));
|
||||
ms_message("New subscription request from [%s] url [%s]",from,url);
|
||||
ms_free(from);
|
||||
stats* counters = (stats*)linphone_core_get_user_data(lc);
|
||||
counters->number_of_NewSubscriptionRequest++;
|
||||
|
||||
}
|
||||
static void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) {
|
||||
char* from=linphone_address_as_string(linphone_friend_get_address(lf));
|
||||
ms_message("New Notify request from [%s] ",from);
|
||||
ms_free(from);
|
||||
stats* counters = (stats*)linphone_core_get_user_data(lc);
|
||||
counters->number_of_NotifyReceived++;
|
||||
}
|
||||
static bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
|
||||
int retry=0;
|
||||
while (*counter<value && retry++ <20) {
|
||||
|
|
@ -339,6 +356,8 @@ static LinphoneCoreManager* linphone_core_manager_new(const char* rc_file) {
|
|||
mgr->v_table.registration_state_changed=registration_state_changed;
|
||||
mgr->v_table.call_state_changed=call_state_changed;
|
||||
mgr->v_table.text_received=text_message_received;
|
||||
mgr->v_table.new_subscription_request=new_subscribtion_request;
|
||||
mgr->v_table.notify_presence_recv=notify_presence_received;
|
||||
mgr->lc=configure_lc_from(&mgr->v_table,rc_file,1);
|
||||
enable_codec(mgr->lc,"PCMU",8000);
|
||||
linphone_core_set_user_data(mgr->lc,&mgr->stat);
|
||||
|
|
@ -551,6 +570,37 @@ static void text_message() {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void simple_publish() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
|
||||
LinphoneProxyConfig* proxy;
|
||||
linphone_core_get_default_proxy(marie->lc,&proxy);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
linphone_core_iterate(marie->lc);
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
|
||||
static void simple_subscribe() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("./tester/pauline_rc");
|
||||
const MSList* marie_friends = linphone_core_get_friend_list(marie->lc);
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_friends);
|
||||
LinphoneFriend* friend = (LinphoneFriend*) marie_friends->data;
|
||||
linphone_friend_edit(friend);
|
||||
linphone_friend_enable_subscribes(friend,TRUE);
|
||||
linphone_friend_done(friend);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyReceived,1));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
CU_ASSERT_TRUE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*wait for unsubscribe*/
|
||||
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
int init_test_suite () {
|
||||
|
||||
CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit);
|
||||
|
|
@ -604,6 +654,12 @@ CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit);
|
|||
if (NULL == CU_add_test(pSuite, "text_message", text_message)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
if (NULL == CU_add_test(pSuite, "simple_subscribe", simple_subscribe)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
if (NULL == CU_add_test(pSuite, "simple_publish", simple_publish)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int main (int argc, char *argv[]) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ reg_sendregister=1
|
|||
publish=0
|
||||
dial_escape_plus=0
|
||||
|
||||
[friend_0]
|
||||
url="Paupoche" <sip:pauline@sip.example.org>
|
||||
pol=accept
|
||||
subscribe=0
|
||||
|
||||
|
||||
[rtp]
|
||||
audio_rtp_port=8070
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ reg_sendregister=1
|
|||
publish=0
|
||||
dial_escape_plus=0
|
||||
|
||||
#[friend_0]
|
||||
#url="Mariette" <sip:marie@sip.example.org>
|
||||
#pol=accept
|
||||
#subscribe=0
|
||||
|
||||
[rtp]
|
||||
audio_rtp_port=8090
|
||||
video_rtp_port=8092
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue