mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
improve notification of generic subscribe errors
This commit is contained in:
parent
71f81ce6ec
commit
005140d321
7 changed files with 78 additions and 103 deletions
|
|
@ -18,19 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
#include "sal_impl.h"
|
||||
|
||||
|
||||
static void subscribe_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
|
||||
ms_error("subscribe_process_io_error not implemented yet");
|
||||
}
|
||||
|
||||
static void subscribe_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
|
||||
SalOp* op= (SalOp*)ctx;
|
||||
if (op->dialog) {
|
||||
op->dialog=NULL;
|
||||
sal_op_unref(op);
|
||||
}
|
||||
}
|
||||
|
||||
SalSubscribeStatus get_subscription_state(belle_sip_message_t *msg){
|
||||
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(msg,belle_sip_header_subscription_state_t);
|
||||
SalSubscribeStatus sss=SalSubscribeNone;
|
||||
|
|
@ -45,73 +32,49 @@ SalSubscribeStatus get_subscription_state(belle_sip_message_t *msg){
|
|||
return sss;
|
||||
}
|
||||
|
||||
static void subscribe_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};
|
||||
static void subscribe_refresher_listener (belle_sip_refresher_t* refresher
|
||||
,void* user_pointer
|
||||
,unsigned int status_code
|
||||
,const char* reason_phrase) {
|
||||
SalOp* op = (SalOp*)user_pointer;
|
||||
SalError error=SalErrorUnknown;
|
||||
SalReason sr=SalReasonUnknown;
|
||||
belle_sip_header_expires_t* expires;
|
||||
SalSubscribeStatus sss=get_subscription_state(BELLE_SIP_MESSAGE(response));
|
||||
belle_sip_transaction_t *tr=BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher));
|
||||
/*belle_sip_response_t* response=belle_sip_transaction_get_response(tr);*/
|
||||
SalSubscribeStatus sss=SalSubscribeTerminated;
|
||||
|
||||
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.subscribe_response(op,SalSubscribeTerminated,error,sr);
|
||||
return;
|
||||
ms_message("Subscribe refresher [%i] reason [%s] ",status_code,reason_phrase?reason_phrase:"none");
|
||||
if (status_code>=200 && status_code<300){
|
||||
if (status_code==200) sss=SalSubscribeActive;
|
||||
else if (status_code==202) sss=SalSubscribePending;
|
||||
set_or_update_dialog(op,belle_sip_transaction_get_dialog(tr));
|
||||
}
|
||||
set_or_update_dialog(op_base,belle_sip_response_event_get_dialog(event));
|
||||
if (!op->dialog) {
|
||||
ms_message("subscribe op [%p] received out of dialog answer [%i]",op,code);
|
||||
return;
|
||||
if (status_code>=200){
|
||||
sal_compute_sal_errors_from_code(status_code,&error,&sr);
|
||||
op->base.root->callbacks.subscribe_response(op,sss,error,sr);
|
||||
}
|
||||
dialog_state=belle_sip_dialog_get_state(op->dialog);
|
||||
switch(dialog_state) {
|
||||
case BELLE_SIP_DIALOG_NULL:
|
||||
case BELLE_SIP_DIALOG_EARLY: {
|
||||
ms_error("subscribe 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);
|
||||
op->refresher=NULL;
|
||||
}
|
||||
if (expires>0){
|
||||
op->refresher=belle_sip_client_transaction_create_refresher(client_transaction);
|
||||
if (op->refresher) belle_sip_refresher_enable_manual_mode(op->refresher,op->manual_refresher);
|
||||
}
|
||||
if (sss==SalSubscribeNone) sss=SalSubscribeActive; /*without Subscription-state header, consider subscription is accepted.*/
|
||||
op->base.root->callbacks.subscribe_response(op,sss,SalErrorNone,SalReasonUnknown);
|
||||
}
|
||||
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("subscribe op [%p] receive answer [%i] not implemented",op,code);
|
||||
}
|
||||
/* no break */
|
||||
|
||||
}
|
||||
|
||||
static void subscribe_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
|
||||
ms_error("subscribe_process_io_error not implemented yet");
|
||||
}
|
||||
|
||||
static void subscribe_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
|
||||
SalOp* op= (SalOp*)ctx;
|
||||
if (op->dialog) {
|
||||
op->dialog=NULL;
|
||||
sal_op_unref(op);
|
||||
}
|
||||
}
|
||||
|
||||
static void subscribe_response_event(void *op_base, const belle_sip_response_event_t *event){
|
||||
}
|
||||
|
||||
static void subscribe_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
|
||||
ms_message("subscribe_process_timeout not implemented yet");
|
||||
}
|
||||
|
||||
static void subscribe_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
|
||||
ms_message("subscribe_process_transaction_terminated not implemented yet");
|
||||
}
|
||||
|
||||
static void handle_notify(SalOp *op, belle_sip_request_t *req, const char *eventname, SalBody * body){
|
||||
|
|
@ -191,7 +154,8 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
|
|||
} else if (strcmp("SUBSCRIBE",method)==0) {
|
||||
/*either a refresh of an unsubscribe*/
|
||||
if (expires && belle_sip_header_expires_get_expires(expires)>0) {
|
||||
|
||||
resp=sal_op_create_response_from_request(op,req,200);
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
} else if(expires) {
|
||||
ms_message("Unsubscribe received from [%s]",sal_op_get_from(op));
|
||||
resp=sal_op_create_response_from_request(op,req,200);
|
||||
|
|
@ -235,36 +199,29 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
|
|||
belle_sip_object_ref(op->event);
|
||||
}
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
}else{
|
||||
req=belle_sip_dialog_create_request(op->dialog,"SUBSCRIBE");
|
||||
if (!req) {
|
||||
ms_error("Cannot create subscribe refresh.");
|
||||
return -1;
|
||||
}
|
||||
if (expires==-1){
|
||||
belle_sip_transaction_t *last=(belle_sip_transaction_t*)op->pending_client_trans;
|
||||
belle_sip_message_t *msg=BELLE_SIP_MESSAGE(belle_sip_transaction_get_request(last));
|
||||
belle_sip_header_expires_t *eh=belle_sip_message_get_header_by_type(msg,belle_sip_header_expires_t);
|
||||
expires=belle_sip_header_expires_get_expires(eh);
|
||||
}
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
|
||||
sal_op_add_body(op,(belle_sip_message_t*)req,body);
|
||||
return sal_op_send_and_create_refresher(op,req,expires,subscribe_refresher_listener);
|
||||
}else if (op->refresher){
|
||||
const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher);
|
||||
belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr);
|
||||
/* modify last request to update body*/
|
||||
sal_op_add_body(op,(belle_sip_message_t*)last_req,body);
|
||||
return belle_sip_refresher_refresh(op->refresher,expires);
|
||||
}
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
|
||||
sal_op_add_body(op,(belle_sip_message_t*)req,body);
|
||||
return sal_op_send_request(op,req);
|
||||
ms_warning("sal_subscribe(): no dialog and no refresher ?");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sal_unsubscribe(SalOp *op){
|
||||
belle_sip_request_t* req=op->dialog?belle_sip_dialog_create_request(op->dialog,"SUBSCRIBE"):NULL; /*cannot create request if dialog not set yet*/
|
||||
if (!req) {
|
||||
ms_error("Cannot unsubscribe to [%s]",sal_op_get_to(op));
|
||||
return -1;
|
||||
if (op->refresher){
|
||||
const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher);
|
||||
belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr);
|
||||
sal_op_add_body(op,(belle_sip_message_t*)last_req,NULL);
|
||||
belle_sip_refresher_refresh(op->refresher,0);
|
||||
return 0;
|
||||
}
|
||||
if (op->refresher)
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sal_subscribe_accept(SalOp *op){
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,S
|
|||
} else {
|
||||
strncpy(reason,belle_sip_response_get_reason_phrase(response),reason_size);
|
||||
}
|
||||
if (code>400) {
|
||||
if (code>=400) {
|
||||
sal_compute_sal_errors_from_code(code,sal_err,sal_reason);
|
||||
return TRUE;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState stat
|
|||
if (lc->vtable.subscription_state_changed){
|
||||
lc->vtable.subscription_state_changed(lev->lc,lev,state);
|
||||
}
|
||||
if (state==LinphoneSubscriptionError || state==LinphoneSubscriptionTerminated){
|
||||
if (state==LinphoneSubscriptionTerminated){
|
||||
linphone_event_unref(lev);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 214f82f8942f9d1c419f038dbd33b36b65e2a1e6
|
||||
Subproject commit 5003385d52f715b60772da879b4655463890ffd1
|
||||
|
|
@ -120,12 +120,15 @@ static void subscribe_test_declined(void) {
|
|||
}
|
||||
|
||||
|
||||
static void subscribe_test_with_args(bool_t terminated_by_subscriber) {
|
||||
static void subscribe_test_with_args(bool_t terminated_by_subscriber, bool_t test_refreshing) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneContent content;
|
||||
LinphoneEvent *lev;
|
||||
int expires= test_refreshing ? 4 : 600;
|
||||
MSList* lcs=ms_list_append(NULL,marie->lc);
|
||||
|
||||
|
||||
lcs=ms_list_append(lcs,pauline->lc);
|
||||
|
||||
|
||||
|
|
@ -134,7 +137,7 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber) {
|
|||
content.data=(char*)subscribe_content;
|
||||
content.size=strlen(subscribe_content);
|
||||
|
||||
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,&content);
|
||||
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,&content);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
|
||||
|
|
@ -143,6 +146,11 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber) {
|
|||
|
||||
/*make sure marie receives first notification before terminating*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
|
||||
|
||||
if (test_refreshing){
|
||||
wait_for_list(lcs,NULL,0,6000);
|
||||
CU_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
|
||||
}
|
||||
|
||||
if (terminated_by_subscriber){
|
||||
linphone_event_terminate(lev);
|
||||
|
|
@ -159,11 +167,18 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber) {
|
|||
}
|
||||
|
||||
static void subscribe_test_terminated_by_subscriber(void){
|
||||
subscribe_test_with_args(TRUE);
|
||||
subscribe_test_with_args(TRUE,FALSE);
|
||||
}
|
||||
|
||||
static void subscribe_test_terminated_by_notifier(void){
|
||||
subscribe_test_with_args(FALSE);
|
||||
subscribe_test_with_args(FALSE,FALSE);
|
||||
}
|
||||
|
||||
/* Caution: this test does not really check that the subscribe are refreshed, because the core is not managing the expiration of
|
||||
* unrefreshed subscribe dialogs. So it is just checking that it is not crashing.
|
||||
*/
|
||||
static void subscribe_test_refreshed(void){
|
||||
subscribe_test_with_args(TRUE,TRUE);
|
||||
}
|
||||
|
||||
static void publish_test_with_args(bool_t refresh){
|
||||
|
|
@ -218,6 +233,7 @@ static void publish_no_auto_test(){
|
|||
test_t event_tests[] = {
|
||||
{ "Subscribe declined" , subscribe_test_declined },
|
||||
{ "Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber },
|
||||
{ "Subscribe refreshed", subscribe_test_refreshed },
|
||||
{ "Subscribe terminated by notifier", subscribe_test_terminated_by_notifier },
|
||||
{ "Publish", publish_test },
|
||||
{ "Publish without automatic refresh",publish_no_auto_test }
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
|
|||
bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) {
|
||||
int retry=0;
|
||||
MSList* iterator;
|
||||
while (*counter<value && retry++ <timeout_ms/100) {
|
||||
while ((counter==NULL || *counter<value) && retry++ <timeout_ms/100) {
|
||||
for (iterator=lcs;iterator!=NULL;iterator=iterator->next) {
|
||||
linphone_core_iterate((LinphoneCore*)(iterator->data));
|
||||
}
|
||||
ms_usleep(100000);
|
||||
}
|
||||
if(*counter<value) return FALSE;
|
||||
if(counter && *counter<value) return FALSE;
|
||||
else return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ private:
|
|||
mPropertyName=mName.substr(6,string::npos);
|
||||
if (!mPropertyName.empty()){
|
||||
mPropertyName[0]=tolower(mPropertyName[0]);
|
||||
mPropertyName+="Enabled";
|
||||
mPropertyBehaviour=Write;
|
||||
}
|
||||
}else if (mName.find("set")==0 && mArgs.size()==1){
|
||||
|
|
@ -217,6 +218,7 @@ private:
|
|||
if (enabled_pos==goodpos){
|
||||
mPropertyName=mName.substr(0,goodpos);
|
||||
if (!mPropertyName.empty()){
|
||||
mPropertyName+="Enabled";
|
||||
mPropertyBehaviour=Read;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue