Commit 67e1d559 authored by Simon Morlat's avatar Simon Morlat

bugfixes and progresses

parent 52632a80
......@@ -41,7 +41,11 @@ 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);
belle_sip_dialog_t *belle_sip_response_event_get_dialog(const belle_sip_response_event_t* event);
belle_sip_request_t* belle_sip_request_event_get_request(const belle_sip_request_event_t* event);
belle_sip_server_transaction_t *belle_sip_request_event_get_server_transaction(const belle_sip_request_event_t* event);
belle_sip_dialog_t *belle_sip_request_event_get_dialog(const belle_sip_request_event_t* event);
#endif
......
......@@ -47,6 +47,7 @@ libbellesip_la_SOURCES= \
auth_helper.c \
siplistener.c \
ict.c \
ist.c \
nict.c \
nist.c \
transports/udp_listeningpoint.c \
......
......@@ -476,12 +476,17 @@ struct belle_sip_provider{
belle_sip_list_t *lps; /*listening points*/
belle_sip_list_t *listeners;
belle_sip_list_t *client_transactions;
belle_sip_list_t *server_transactions;
};
belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp);
void belle_sip_provider_add_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t);
belle_sip_client_transaction_t *belle_sip_provider_find_matching_client_transaction(belle_sip_provider_t *prov, belle_sip_response_t *resp);
void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t);
void belle_sip_provider_add_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t *prov,
belle_sip_request_t *req);
void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t);
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const char *name, int port, const char *transport);
......@@ -598,6 +603,7 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_server_transaction_t,belle_sip_tra
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
void belle_sip_server_transaction_init(belle_sip_server_transaction_t *t, belle_sip_provider_t *prov,belle_sip_request_t *req);
void belle_sip_server_transaction_on_request(belle_sip_server_transaction_t *t, belle_sip_request_t *req);
struct belle_sip_ist{
belle_sip_server_transaction_t base;
......
......@@ -97,7 +97,11 @@ static void belle_sip_main_loop_destroy(belle_sip_main_loop_t *ml){
}
static int main_loop_done(void *data, unsigned int events){
belle_sip_debug("Got data on control fd...");
belle_sip_main_loop_t * m=(belle_sip_main_loop_t*)data;
char tmp;
if (read(m->control_fds[0],&tmp,sizeof(tmp))!=1){
belle_sip_error("Problem on control fd of main loop.");
}
return TRUE;
}
......@@ -110,7 +114,8 @@ belle_sip_main_loop_t *belle_sip_main_loop_new(void){
if (pipe(m->control_fds)==-1){
belle_sip_fatal("Could not create control pipe.");
}
m->control=belle_sip_fd_source_new(main_loop_done,NULL,m->control_fds[0],BELLE_SIP_EVENT_READ,-1);
m->control=belle_sip_fd_source_new(main_loop_done,m,m->control_fds[0],BELLE_SIP_EVENT_READ,-1);
belle_sip_object_set_name((belle_sip_object_t*)m->control,"main loop control fd");
belle_sip_main_loop_add_source(m,m->control);
return m;
}
......@@ -131,6 +136,7 @@ void belle_sip_main_loop_add_source(belle_sip_main_loop_t *ml, belle_sip_source_
unsigned long belle_sip_main_loop_add_timeout(belle_sip_main_loop_t *ml, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms){
belle_sip_source_t * s=belle_sip_timeout_source_new(func,data,timeout_value_ms);
belle_sip_object_set_name((belle_sip_object_t*)s,"timeout");
belle_sip_main_loop_add_source(ml,s);
belle_sip_object_unref(s);
return s->id;
......@@ -248,7 +254,10 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
}
}
if (revents!=0 || (s->timeout>0 && cur>=s->expire_ms)){
char *objdesc=belle_sip_object_to_string((belle_sip_object_t*)s);
s->expired=TRUE;
belle_sip_message("source %s notified revents=%u, timeout=%i",objdesc,revents,s->timeout);
belle_sip_free(objdesc);
ret=s->notify(s->data,revents);
if (ret==0){
/*this source needs to be removed*/
......
......@@ -116,6 +116,10 @@ static void _belle_sip_object_clone(belle_sip_object_t *obj, const belle_sip_obj
if (orig->name!=NULL) obj->name=belle_sip_strdup(obj->name);
}
static int _belle_object_marshall(belle_sip_object_t* obj, char* buff,unsigned int offset,size_t buff_size) {
return snprintf(buff+offset,buff_size,"{%s::%s %p}",obj->vptr->type_name,obj->name ? obj->name : "(no name)",obj);
}
belle_sip_object_vptr_t belle_sip_object_t_vptr={
BELLE_SIP_TYPE_ID(belle_sip_object_t),
"belle_sip_object_t",
......@@ -124,7 +128,7 @@ belle_sip_object_vptr_t belle_sip_object_t_vptr={
NULL,
_belle_sip_object_uninit,
_belle_sip_object_clone,
NULL
_belle_object_marshall
};
void belle_sip_object_delete(void *ptr){
......
......@@ -60,6 +60,8 @@ void belle_sip_resolver_context_destroy(belle_sip_resolver_context_t *ctx){
if (ctx->ai){
freeaddrinfo(ctx->ai);
}
close(ctx->ctlpipe[0]);
close(ctx->ctlpipe[1]);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_resolver_context_t);
......@@ -81,7 +83,6 @@ belle_sip_resolver_context_t *belle_sip_resolver_context_new(){
belle_sip_fatal("pipe() failed: %s",strerror(errno));
}
belle_sip_fd_source_init(&ctx->source,(belle_sip_source_func_t)resolver_callback,ctx,ctx->ctlpipe[0],BELLE_SIP_EVENT_READ,-1);
ctx->source.on_remove=(belle_sip_source_remove_callback_t)belle_sip_object_unref;
return ctx;
}
......@@ -123,6 +124,7 @@ unsigned long belle_sip_resolve(const char *name, int port, unsigned int hints,
ctx->port=port;
ctx->hints=hints;
belle_sip_main_loop_add_source(ml,(belle_sip_source_t*)ctx);
belle_sip_object_unref(ctx);
pthread_create(&ctx->thread,NULL,belle_sip_resolver_thread,ctx);
return ctx->source.id;
}else{
......
......@@ -93,6 +93,8 @@ static void ict_on_response(belle_sip_ict_t *obj, belle_sip_response_t *resp){
}else if (code>=200){
belle_sip_transaction_terminate(base);
belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp);
}else if (code>=100){
belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp);
}
break;
case BELLE_SIP_TRANSACTION_COMPLETED:
......
......@@ -18,7 +18,7 @@
/**
* INVITE server transaction implementation.
**
**/
#include "belle_sip_internal.h"
......
......@@ -36,35 +36,51 @@ 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){
if (belle_sip_message_is_request(msg)){
belle_sip_request_event_t event;
static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, belle_sip_request_t *req){
belle_sip_server_transaction_t *t;
t=belle_sip_provider_find_matching_server_transaction(prov,req);
if (t){
belle_sip_object_ref(t);
belle_sip_server_transaction_on_request(t,req);
belle_sip_object_unref(t);
}else{
belle_sip_request_event_t ev;
ev.source=prov;
ev.server_transaction=NULL;
ev.dialog=NULL;
ev.request=req;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_request_event,&ev);
}
}
static void belle_sip_provider_dispatch_response(belle_sip_provider_t* prov, belle_sip_response_t *msg){
belle_sip_client_transaction_t *t;
t=belle_sip_provider_find_matching_client_transaction(prov,msg);
/*
* If a transaction is found, pass it to the transaction and let it decide what to do.
* Else notifies directly.
*/
if (t){
/*since the add_response may indirectly terminate the transaction, we need to guarantee the transaction is not freed
* until full completion*/
belle_sip_object_ref(t);
belle_sip_client_transaction_add_response(t,msg);
belle_sip_object_unref(t);
}else{
belle_sip_response_event_t event;
event.source=prov;
event.server_transaction=NULL;
event.request=(belle_sip_request_t*)msg;
event.client_transaction=NULL;
event.dialog=NULL;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_request_event,&event);
event.response=msg;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_response_event,&event);
}
}
static void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, belle_sip_message_t *msg){
if (belle_sip_message_is_request(msg)){
belle_sip_provider_dispatch_request(prov,(belle_sip_request_t*)msg);
}else{
belle_sip_client_transaction_t *t;
t=belle_sip_provider_find_matching_client_transaction(prov,(belle_sip_response_t*)msg);
/*
* If a transaction is found, pass it to the transaction and let it decide what to do.
* Else notifies directly.
*/
if (t){
/*since the add_response may indirectly terminate the transaction, we need to guarantee the transaction is not freed
* until full completion*/
belle_sip_object_ref(t);
belle_sip_client_transaction_add_response(t,(belle_sip_response_t*)msg);
belle_sip_object_unref(t);
}else{
belle_sip_response_event_t event;
event.source=prov;
event.client_transaction=NULL;
event.dialog=NULL;
event.response=(belle_sip_response_t*)msg;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov,process_response_event,&event);
}
belle_sip_provider_dispatch_response(prov,(belle_sip_response_t*)msg);
}
belle_sip_object_unref(msg);
}
......@@ -121,8 +137,11 @@ static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_chan
belle_sip_header_contact_t* contact = (belle_sip_header_contact_t*)belle_sip_message_get_header(msg,"Contact");
belle_sip_header_content_length_t* content_lenght = (belle_sip_header_content_length_t*)belle_sip_message_get_header(msg,"Content-Length");
belle_sip_uri_t* contact_uri;
/*probably better to be in channel*/
fix_outgoing_via((belle_sip_provider_t*)obj,chan,msg);
if (belle_sip_message_is_request(msg)){
/*probably better to be in channel*/
fix_outgoing_via((belle_sip_provider_t*)obj,chan,msg);
}
/* fix the contact if empty*/
if (!(contact_uri =belle_sip_header_address_get_uri((belle_sip_header_address_t*)contact))) {
......@@ -169,6 +188,7 @@ int belle_sip_provider_add_listening_point(belle_sip_provider_t *p, belle_sip_li
p->lps=belle_sip_list_append(p->lps,belle_sip_object_ref(lp));
return 0;
}
void belle_sip_provider_remove_listening_point(belle_sip_provider_t *p, belle_sip_listening_point_t *lp) {
p->lps=belle_sip_list_remove(p->lps,lp);
belle_sip_object_unref(lp);
......@@ -216,10 +236,13 @@ belle_sip_client_transaction_t *belle_sip_provider_create_client_transaction(bel
}
belle_sip_server_transaction_t *belle_sip_provider_create_server_transaction(belle_sip_provider_t *prov, belle_sip_request_t *req){
belle_sip_server_transaction_t* t;
if (strcmp(belle_sip_request_get_method(req),"INVITE")==0)
return (belle_sip_server_transaction_t*)belle_sip_ist_new(prov,req);
t=(belle_sip_server_transaction_t*)belle_sip_ist_new(prov,req);
else
return (belle_sip_server_transaction_t*)belle_sip_nist_new(prov,req);
t=(belle_sip_server_transaction_t*)belle_sip_nist_new(prov,req);
belle_sip_provider_add_server_transaction(prov,t);
return t;
}
belle_sip_stack_t *belle_sip_provider_get_sip_stack(belle_sip_provider_t *p){
......@@ -279,6 +302,8 @@ void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, bell
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(t->provider,process_transaction_terminated,&ev);
if (!ev.is_server_transaction){
belle_sip_provider_remove_client_transaction(p,(belle_sip_client_transaction_t*)t);
}else{
belle_sip_provider_remove_server_transaction(p,(belle_sip_server_transaction_t*)t);
}
}
......@@ -310,7 +335,7 @@ belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transac
belle_sip_warning("Response has no via.");
return NULL;
}
if (via==NULL){
if (cseq==NULL){
belle_sip_warning("Response has no cseq.");
return NULL;
}
......@@ -328,3 +353,56 @@ void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, be
prov->client_transactions=belle_sip_list_remove(prov->client_transactions,t);
belle_sip_object_unref(t);
}
void belle_sip_provider_add_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t){
prov->server_transactions=belle_sip_list_prepend(prov->server_transactions,belle_sip_object_ref(t));
}
struct server_transaction_matcher{
const char *branchid;
const char *method;
const char *sentby;
int is_ack;
};
static int rfc3261_server_transaction_match(const void *p_tr, const void *p_matcher){
belle_sip_server_transaction_t *tr=(belle_sip_server_transaction_t*)p_tr;
struct server_transaction_matcher *matcher=(struct server_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){
if (strcmp(matcher->method,req_method)==0) return 0;
if (matcher->is_ack && strcmp(req_method,"INVITE")==0) return 0;
}
return -1;
}
belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t *prov, belle_sip_request_t *req){
struct server_transaction_matcher matcher;
belle_sip_header_via_t *via=(belle_sip_header_via_t*)belle_sip_message_get_header((belle_sip_message_t*)req,"via");
belle_sip_server_transaction_t *ret=NULL;
belle_sip_list_t *elem;
if (via==NULL){
belle_sip_warning("Request has no via.");
return NULL;
}
matcher.branchid=belle_sip_header_via_get_branch(via);
matcher.method=belle_sip_request_get_method(req);
matcher.is_ack=(strcmp(matcher.method,"ACK")==0);
if (strncmp(matcher.branchid,BELLE_SIP_BRANCH_MAGIC_COOKIE,strlen(BELLE_SIP_BRANCH_MAGIC_COOKIE))==0){
/*compliant to RFC3261*/
elem=belle_sip_list_find_custom(prov->client_transactions,rfc3261_server_transaction_match,&matcher);
}else{
//FIXME
}
if (elem){
ret=(belle_sip_server_transaction_t*)elem->data;
belle_sip_message("Found transaction matching request.");
}
return ret;
}
void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t){
prov->server_transactions=belle_sip_list_remove(prov->server_transactions,t);
belle_sip_object_unref(t);
}
......@@ -79,16 +79,9 @@ belle_sip_transaction_state_t belle_sip_transaction_get_state(const belle_sip_tr
}
void belle_sip_transaction_terminate(belle_sip_transaction_t *t){
belle_sip_transaction_terminated_event_t ev;
t->state=BELLE_SIP_TRANSACTION_TERMINATED;
belle_sip_provider_set_transaction_terminated(t->provider,t);
BELLE_SIP_OBJECT_VPTR(t,belle_sip_transaction_t)->on_terminate(t);
ev.source=t->provider;
ev.transaction=t;
ev.is_server_transaction=BELLE_SIP_IS_INSTANCE_OF(t,belle_sip_server_transaction_t);
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(t->provider,process_transaction_terminated,&ev);
}
belle_sip_request_t *belle_sip_transaction_get_request(belle_sip_transaction_t *t){
......@@ -144,8 +137,14 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
}
}
void belle_sip_server_transaction_on_retransmission(belle_sip_server_transaction_t *t){
BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->on_request_retransmission(t);
void belle_sip_server_transaction_on_request(belle_sip_server_transaction_t *t, belle_sip_request_t *req){
const char *method=belle_sip_request_get_method(req);
if (strcmp(method,"ACK")==0){
belle_sip_error("please handle this ack");
}else if (strcmp(method,"CANCEL")==0){
belle_sip_error("please handle this cancel ??");
}else
BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->on_request_retransmission(t);
}
/*
......@@ -280,8 +279,4 @@ void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, bell
belle_sip_transaction_init((belle_sip_transaction_t*)obj, prov,req);
}
belle_sip_ist_t *belle_sip_ist_new(belle_sip_provider_t *prov, belle_sip_request_t *req){
return NULL;
}
......@@ -25,8 +25,13 @@ static void belle_sip_tls_listening_point_uninit(belle_sip_tls_listening_point_t
}
static belle_sip_channel_t *tls_create_channel(belle_sip_listening_point_t *lp, const char *dest_ip, int port){
#ifdef HAVE_GNUTLS
belle_sip_channel_t *chan=belle_sip_channel_new_tls(BELLE_SIP_TLS_LISTENING_POINT(lp),lp->addr,lp->port,dest_ip,port);
return chan;
#else
return NULL;
#endif
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_tls_listening_point_t);
......
......@@ -21,7 +21,7 @@
#include "belle-sip/belle-sip.h"
#include "pthread.h"
const char *test_domain="localhost";
const char *test_domain="test.linphone.org";
static int is_register_ok;
static int using_transaction;
static belle_sip_stack_t * stack;
......@@ -117,6 +117,11 @@ static void register_test(const char *transport, int use_transaction) {
snprintf(uri,sizeof(uri),"sip:%s;transport=%s",test_domain,transport);
else snprintf(uri,sizeof(uri),"sip:%s",test_domain);
if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
belle_sip_error("No TLS support, test skipped.");
return;
}
snprintf(identity,sizeof(identity),"Tester <sip:tester@%s>",test_domain);
req=belle_sip_request_create(
belle_sip_uri_parse(uri),
......
......@@ -30,6 +30,10 @@ extern int belle_sip_register_test_suite();
int main (int argc, char *argv[]) {
int i;
const char *env_domain=getenv("TEST_DOMAIN");
if (env_domain)
test_domain=env_domain;
for(i=1;i<argc;++i){
if (strcmp(argv[i],"--help")==0){
fprintf(stderr,"%s \t--help\n\t\t\t--verbose",argv[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