Commit 73acfcd2 authored by jehan's avatar jehan

implement refresher for SUBSCRIBE

parent 041fa954
......@@ -218,7 +218,7 @@ int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req
}
if (belle_sip_dialog_establish_full(obj,req,resp)==0){
obj->state=BELLE_SIP_DIALOG_CONFIRMED;
obj->needs_ack=TRUE;
obj->needs_ack=strcmp("INVITE",belle_sip_request_get_method(req))==0; /*only for invite*/
}else return -1;
} else if (code>=300 && obj->state!=BELLE_SIP_DIALOG_CONFIRMED) {
/*12.3 Termination of a Dialog
......
......@@ -122,6 +122,11 @@ static int refresh(belle_sip_refresher_t* refresher) {
request=belle_sip_client_transaction_create_authenticated_request(refresher->transaction);
} else if (dialog && belle_sip_dialog_get_state(dialog)==BELLE_SIP_DIALOG_CONFIRMED) {
request=belle_sip_dialog_create_request(dialog,belle_sip_request_get_method(old_request));
if (strcmp(belle_sip_request_get_method(request),"SUBSCRIBE")==0) {
/*put expire header*/
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(belle_sip_header_expires_create(refresher->expires)));
}
belle_sip_provider_add_authorization(prov,request,NULL);
} else {
belle_sip_error("Unexpected dialog state [%s] for dialog [%p], cannot refresh [%s]"
,belle_sip_dialog_state_to_string(belle_sip_dialog_get_state(dialog))
......
......@@ -264,7 +264,12 @@ int belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t)
belle_sip_hop_free(&hop);
return 0;
}
static unsigned int should_dialog_be_created(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t));
const char* method = belle_sip_request_get_method(req);
int status_code = belle_sip_response_get_status_code(resp);
return status_code>=200 && status_code<300 && (strcmp(method,"INVITE")==0 || strcmp(method,"SUBSCRIBE")==0);
}
void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
belle_sip_transaction_t *base=(belle_sip_transaction_t*)t;
belle_sip_response_event_t event;
......@@ -272,7 +277,6 @@ void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t
int status_code = belle_sip_response_get_status_code(resp);
if (base->last_response)
belle_sip_object_unref(base->last_response);
base->last_response=(belle_sip_response_t*)belle_sip_object_ref(resp);
if (dialog){
if (status_code>=200 && status_code<300
......@@ -285,8 +289,13 @@ void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t
}
}
}
if (dialog) belle_sip_dialog_update(dialog,base->request,resp,FALSE);
} else if (should_dialog_be_created(t,resp)) {
dialog=belle_sip_provider_create_dialog(t->base.provider,BELLE_SIP_TRANSACTION(t));
}
base->last_response=(belle_sip_response_t*)belle_sip_object_ref(resp);
if (dialog)
belle_sip_dialog_update(dialog,base->request,resp,FALSE);
event.source=base->provider;
event.client_transaction=t;
event.dialog=dialog;
......
......@@ -173,8 +173,14 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires=belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t)));
belle_sip_object_ref(expires); /*to be usable in an other message*/
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(contact=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t)));
belle_sip_object_ref(contact);/*to be usable in an other message*/
if (strcmp(belle_sip_request_get_method(req),"REGISTER")==0) {
contact=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);
belle_sip_object_ref(contact);/*to be usable in an other message*/
} else {
contact=belle_sip_header_contact_new();
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(contact));
} else {
resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),401);
if (www_authenticate)
......@@ -312,6 +318,74 @@ static void register_test_with_param(unsigned char expire_in_contact,auth_mode_t
destroy_endpoint(server);
}
static void subscribe_test() {
belle_sip_listener_callbacks_t client_callbacks;
belle_sip_listener_callbacks_t server_callbacks;
belle_sip_request_t* req;
belle_sip_client_transaction_t* trans;
belle_sip_header_route_t* destination_route;
const char* identity = "sip:" USERNAME "@" SIPDOMAIN ;
const char* domain="sip:" SIPDOMAIN ;
belle_sip_header_contact_t* contact=belle_sip_header_contact_new();
memset(&client_callbacks,0,sizeof(belle_sip_listener_callbacks_t));
memset(&server_callbacks,0,sizeof(belle_sip_listener_callbacks_t));
client_callbacks.process_response_event=client_process_response_event;
client_callbacks.process_auth_requested=client_process_auth_requested;
server_callbacks.process_request_event=server_process_request_event;
endpoint_t* client = create_udp_endpoint(3452,&client_callbacks);
endpoint_t* server = create_udp_endpoint(6788,&server_callbacks);
server->expire_in_contact=0;
server->auth=digest_auth;
destination_route=belle_sip_header_route_create(belle_sip_header_address_create(NULL,(belle_sip_uri_t*)belle_sip_listening_point_get_uri(server->lp)));
req=belle_sip_request_create(
belle_sip_uri_parse(domain),
"SUBSCRIBE",
belle_sip_provider_create_call_id(client->provider),
belle_sip_header_cseq_create(20,"SUBSCRIBE"),
belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
belle_sip_header_to_create2(identity,NULL),
belle_sip_header_via_new(),
70);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(contact));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(1)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(destination_route));
trans=belle_sip_provider_create_client_transaction(client->provider,req);
belle_sip_object_ref(trans);/*to avoid trans from being deleted before refresher can use it*/
belle_sip_client_transaction_send_request(trans);
CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.fourHundredOne,1,1000));
req=belle_sip_client_transaction_create_authenticated_request(trans);
belle_sip_object_unref(trans);
trans=belle_sip_provider_create_client_transaction(client->provider,req);
belle_sip_object_ref(trans);
belle_sip_client_transaction_send_request(trans);
CU_ASSERT_TRUE_FATAL(wait_for(server->stack,client->stack,&client->stat.twoHundredOk,1,1000));
/*maybe dialog should be automatically created*/
CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(trans)))
belle_sip_refresher_t* refresher = belle_sip_client_transaction_create_refresher(trans);
belle_sip_object_unref(trans);
belle_sip_refresher_set_listener(refresher,belle_sip_refresher_listener,client);
struct timeval begin;
gettimeofday(&begin, NULL);
CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,3,4000));
struct timeval end;
gettimeofday(&end, NULL);
CU_ASSERT_TRUE(end.tv_sec-begin.tv_sec>=3);
CU_ASSERT_TRUE(end.tv_sec-begin.tv_sec<5);
belle_sip_refresher_stop(refresher);
belle_sip_object_unref(refresher);
destroy_endpoint(client);
destroy_endpoint(server);
}
static void register_expires_header() {
register_test_with_param(0,none);
}
......@@ -341,6 +415,9 @@ int belle_sip_refresher_test_suite(){
if (NULL == CU_add_test(pSuite, "register_expires_in_contact_header_digest_auth", register_expires_in_contact_header_digest_auth)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "subscribe_test", subscribe_test)) {
return CU_get_error();
}
return 0;
}
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