Commit fb0ea39d authored by Simon Morlat's avatar Simon Morlat

add response/client transaction matching

parent cacabcae
......@@ -40,7 +40,7 @@ BELLE_SIP_DECLARE_INTERFACE_END
belle_sip_response_t* belle_sip_response_event_get_response(const belle_sip_response_event_t* event);
belle_sip_client_transaction_t *belle_sip_response_event_get_client_transaction(const belle_sip_response_event_t* event);
......
......@@ -45,6 +45,7 @@ libbellesip_la_SOURCES= \
message.c \
md5.c md5.h \
auth_helper.c \
siplistener.c \
ict.c \
nict.c \
transports/udp_listeningpoint.c \
......
......@@ -485,7 +485,7 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_client_transaction_t,belle_sip_tra
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, belle_sip_provider_t *prov, belle_sip_request_t *req);
void belle_sip_client_transaction_add_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp);
int belle_sip_client_transaction_add_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp);
struct belle_sip_ict{
belle_sip_client_transaction_t base;
......
......@@ -134,7 +134,6 @@ static void nict_send_request(belle_sip_nict_t *obj){
belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request);
if (!belle_sip_channel_is_reliable(base->channel)){
belle_sip_message("channel is not reliable");
obj->timer_E=belle_sip_timeout_source_new((belle_sip_source_func_t)nict_on_timer_E,obj,cfg->T1);
belle_sip_transaction_start_timer(base,obj->timer_E);
}
......
......@@ -29,8 +29,6 @@ static void channel_state_changed(belle_sip_channel_listener_t *obj, belle_sip_c
}
static void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, belle_sip_message_t *msg){
/*should find existing transaction*/
if (belle_sip_message_is_request(msg)){
belle_sip_request_event_t event;
event.source=prov;
......@@ -40,12 +38,17 @@ static void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, bell
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_request_event,&event);
}else{
belle_sip_response_event_t event;
int pass=1;
event.source=prov;
event.client_transaction=NULL;
event.client_transaction=belle_sip_provider_find_matching_client_transaction(prov,(belle_sip_response_t*)msg);
event.dialog=NULL;
event.response=(belle_sip_response_t*)msg;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_response_event,&event);
if (event.client_transaction){
pass=belle_sip_client_transaction_add_response(event.client_transaction,event.response);
}
if (pass) BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_response_event,&event);
}
belle_sip_object_unref(msg);
}
......@@ -233,9 +236,7 @@ void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_respons
if (chan) belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(resp));
}
belle_sip_response_t* belle_sip_response_event_get_response(const belle_sip_response_event_t* event) {
return event->response;
}
/*private provider API*/
void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t){
......@@ -248,11 +249,45 @@ void belle_sip_provider_add_client_transaction(belle_sip_provider_t *prov, belle
prov->client_transactions=belle_sip_list_prepend(prov->client_transactions,belle_sip_object_ref(t));
}
struct client_transaction_matcher{
const char *branchid;
const char *method;
};
static int client_transaction_match(const void *p_tr, const void *p_matcher){
belle_sip_client_transaction_t *tr=(belle_sip_client_transaction_t*)p_tr;
struct client_transaction_matcher *matcher=(struct client_transaction_matcher*)p_matcher;
const char *req_method=belle_sip_request_get_method(tr->base.request);
if (strcmp(matcher->branchid,tr->base.branch_id)==0 && strcmp(matcher->method,req_method)==0) return 0;
return -1;
}
belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transaction(belle_sip_provider_t *prov,
belle_sip_response_t *resp){
return NULL;
struct client_transaction_matcher matcher;
belle_sip_header_via_t *via=(belle_sip_header_via_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"via");
belle_sip_header_cseq_t *cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"cseq");
belle_sip_client_transaction_t *ret=NULL;
belle_sip_list_t *elem;
if (via==NULL){
belle_sip_warning("Response has no via.");
return NULL;
}
if (via==NULL){
belle_sip_warning("Response has no cseq.");
return NULL;
}
matcher.branchid=belle_sip_header_via_get_branch(via);
matcher.method=belle_sip_header_cseq_get_method(cseq);
elem=belle_sip_list_find_custom(prov->client_transactions,client_transaction_match,&matcher);
if (elem){
ret=(belle_sip_client_transaction_t*)elem->data;
belle_sip_message("Found transaction matching response.");
}
return ret;
}
void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t){
void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t){
prov->client_transactions=belle_sip_list_remove(prov->client_transactions,t);
belle_sip_object_unref(t);
}
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "belle_sip_internal.h"
belle_sip_response_t* belle_sip_response_event_get_response(const belle_sip_response_event_t* event) {
return event->response;
}
belle_sip_client_transaction_t *belle_sip_response_event_get_client_transaction(const belle_sip_response_event_t* event){
return event->client_transaction;
}
......@@ -147,22 +147,15 @@ void belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t
}else belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
}
void belle_sip_client_transaction_add_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
int belle_sip_client_transaction_add_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
belle_sip_transaction_t *base=(belle_sip_transaction_t*)t;
int pass=BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->on_response(t,resp);
if (pass){
belle_sip_response_event_t ev;
if (base->prov_response)
belle_sip_object_unref(base->prov_response);
base->prov_response=(belle_sip_response_t*)belle_sip_object_ref(resp);
ev.source=base->provider;
ev.response=resp;
ev.client_transaction=t;
ev.dialog=NULL;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(base->provider,process_response_event,&ev);
}
return pass;
}
static void client_transaction_destroy(belle_sip_client_transaction_t *t ){
......
......@@ -23,6 +23,7 @@
const char *test_domain="localhost";
static int is_register_ok;
static int using_transaction;
static belle_sip_stack_t * stack;
static belle_sip_provider_t *prov;
......@@ -40,7 +41,7 @@ static void process_response_event(belle_sip_listener_t *obj, const belle_sip_re
CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_response_event_get_response(event));
CU_ASSERT_EQUAL(belle_sip_response_get_status_code(belle_sip_response_event_get_response(event)),200);
is_register_ok=1;
belle_sip_object_unref(belle_sip_response_event_get_response(event));
using_transaction=belle_sip_response_event_get_client_transaction(event)!=NULL;
belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
}
static void process_timeout(belle_sip_listener_t *obj, const belle_sip_timeout_event_t *event){
......@@ -121,6 +122,7 @@ static void register_test(const char *transport, int use_transaction) {
70);
is_register_ok=0;
using_transaction=0;
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
if (use_transaction){
......@@ -129,6 +131,7 @@ static void register_test(const char *transport, int use_transaction) {
}else belle_sip_provider_send_request(prov,req);
belle_sip_stack_sleep(stack,33000);
CU_ASSERT_EQUAL(is_register_ok,1);
CU_ASSERT_EQUAL(using_transaction,use_transaction);
return;
}
......
......@@ -30,16 +30,16 @@ static int cleanup_cast_suite(){
static void cast_test(){
belle_sip_stack_t *stack=belle_sip_stack_new(NULL);
belle_sip_listening_point_t *lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",5040,"UDP");
CU_ASSERT_PTR_NOT_NULL(lp);
belle_sip_provider_t *provider=belle_sip_stack_create_provider(stack,lp);
belle_sip_listening_point_t *lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"UDP");
belle_sip_provider_t *provider;
belle_sip_request_t *req=belle_sip_request_new();
belle_sip_response_t *resp=belle_sip_response_new();
belle_sip_message_t *msg;
int tmp;
CU_ASSERT_PTR_NOT_NULL(stack);
CU_ASSERT_PTR_NOT_NULL(lp);
provider=belle_sip_stack_create_provider(stack,lp);
CU_ASSERT_PTR_NOT_NULL(provider);
CU_ASSERT_PTR_NOT_NULL(req);
CU_ASSERT_PTR_NOT_NULL(resp);
......@@ -58,6 +58,7 @@ static void cast_test(){
belle_sip_object_unref(req);
belle_sip_object_unref(resp);
belle_sip_object_unref(provider);
belle_sip_object_unref(lp);
belle_sip_object_unref(stack);
}
......
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