Commit 06a9ea3c authored by jehan's avatar jehan

implement publish

parent 9f1fbf40
......@@ -60,6 +60,7 @@ liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
bellesip_sal/sal_sdp.c \
bellesip_sal/sal_op_message.c \
bellesip_sal/sal_op_presence.c \
bellesip_sal/sal_op_publish.c \
bellesip_sal/sal_op_call_transfer.c
else
liblinphone_la_SOURCES+= sal_eXosip2.c sal_eXosip2.h\
......
......@@ -345,7 +345,7 @@ static void process_transaction_terminated(void *user_ctx, const belle_sip_trans
} else {
ms_error("Unhandled transaction terminated [%p]",trans);
}
if (op) sal_op_unref(op); /*no longuer need to ref op*/
if (op && client_transaction) sal_op_unref(op); /*because every client transaction ref op*/
}
......
......@@ -50,6 +50,7 @@ typedef enum SalOpSate {
,SalOpStateTerminating /*this state is used to wait until a proceeding state, so we can send the cancel*/
,SalOpStateTerminated
}SalOpSate_t;
const char* sal_op_state_to_string(const SalOpSate_t value);
typedef enum SalOpDir {
SalOpDirIncoming=0
......@@ -60,7 +61,8 @@ typedef enum SalOpType {
SalOpRegister,
SalOpCall,
SalOpMessage,
SalOpPresence
SalOpPresence,
SalOpPublish
}SalOpType_t;
const char* sal_op_type_to_string(const SalOpType_t type);
......@@ -71,7 +73,6 @@ struct SalOp{
belle_sip_server_transaction_t* pending_server_trans;
belle_sip_client_transaction_t* pending_client_trans;
SalAuthInfo* auth_info;
belle_sip_refresher_t* registration_refresher;
bool_t sdp_offering;
belle_sip_dialog_t* dialog;
belle_sip_header_replaces_t *replaces;
......@@ -103,8 +104,10 @@ void sal_op_release_impl(SalOp *op);
void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message);
int sal_op_send_request(SalOp* op, belle_sip_request_t* request);
int sal_op_send_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires);
void sal_op_resend_request(SalOp* op, belle_sip_request_t* request);
int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener );
void sal_process_authentication(SalOp *op);
belle_sip_header_contact_t* sal_op_create_contact(SalOp *op,belle_sip_header_from_t* from_header) ;
......@@ -120,4 +123,6 @@ void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *even
/*create SalAuthInfo by copying username and realm from suth event*/
SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ;
void sal_add_pending_auth(Sal *sal, SalOp *op);
void sal_add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status);
#endif /* SAL_IMPL_H_ */
......@@ -146,7 +146,7 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat
case 401:
case 407:
if (op->state!=SalOpStateTerminating) {
/*normal termination for chalanged dialog */
/*normal termination for challenged dialog */
break;
}
default:
......@@ -182,7 +182,7 @@ static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
}
static void cancelling_invite(SalOp* op ){
belle_sip_request_t* cancel;
ms_message("Cancelling INVITE requets from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
sal_op_send_request(op,cancel);
op->state=SalOpStateTerminating;
......@@ -211,12 +211,16 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t
case BELLE_SIP_DIALOG_EARLY: {
if (strcmp("INVITE",belle_sip_request_get_method(req))==0 ) {
if ( op->state == SalOpStateTerminating) {
if (code <200) {
cancelling_invite(op);
} else if (code<400) {
sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE"));
if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
if (code <200) {
cancelling_invite(op);
} else if (code<400) {
sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE"));
} else {
/*nop ?*/
}
} else {
/*nop ?*/
/*nop, already cancelled*/
}
break;
} else if (code >= 180 && code<300) {
......@@ -708,7 +712,10 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){
int sal_call_terminate(SalOp *op){
belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; /*no dialog = dialog in NULL state*/
op->state=SalOpStateTerminating;
if (op->state==SalOpStateTerminating || op->state==SalOpStateTerminated) {
ms_error("Cannot terminate op [%p] in state [%s]",op,sal_op_state_to_string(op->state));
return -1;
}
switch(dialog_state) {
case BELLE_SIP_DIALOG_CONFIRMED: {
sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE"));
......
......@@ -30,7 +30,6 @@ SalOp * sal_op_new(Sal *sal){
void sal_op_release(SalOp *op){
op->state=SalOpStateTerminated;
sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn not mean freeing op. Make sure back pointer will not be used later*/
if (op->registration_refresher) belle_sip_refresher_stop(op->registration_refresher);
if (op->refresher) belle_sip_refresher_stop(op->refresher);
sal_op_unref(op);
}
......@@ -39,10 +38,9 @@ void sal_op_release_impl(SalOp *op){
if (op->pending_auth_transaction) belle_sip_object_unref(op->pending_auth_transaction);
if (op->auth_info) sal_auth_info_delete(op->auth_info);
if (op->sdp_answer) belle_sip_object_unref(op->sdp_answer);
if (op->registration_refresher) {
belle_sip_refresher_stop(op->registration_refresher);
belle_sip_object_unref(op->registration_refresher);
op->registration_refresher=NULL;
if (op->refresher) {
belle_sip_object_unref(op->refresher);
op->refresher=NULL;
}
if(op->replaces) belle_sip_object_unref(op->replaces);
if(op->referred_by) belle_sip_object_unref(op->referred_by);
......@@ -131,6 +129,17 @@ void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message) {
}
}
int sal_op_send_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires) {
belle_sip_header_expires_t* expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_EXPIRES);
if (!expires_header && expires>=0) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(expires_header=belle_sip_header_expires_new()));
}
if (expires_header) belle_sip_header_expires_set_expires(expires_header,expires);
return sal_op_send_request(op,request);
}
void sal_op_resend_request(SalOp* op, belle_sip_request_t* request) {
belle_sip_header_cseq_t* cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CSEQ);
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
......@@ -176,14 +185,13 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),sal_op_ref(op));
if ( strcmp("INVITE",belle_sip_request_get_method(request))==0 || strcmp("REGISTER",belle_sip_request_get_method(request))==0) {
if (op->pending_client_trans) belle_sip_object_unref(op->pending_client_trans);
op->pending_client_trans=client_transaction; /*update pending inv for being able to cancel*/
belle_sip_object_ref(op->pending_client_trans);
}
if (op->pending_client_trans) belle_sip_object_unref(op->pending_client_trans);
op->pending_client_trans=client_transaction; /*update pending inv for being able to cancel*/
belle_sip_object_ref(op->pending_client_trans);
if (belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_user_agent_t)==NULL)
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(op->base.root->user_agent));
if (add_contact) {
contact = sal_op_create_contact(op,belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_from_t));
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CONTACT);
......@@ -308,3 +316,31 @@ void* sal_op_unref(SalOp* op) {
}
return NULL;
}
int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener ) {
if (sal_op_send_request_with_expires(op,req,expires)) {
return -1;
} else {
if (op->refresher) {
belle_sip_refresher_stop(op->refresher);
belle_sip_object_unref(op->refresher);
}
if ((op->refresher = belle_sip_client_transaction_create_refresher(op->pending_client_trans))) {
belle_sip_refresher_enable_nat_helper(op->refresher,op->base.root->nat_helper_enabled);
belle_sip_refresher_set_listener(op->refresher,listener,op);
return 0;
} else {
return -1;
}
}
}
const char* sal_op_state_to_string(const SalOpSate_t value) {
switch(value) {
case SalOpStateEarly: return"SalOpStateEarly";
case SalOpStateActive: return "SalOpStateActive";
case SalOpStateTerminating: return "SalOpStateTerminating";
case SalOpStateTerminated: return "SalOpStateTerminated";
default:
return "Unknon";
}
}
......@@ -381,7 +381,7 @@ entity=\"%s\">\n\
}
static void add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status) {
void sal_add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status) {
char buf[1000];
char *contact_info;
size_t content_length;
......@@ -576,19 +576,7 @@ void sal_op_presence_fill_cbs(SalOp*op) {
op->type=SalOpPresence;
}
/*presence publish */
int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status){
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);
req=sal_op_build_request(op,"PUBLISH");
add_presence_info(BELLE_SIP_MESSAGE(req),status);
return sal_op_send_request(op,req);
}
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
belle_sip_request_t *req=NULL;
......@@ -631,15 +619,18 @@ int sal_subscribe_decline(SalOp *op){
}
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");
add_presence_info(BELLE_SIP_MESSAGE(notify),status); /*FIXME, what about expires ??*/
sal_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 ??*/
sal_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);
}
/*
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"
static void publish_refresher_listener ( const belle_sip_refresher_t* refresher
,void* user_pointer
,unsigned int status_code
,const char* reason_phrase) {
SalOp* op = (SalOp*)user_pointer;
/*belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));*/
ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));
}
/*presence publish */
int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status){
belle_sip_request_t *req=NULL;
if (from)
sal_op_set_from(op,from);
if (to)
sal_op_set_to(op,to);
op->type=SalOpPublish;
req=sal_op_build_request(op,"PUBLISH");
sal_add_presence_info(BELLE_SIP_MESSAGE(req),status);
return sal_op_send_and_create_refresher(op,req,600,publish_refresher_listener);
}
......@@ -43,7 +43,7 @@ static void register_refresher_listener ( const belle_sip_refresher_t* refresher
}
sal_op_set_service_route(op,(const SalAddress*)service_route_address);
if (service_route_address) belle_sip_object_unref(service_route_address);
op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->registration_refresher)>0);
op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0);
} else if (status_code>=400) {
/* from rfc3608, 6.1.
If the UA refreshes the registration, the stored value of the Service-
......@@ -70,20 +70,6 @@ static void register_refresher_listener ( const belle_sip_refresher_t* refresher
}
}
/*if expire = -1, does not change expires*/
static int send_register_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires) {
belle_sip_header_expires_t* expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_EXPIRES);
if (!expires_header && expires>=0) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(expires_header=belle_sip_header_expires_new()));
}
if (expires_header) belle_sip_header_expires_set_expires(expires_header,expires);
return sal_op_send_request(op,request);
}
int sal_register(SalOp *op, const char *proxy, const char *from, int expires){
belle_sip_request_t *req;
belle_sip_uri_t* req_uri;
......@@ -95,27 +81,12 @@ int sal_register(SalOp *op, const char *proxy, const char *from, int expires){
req_uri = belle_sip_request_get_uri(req);
belle_sip_uri_set_user(req_uri,NULL); /*remove userinfo if any*/
if (send_register_request_with_expires(op,req,expires)) {
return -1;
} else {
if (op->registration_refresher) {
belle_sip_refresher_stop(op->registration_refresher);
belle_sip_object_unref(op->registration_refresher);
}
if ((op->registration_refresher = belle_sip_client_transaction_create_refresher(op->pending_client_trans))) {
belle_sip_refresher_enable_nat_helper(op->registration_refresher,op->base.root->nat_helper_enabled);
belle_sip_refresher_set_listener(op->registration_refresher,register_refresher_listener,op);
return 0;
} else {
return -1;
}
}
return sal_op_send_and_create_refresher(op,req,expires,register_refresher_listener);
}
int sal_register_refresh(SalOp *op, int expires){
if (op->registration_refresher)
return belle_sip_refresher_refresh(op->registration_refresher,expires);
if (op->refresher)
return belle_sip_refresher_refresh(op->refresher,expires);
else
return -1;
}
......
......@@ -93,15 +93,11 @@ static void linphone_call_cb(LinphoneCall *call,void * user_data) {
}
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
LinphoneProxyConfig* proxy;
int retry=0;
stats initial_caller=caller_mgr->stat;
stats initial_callee=callee_mgr->stat;
LinphoneAddress* identity;
linphone_core_get_default_proxy(callee_mgr->lc,&proxy);
CU_ASSERT_PTR_NOT_NULL(proxy);
if (!proxy) return -1;
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity));
......@@ -127,15 +123,12 @@ bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
CU_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging==initial_caller.number_of_LinphoneCallOutgoingRinging+1)
|(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia==initial_caller.number_of_LinphoneCallOutgoingEarlyMedia+1));
linphone_core_get_default_proxy(caller_mgr->lc,&proxy);
CU_ASSERT_PTR_NOT_NULL(proxy);
if (!proxy) return 0;
identity = linphone_address_new(linphone_proxy_config_get_identity(proxy));
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc));
if (!linphone_core_get_current_call_remote_address(callee_mgr->lc))
return 0;
CU_ASSERT_TRUE(linphone_address_weak_equal(identity,linphone_core_get_current_call_remote_address(callee_mgr->lc)));
linphone_address_destroy(identity);
CU_ASSERT_TRUE(linphone_address_weak_equal(caller_mgr->identity,linphone_core_get_current_call_remote_address(callee_mgr->lc)));
linphone_core_accept_call(callee_mgr->lc,linphone_core_get_current_call(callee_mgr->lc));
......
[net]
[net]
mtu=1300
[sip]
ping_with_options=0
\ No newline at end of file
ping_with_options=0
sip_random_port=1
\ No newline at end of file
......@@ -22,7 +22,15 @@
#include "private.h"
#include "liblinphone_tester.h"
static LinphoneCoreManager* presence_linphone_core_manager_new(char* username) {
LinphoneCoreManager* mgr= linphone_core_manager_new2(liblinphone_tester_file_prefix, "empty_rc", FALSE);
char* identity_char;
mgr->identity= linphone_core_get_primary_contact_parsed(mgr->lc);
linphone_address_set_username(mgr->identity,username);
identity_char=linphone_address_as_string(mgr->identity);
linphone_core_set_primary_contact(mgr->lc,identity_char);
return mgr;
}
void new_subscribtion_request(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
char* from=linphone_address_as_string(linphone_friend_get_address(lf));
stats* counters;
......@@ -76,14 +84,11 @@ static void simple_publish(void) {
static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
stats initial_caller=caller_mgr->stat;
stats initial_callee=callee_mgr->stat;
LinphoneProxyConfig* proxy;
bool_t result=FALSE;
char* identity=linphone_address_as_string_uri_only(callee_mgr->identity);
LinphoneFriend * friend;
linphone_core_get_default_proxy(callee_mgr->lc,&proxy);
if (!proxy) return 0;
friend=linphone_friend_new_with_addr(linphone_proxy_config_get_identity(proxy));
LinphoneFriend* friend=linphone_friend_new_with_addr(identity);
linphone_friend_edit(friend);
linphone_friend_enable_subscribes(friend,TRUE);
linphone_friend_done(friend);
......@@ -96,23 +101,15 @@ static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,Linph
CU_ASSERT_EQUAL(callee_mgr->stat.number_of_NewSubscriptionRequest,initial_callee.number_of_NewSubscriptionRequest+1);
CU_ASSERT_EQUAL(callee_mgr->stat.number_of_NotifyReceived,initial_callee.number_of_NotifyReceived+1);
CU_ASSERT_EQUAL(caller_mgr->stat.number_of_NotifyReceived,initial_caller.number_of_NotifyReceived+1);
ms_free(identity);
return result;
}
static void simple_subscribe(void) {
LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc");
const MSList* marie_friends = linphone_core_get_friend_list(marie->lc);
LinphoneFriend* friend;
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_friends);
friend = (LinphoneFriend*) marie_friends->data;
linphone_friend_edit(friend);
linphone_friend_enable_subscribes(friend,TRUE);
linphone_friend_done(friend);
LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
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));
CU_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
linphone_core_manager_destroy(marie);
CU_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
......@@ -132,8 +129,8 @@ static void unsubscribe_while_subscribing(void) {
}
static void call_with_presence(void) {
LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc");
LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
CU_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
CU_ASSERT_TRUE(call(marie,pauline));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment