Commit 89abc5b1 authored by Simon Morlat's avatar Simon Morlat

dialog in progress

parent fe4d2326
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
......@@ -226,6 +226,11 @@ order to use an ANSI C compiler:
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
......
......@@ -37,31 +37,35 @@ belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *dialog,
void belle_sip_dialog_delete(belle_sip_dialog_t *dialog);
void *belle_sip_get_application_data(belle_sip_dialog_t *dialog);
void *belle_sip_get_application_data(const belle_sip_dialog_t *dialog);
void belle_sip_set_application_data(belle_sip_dialog_t *dialog, void *data);
const char *belle_sip_dialog_get_dialog_id(belle_sip_dialog_t *dialog);
const char *belle_sip_dialog_get_dialog_id(const belle_sip_dialog_t *dialog);
const belle_sip_header_address_t *belle_sip_get_local_party(belle_sip_dialog_t *dialog);
const belle_sip_header_call_id_t *belle_sip_dialog_get_call_id(const belle_sip_dialog_t *dialog);
const belle_sip_header_address_t *belle_sip_get_remote_party(belle_sip_dialog_t *dialog);
const belle_sip_header_address_t *belle_sip_get_local_party(const belle_sip_dialog_t *dialog);
unsigned int belle_sip_dialog_get_local_seq_number(belle_sip_dialog_t *dialog);
const belle_sip_header_address_t *belle_sip_get_remote_party(const belle_sip_dialog_t *dialog);
unsigned int belle_sip_dialog_get_remote_seq_number(belle_sip_dialog_t *dialog);
unsigned int belle_sip_dialog_get_local_seq_number(const belle_sip_dialog_t *dialog);
const char *belle_sip_dialog_get_local_tag(belle_sip_dialog_t *dialog);
unsigned int belle_sip_dialog_get_remote_seq_number(const belle_sip_dialog_t *dialog);
const char *belle_sip_dialog_get_remote_tag(belle_sip_dialog_t *dialog);
const char *belle_sip_dialog_get_local_tag(const belle_sip_dialog_t *dialog);
const char *belle_sip_dialog_get_remote_tag(const belle_sip_dialog_t *dialog);
const belle_sip_header_address_t *belle_sip_dialog_get_remote_target(belle_sip_dialog_t *dialog);
const belle_sip_list_t* belle_sip_dialog_get_route_set(belle_sip_dialog_t *dialog);
belle_sip_dialog_state_t belle_sip_dialog_get_state(belle_sip_dialog_t *dialog);
belle_sip_dialog_state_t belle_sip_dialog_get_state(const belle_sip_dialog_t *dialog);
int belle_sip_dialog_is_server(const belle_sip_dialog_t *dialog);
int belle_sip_dialog_is_server(belle_sip_dialog_t *dialog);
int belle_sip_dialog_is_secure(const belle_sip_dialog_t *dialog);
void belle_sip_dialog_send_ack(belle_sip_dialog_t *dialog, belle_sip_request_t *request);
......
......@@ -290,6 +290,7 @@ belle_sip_header_expires_t* belle_sip_header_expires_create(int expires);
belle_sip_header_record_route_t* belle_sip_header_record_route_parse (const char* route) ;
#define BELLE_SIP_HEADER_RECORD_ROUTE(t) BELLE_SIP_CAST(t,belle_sip_header_record_route_t)
#define BELLE_SIP_RECORD_ROUTE "Record-route"
/******************************
*
* user-Agent header inherit from header
......
......@@ -60,6 +60,11 @@ int belle_sip_message_is_response(const belle_sip_message_t *msg);
belle_sip_header_t *belle_sip_message_get_header(const belle_sip_message_t *msg, const char *header_name);
belle_sip_object_t *_belle_sip_message_get_header_by_type_id(const belle_sip_message_t *message, belle_sip_type_id_t id);
#define belle_sip_message_get_header_by_type(msg,header_type)\
(header_type*)_belle_sip_message_get_header_by_type_id(BELLE_SIP_MESSAGE(msg),BELLE_SIP_TYPE_ID(header_type))
const belle_sip_list_t* belle_sip_message_get_headers(const belle_sip_message_t *message,const char* header_name);
/**
......
......@@ -152,6 +152,9 @@ void belle_sip_object_set_name(belle_sip_object_t *obj,const char* name);
**/
const char* belle_sip_object_get_name(belle_sip_object_t *obj);
/*copy the content of ref object to new object, for the part they have in common in their inheritence diagram*/
void _belle_sip_object_copy(belle_sip_object_t *newobj, const belle_sip_object_t *ref);
belle_sip_object_t *belle_sip_object_clone(const belle_sip_object_t *obj);
/**
......
......@@ -38,6 +38,8 @@ void belle_sip_provider_remove_sip_listener(belle_sip_provider_t *p, belle_sip_l
belle_sip_header_call_id_t * belle_sip_provider_create_call_id(const belle_sip_provider_t *prov);
belle_sip_dialog_t *belle_sip_provider_create_dialog(belle_sip_provider_t *prov, belle_sip_transaction_t *t);
belle_sip_client_transaction_t *belle_sip_provider_create_client_transaction(belle_sip_provider_t *p, belle_sip_request_t *req);
belle_sip_server_transaction_t *belle_sip_provider_create_server_transaction(belle_sip_provider_t *p, belle_sip_request_t *req);
......
......@@ -50,6 +50,7 @@ libbellesip_la_SOURCES= \
ist.c \
nict.c \
nist.c \
dialog.c \
transports/udp_listeningpoint.c \
transports/udp_channel.c \
transports/stream_channel.c \
......
......@@ -262,7 +262,7 @@ belle_sip_header_from_t* belle_sip_header_from_create2(const char *address, cons
}
belle_sip_header_from_t* belle_sip_header_from_create(const belle_sip_header_address_t* address, const char *tag) {
belle_sip_header_from_t* header= belle_sip_header_from_new();
belle_sip_header_address_clone(BELLE_SIP_HEADER_ADDRESS(header),address);
_belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)address);
if (tag) belle_sip_header_from_set_tag(header,tag);
return header;
}
......@@ -317,7 +317,7 @@ belle_sip_header_to_t* belle_sip_header_to_create2(const char *address, const ch
}
belle_sip_header_to_t* belle_sip_header_to_create(const belle_sip_header_address_t* address, const char *tag) {
belle_sip_header_to_t* header= belle_sip_header_to_new();
belle_sip_header_address_clone(BELLE_SIP_HEADER_ADDRESS(header),address);
_belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)address);
if (tag) belle_sip_header_to_set_tag(header,tag);
return header;
}
......
......@@ -278,9 +278,9 @@ char *belle_sip_strdup_printf(const char *fmt,...);
return obj->attribute;\
}\
void object_type##_set_##attribute (object_type##_t* obj,const char* value) {\
if (obj->attribute != NULL) free((void*)obj->attribute);\
if (obj->attribute != NULL) belle_sip_free((void*)obj->attribute);\
if (value) {\
obj->attribute=malloc(strlen(value)+1);\
obj->attribute=belle_sip_malloc(strlen(value)+1);\
strcpy((char*)(obj->attribute),value);\
} else obj->attribute=NULL;\
}
......@@ -526,6 +526,7 @@ struct belle_sip_transaction{
belle_sip_request_t *request;
belle_sip_response_t *last_response;
belle_sip_channel_t *channel;
belle_sip_dialog_t *dialog;
char *branch_id;
belle_sip_transaction_state_t state;
uint64_t start_time;
......@@ -650,6 +651,30 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_END
belle_sip_nist_t * belle_sip_nist_new(belle_sip_provider_t *prov, belle_sip_request_t *req);
/*
* Dialogs
*/
struct belle_sip_dialog{
belle_sip_object_t base;
belle_sip_dialog_state_t state;
void *appdata;
belle_sip_header_call_id_t *call_id;
belle_sip_header_address_t *local_party;
belle_sip_header_address_t *remote_party;
belle_sip_list_t *route_set;
belle_sip_header_address_t *remote_target;
char *local_tag;
char *remote_tag;
unsigned int local_cseq;
unsigned int remote_cseq;
int is_server:1;
int is_secure:1;
int terminate_on_bye:1;
};
belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t);
/*
belle_sip_response_t
*/
......
......@@ -148,27 +148,50 @@ void belle_sip_object_delete(void *ptr){
belle_sip_free(obj);
}
static belle_sip_object_vptr_t *find_common_floor(belle_sip_object_vptr_t *vptr1, belle_sip_object_vptr_t *vptr2){
belle_sip_object_vptr_t *it1,*it2;
for (it1=vptr1;it1!=NULL;it1=it1->parent){
if (it1==vptr2)
return vptr2;
}
for(it2=vptr2;it2!=NULL;it2=it2->parent){
if (vptr1==it2)
return vptr1;
}
return NULL;
}
/*copy the content of ref object to new object, for the part they have in common in their inheritence diagram*/
void _belle_sip_object_copy(belle_sip_object_t *newobj, const belle_sip_object_t *ref){
belle_sip_object_vptr_t *vptr;
vptr=find_common_floor(newobj->vptr,ref->vptr);
if (vptr==NULL){
belle_sip_fatal("Should not happen");
}
while(vptr!=NULL){
if (vptr->clone==NULL){
belle_sip_fatal("Object of type %s cannot be cloned, it does not provide a clone() implementation.",vptr->type_name);
return;
}else vptr->clone(newobj,ref);
vptr=vptr->parent;
}
}
belle_sip_object_t *belle_sip_object_clone(const belle_sip_object_t *obj){
belle_sip_object_t *newobj;
belle_sip_object_vptr_t *vptr;
newobj=belle_sip_malloc0(obj->size);
newobj->ref=obj->vptr->initially_unowned ? 0 : 1;
newobj->vptr=obj->vptr;
newobj->size=obj->size;
if (obj->name) newobj->name=belle_sip_strdup(obj->name);
vptr=obj->vptr;
while(vptr!=NULL){
if (vptr->clone==NULL){
belle_sip_fatal("Object of type %s cannot be cloned, it does not provide a clone() implementation.",vptr->type_name);
return NULL;
}else vptr->clone(newobj,obj);
vptr=vptr->parent;
}
_belle_sip_object_copy(newobj,obj);
return newobj;
}
void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno){
if (obj!=NULL){
if (has_type(obj,id)==0){
......
/*
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"
static void belle_sip_dialog_uninit(belle_sip_dialog_t *obj){
if (obj->route_set)
belle_sip_list_free_with_data(obj->route_set,belle_sip_object_unref);
if (obj->remote_target)
belle_sip_object_unref(obj->remote_target);
if (obj->call_id)
belle_sip_object_unref(obj->call_id);
if (obj->local_party)
belle_sip_object_unref(obj->local_party);
if (obj->remote_party)
belle_sip_object_unref(obj->remote_party);
if (obj->local_tag)
belle_sip_free(obj->local_tag);
if (obj->remote_tag)
belle_sip_free(obj->remote_tag);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_dialog_t);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_dialog_t)={
BELLE_SIP_VPTR_INIT(belle_sip_dialog_t, belle_sip_object_t,FALSE),
(belle_sip_object_destroy_t)belle_sip_dialog_uninit,
NULL,
NULL
};
static void set_to_tag(belle_sip_dialog_t *obj, belle_sip_header_to_t *to){
const char *to_tag=belle_sip_header_to_get_tag(to);
if (obj->is_server){
if (to_tag)
obj->local_tag=belle_sip_strdup(to_tag);
}else{
if (to_tag)
obj->remote_tag=belle_sip_strdup(to_tag);
}
}
static void check_route_set(belle_sip_list_t *rs){
if (rs){
belle_sip_header_route_t *r=(belle_sip_header_route_t*)rs->data;
if (!belle_sip_uri_has_lr_param(belle_sip_header_address_get_uri((belle_sip_header_address_t*)r))){
belle_sip_warning("top uri of route set does not contain 'lr', not really supported.");
}
}
}
static int belle_sip_dialog_init_as_uas(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
const belle_sip_list_t *elem;
belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);
belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
belle_sip_header_call_id_t *call_id=belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
belle_sip_uri_t *requri=belle_sip_request_get_uri(req);
if (!ct){
belle_sip_error("No contact in request.");
return -1;
}
if (!to){
belle_sip_error("No to in response.");
return -1;
}
if (!cseq){
belle_sip_error("No cseq in request.");
return -1;
}
if (!call_id){
belle_sip_error("No call_id in request.");
return -1;
}
if (!via){
belle_sip_error("No via in request.");
return -1;
}
if (strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
&& belle_sip_uri_is_secure(requri)){
obj->is_secure=TRUE;
}
for(elem=belle_sip_message_get_headers((belle_sip_message_t*)req,BELLE_SIP_RECORD_ROUTE);elem!=NULL;elem=elem->next){
obj->route_set=belle_sip_list_append(obj->route_set,belle_sip_header_route_create(
(belle_sip_header_address_t*)elem->data));
}
check_route_set(obj->route_set);
obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
obj->remote_cseq=belle_sip_header_cseq_get_seq_number(cseq);
obj->call_id=(belle_sip_header_call_id_t*)belle_sip_object_ref(call_id);
/*remote party already set */
obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(to);
return 0;
}
static int belle_sip_dialog_init_as_uac(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
const belle_sip_list_t *elem;
belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
belle_sip_header_call_id_t *call_id=belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
belle_sip_uri_t *requri=belle_sip_request_get_uri(req);
if (!ct){
belle_sip_error("No contact in response.");
return -1;
}
if (!to){
belle_sip_error("No to in response.");
return -1;
}
if (!cseq){
belle_sip_error("No cseq in request.");
return -1;
}
if (!call_id){
belle_sip_error("No call_id in request.");
return -1;
}
if (!via){
belle_sip_error("No via in request.");
return -1;
}
if (strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
&& belle_sip_uri_is_secure(requri)){
obj->is_secure=TRUE;
}
for(elem=belle_sip_message_get_headers((belle_sip_message_t*)resp,BELLE_SIP_RECORD_ROUTE);elem!=NULL;elem=elem->next){
obj->route_set=belle_sip_list_prepend(obj->route_set,belle_sip_header_route_create(
(belle_sip_header_address_t*)elem->data));
}
check_route_set(obj->route_set);
obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
obj->local_cseq=belle_sip_header_cseq_get_seq_number(cseq);
obj->call_id=(belle_sip_header_call_id_t*)belle_sip_object_ref(call_id);
/*local_tag is already set*/
obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(to);
/*local party is already set*/
return 0;
}
int belle_sip_dialog_establish_full(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
if (obj->is_server)
return belle_sip_dialog_init_as_uas(obj,req,resp);
else
return belle_sip_dialog_init_as_uac(obj,req,resp);
}
int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
int code=belle_sip_response_get_status_code(resp);
belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
if (!to){
belle_sip_error("No to in response.");
return -1;
}
if (code>100 && code<200){
if (obj->state==BELLE_SIP_DIALOG_NULL)
set_to_tag(obj,to);
obj->state=BELLE_SIP_DIALOG_EARLY;
return -1;
}else if (code>=200 && code<300){
if (obj->state==BELLE_SIP_DIALOG_NULL)
set_to_tag(obj,to);
if (belle_sip_dialog_establish_full(obj,req,resp)==0){
obj->state=BELLE_SIP_DIALOG_CONFIRMED;
}else return -1;
}
return 0;
}
int belle_sip_dialog_update(belle_sip_dialog_t *obj,belle_sip_request_t *req, belle_sip_response_t *resp, int as_uas){
int code;
switch (obj->state){
case BELLE_SIP_DIALOG_NULL:
case BELLE_SIP_DIALOG_EARLY:
return belle_sip_dialog_establish(obj,req,resp);
case BELLE_SIP_DIALOG_CONFIRMED:
code=belle_sip_response_get_status_code(resp);
if (strcmp(belle_sip_request_get_method(req),"INVITE")==0 && code>=200 && code<300){
/*refresh the remote_target*/
belle_sip_header_contact_t *ct;
if (as_uas){
ct=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);
}else{
ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
}
if (ct){
belle_sip_object_unref(obj->remote_target);
obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
}
}else if (strcmp(belle_sip_request_get_method(req),"INVITE")==0 && code>=200 && code<300){
if (obj->terminate_on_bye) belle_sip_dialog_delete(obj);
}
break;
case BELLE_SIP_DIALOG_TERMINATED:
/*ignore*/
break;
}
return 0;
}
belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
belle_sip_dialog_t *obj;
belle_sip_header_from_t *from;
const char *from_tag;
if (t->last_response){
int code=belle_sip_response_get_status_code(t->last_response);
if (code>=200 && code<300){
belle_sip_fatal("You must not create dialog after sending the response that establish the dialog.");
}
return NULL;
}
from=belle_sip_message_get_header_by_type(t->request,belle_sip_header_from_t);
if (from==NULL){
belle_sip_error("belle_sip_dialog_new(): no from!");
return NULL;
}
from_tag=belle_sip_header_from_get_tag(from);
if (from_tag==NULL){
belle_sip_error("belle_sip_dialog_new(): no from tag!");
return NULL;
}
obj=belle_sip_object_new(belle_sip_dialog_t);
obj->terminate_on_bye=1;
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t)){
obj->remote_tag=belle_sip_strdup(from_tag);
obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
obj->is_server=TRUE;
}else{
obj->local_tag=belle_sip_strdup(from_tag);
obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
obj->is_server=FALSE;
}
obj->state=BELLE_SIP_DIALOG_NULL;
return obj;
}
belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *dialog, unsigned int cseq);
belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, const char *method){
if (obj->local_cseq==0) obj->local_cseq=110;
belle_sip_request_t *req=belle_sip_request_create(belle_sip_header_address_get_uri(obj->remote_target),
method,
obj->call_id,
belle_sip_header_cseq_create(obj->local_cseq++,method),
belle_sip_header_from_create(obj->local_party,NULL),
belle_sip_header_to_create(obj->remote_party,NULL),
belle_sip_header_via_new(),
0);
belle_sip_message_add_headers((belle_sip_message_t*)req,obj->route_set);
return req;
}
void belle_sip_dialog_delete(belle_sip_dialog_t *obj){
obj->state=BELLE_SIP_DIALOG_TERMINATED;
}
void *belle_sip_get_application_data(const belle_sip_dialog_t *dialog){
return dialog->appdata;
}
void belle_sip_set_application_data(belle_sip_dialog_t *dialog, void *data){
dialog->appdata=data;
}
const belle_sip_header_call_id_t *belle_sip_dialog_get_call_id(const belle_sip_dialog_t *dialog){
return dialog->call_id;
}
const char *belle_sip_dialog_get_dialog_id(const belle_sip_dialog_t *dialog){
return NULL;
}
const belle_sip_header_address_t *belle_sip_get_local_party(const belle_sip_dialog_t *dialog){
return dialog->local_party;
}
const belle_sip_header_address_t *belle_sip_get_remote_party(const belle_sip_dialog_t *dialog){
return dialog->remote_party;
}
unsigned int belle_sip_dialog_get_local_seq_number(const belle_sip_dialog_t *dialog){
return dialog->local_cseq;
}
unsigned int belle_sip_dialog_get_remote_seq_number(const belle_sip_dialog_t *dialog){
return dialog->remote_cseq;
}
const char *belle_sip_dialog_get_local_tag(const belle_sip_dialog_t *dialog){
return dialog->local_tag;
}
const char *belle_sip_dialog_get_remote_tag(const belle_sip_dialog_t *dialog){
return dialog->remote_tag;
}
const belle_sip_header_address_t *belle_sip_dialog_get_remote_target(belle_sip_dialog_t *dialog){
return dialog->remote_target;
}
const belle_sip_list_t* belle_sip_dialog_get_route_set(belle_sip_dialog_t *dialog){
return dialog->route_set;
}
belle_sip_dialog_state_t belle_sip_dialog_get_state(const belle_sip_dialog_t *dialog){
return dialog->state;
}
int belle_sip_dialog_is_server(const belle_sip_dialog_t *dialog){
return dialog->is_server;
}
int belle_sip_dialog_is_secure(const belle_sip_dialog_t *dialog){
return dialog->is_secure;
}
void belle_sip_dialog_send_ack(belle_sip_dialog_t *dialog, belle_sip_request_t *request);
void belle_sip_dialog_terminate_on_bye(belle_sip_dialog_t *obj, int val){
obj->terminate_on_bye=val;
}
......@@ -63,7 +63,7 @@ static belle_sip_request_t *make_ack(belle_sip_ict_t *obj, belle_sip_response_t
belle_sip_message_add_header((belle_sip_message_t*)obj->ack,
(belle_sip_header_t*)belle_sip_header_cseq_create(
belle_sip_header_cseq_get_seq_number((belle_sip_header_cseq_t*)belle_sip_message_get_header((belle_sip_message_t*)base->request,BELLE_SIP_CSEQ)),
"CANCEL"));
"ACK"));
}
return obj->ack;
......
......@@ -154,6 +154,18 @@ const belle_sip_list_t* belle_sip_message_get_headers(const belle_sip_message_t
return headers_container ? headers_container->header_list:NULL;
}
belle_sip_object_t *_belle_sip_message_get_header_by_type_id(const belle_sip_message_t *message, belle_sip_type_id_t id){
const belle_sip_list_t *e1;