Commit 43764778 authored by Ghislain MARY's avatar Ghislain MARY

Improve marshalling.

 - Use our own implementation of snprintf() called belle_sip_snprintf() to handle the various native implementations whose return values are not consistent.
 - Simplify error handling in marshalling.
parent 1c7e3e47
......@@ -21,6 +21,7 @@
#include "belle-sip/defs.h"
#include "belle-sip/uri.h"
#include "belle-sip/utils.h"
#include <time.h>
......@@ -75,7 +76,7 @@ typedef struct _belle_sip_header belle_sip_header_t;
BELLESIP_EXPORT belle_sip_header_t* belle_sip_header_create (const char* name,const char* value);
BELLESIP_EXPORT const char* belle_sip_header_get_name (const belle_sip_header_t* obj);
BELLESIP_EXPORT void belle_sip_header_set_name (belle_sip_header_t* obj,const char* value);
BELLESIP_EXPORT int belle_sip_header_marshal(belle_sip_header_t* header, char* buff, unsigned int offset,unsigned int buff_size);
BELLESIP_EXPORT belle_sip_error_code belle_sip_header_marshal(belle_sip_header_t* header, char* buff, size_t buff_size, unsigned int *offset);
BELLESIP_EXPORT const char *belle_sip_header_get_unparsed_value(belle_sip_header_t* obj);
#define BELLE_SIP_HEADER(t) BELLE_SIP_CAST(t,belle_sip_header_t)
......
......@@ -20,6 +20,7 @@
#define belle_sip_object_h
#include "belle-sip/defs.h"
#include "belle-sip/utils.h"
/*
* typedefs, macros and functions for object definition and manipulation.
......@@ -113,7 +114,7 @@ typedef struct _belle_sip_object belle_sip_object_t;
typedef void (*belle_sip_object_destroy_t)(belle_sip_object_t*);
typedef void (*belle_sip_object_clone_t)(belle_sip_object_t* obj, const belle_sip_object_t *orig);
typedef int (*belle_sip_object_marshal_t)(belle_sip_object_t* obj, char* buff,unsigned int offset,size_t buff_size);
typedef int (*belle_sip_object_marshal_t)(belle_sip_object_t* obj, char* buff, size_t buff_size, unsigned int *offset);
struct _belle_sip_object_vptr{
belle_sip_type_id_t id;
......@@ -230,7 +231,7 @@ BELLESIP_EXPORT char* belle_sip_object_to_string(void* obj);
* Writes a string representation of the object into the supplied buffer.
* Same as belle_sip_object_to_string(), but without allocating space for the output string.
**/
BELLESIP_EXPORT int belle_sip_object_marshal(belle_sip_object_t* obj, char* buff,unsigned int offset,size_t buff_size);
BELLESIP_EXPORT belle_sip_error_code belle_sip_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, unsigned int *offset);
BELLESIP_EXPORT int belle_sip_object_is_instance_of(belle_sip_object_t * obj,belle_sip_type_id_t id);
......
......@@ -19,6 +19,7 @@
#ifndef PARAMETERS_H_
#define PARAMETERS_H_
#include "belle-sip/utils.h"
#include "belle-sip/list.h"
/***
* parameters
......@@ -51,7 +52,7 @@ BELLESIP_EXPORT const belle_sip_list_t * belle_sip_parameters_get_parameters(con
BELLESIP_EXPORT void belle_sip_parameters_remove_parameter(belle_sip_parameters_t* obj,const char* name);
BELLESIP_EXPORT int belle_sip_parameters_marshal(const belle_sip_parameters_t* obj, char* buff,unsigned int offset,unsigned int buff_size);
BELLESIP_EXPORT belle_sip_error_code belle_sip_parameters_marshal(const belle_sip_parameters_t* obj, char* buff, size_t buff_size, unsigned int *offset);
#define BELLE_SIP_PARAMETERS(obj) BELLE_SIP_CAST(obj,belle_sip_parameters_t)
......
......@@ -10,6 +10,7 @@
#include "belle-sip/defs.h"
#include "belle-sip/list.h"
#include "belle-sip/utils.h"
/*inherite from belle_sip_parameters_t*/
typedef struct _belle_sip_uri belle_sip_uri_t;
......@@ -184,7 +185,7 @@ BELLESIP_EXPORT void belle_sip_uri_fix(belle_sip_uri_t *uri);
*/
BELLESIP_EXPORT char* belle_sip_uri_to_string(belle_sip_uri_t* uri) ;
int belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buff,unsigned int offset,unsigned int buff_size);
belle_sip_error_code belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buff, size_t buff_size, unsigned int *offset);
#define BELLE_SIP_URI(obj) BELLE_SIP_CAST(obj,belle_sip_uri_t)
......
......@@ -41,6 +41,13 @@ typedef enum {
typedef void (*belle_sip_log_function_t)(belle_sip_log_level lev, const char *fmt, va_list args);
typedef enum {
BELLE_SIP_NOT_IMPLEMENTED = -2,
BELLE_SIP_BUFFER_OVERFLOW = -1,
BELLE_SIP_OK = 0
} belle_sip_error_code;
#ifdef __GNUC__
#define BELLE_SIP_CHECK_FORMAT_ARGS(m,n) __attribute__((format(printf,m,n)))
#else
......@@ -137,6 +144,8 @@ BELLESIP_EXPORT void belle_sip_set_log_handler(belle_sip_log_function_t func);
BELLESIP_EXPORT char * BELLE_SIP_CHECK_FORMAT_ARGS(1,2) belle_sip_strdup_printf(const char *fmt,...);
BELLESIP_EXPORT belle_sip_error_code belle_sip_snprintf(char *buff, unsigned int buff_size, unsigned int *offset, const char *fmt, ...);
BELLESIP_EXPORT void belle_sip_set_log_level(int level);
BELLESIP_EXPORT char * belle_sip_random_token(char *ret, size_t size);
......
This diff is collapsed.
This diff is collapsed.
......@@ -129,8 +129,8 @@ 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);
static belle_sip_error_code _belle_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, unsigned int *offset) {
return belle_sip_snprintf(buff,buff_size,offset,"{%s::%s %p}",obj->vptr->type_name,obj->name ? obj->name : "(no name)",obj);
}
belle_sip_object_vptr_t belle_sip_object_t_vptr={
......@@ -141,7 +141,7 @@ belle_sip_object_vptr_t belle_sip_object_t_vptr={
NULL,
_belle_sip_object_uninit,
_belle_sip_object_clone,
_belle_object_marshall
_belle_object_marshal
};
void belle_sip_object_delete(void *ptr){
......@@ -264,60 +264,57 @@ const char* belle_sip_object_get_name(belle_sip_object_t* object) {
#if CHECKED_MARSHAL
static int checked_marshal(belle_sip_object_vptr_t *vptr, belle_sip_object_t* obj, char* buff,unsigned int offset,size_t buff_size){
static belle_sip_error_code checked_marshal(belle_sip_object_vptr_t *vptr, belle_sip_object_t* obj, char* buff, size_t buff_size, unsigned int *offset){
int tmp_buf_size=buff_size*2;
char *p=(char*)belle_sip_malloc0(tmp_buf_size);
int i;
int ret=vptr->marshal(obj,p,offset,buff_size);
unsigned int initial_offset=*offset;
belle_sip_error_code error=vptr->marshal(obj,p,buff_size,offset);
int written;
for (i=offset;i<buff_size;++i){
if (p[i]=='\0') break;
}
written=i-offset;
if (written>(buff_size-offset)){
belle_sip_fatal("Object of type %s commited a buffer overflow by marshalling %i bytes ",
vptr->type_name,written);
}
if (written!=ret && written!=(buff_size-offset-1)){ /*this is because snprintf won't allow you to write a non null character at the end of the buffer*/
belle_sip_fatal("Object of type %s marshalled %i bytes but said it marshalled %i bytes !",
vptr->type_name,written,ret);
}
memcpy(buff+offset,p+offset,ret);
if (error==BELLE_SIP_BUFFER_OVERFLOW){
belle_sip_fatal("Object of type %s commited a buffer overflow by marshalling %i bytes",
vptr->type_name,*offset-initial_offset);
} else if (error!=BELLE_SIP_OK){
belle_sip_fatal("Object of type %s produced an error during marshalling: %i",
vptr->type_name,error);
}
memcpy(buff+initial_offset,p,*offset-initial_offset);
belle_sip_free(p);
return ret;
}
#endif
int belle_sip_object_marshal(belle_sip_object_t* obj, char* buff,unsigned int offset,size_t buff_size) {
belle_sip_error_code belle_sip_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, unsigned int *offset) {
belle_sip_object_vptr_t *vptr=obj->vptr;
while (vptr != NULL) {
if (vptr->marshal != NULL) {
#if CHECKED_MARSHAL
return checked_marshal(vptr,obj,buff,offset,buff_size);
return checked_marshal(vptr,obj,buff,buff_size,offset);
#else
return vptr->marshal(obj,buff,offset,buff_size);
return vptr->marshal(obj,buff,buff_size,offset);
#endif
} else {
vptr=vptr->parent;
}
}
return -1; /*no implementation found*/
return BELLE_SIP_NOT_IMPLEMENTED; /*no implementation found*/
}
static char * belle_sip_object_to_alloc_string(belle_sip_object_t *obj, int size_hint){
char *buf=belle_sip_malloc(size_hint);
int size = belle_sip_object_marshal(obj,buf,0,size_hint-1);
unsigned int offset=0;
belle_sip_error_code error = belle_sip_object_marshal(obj,buf,size_hint-1,&offset);
obj->vptr->tostring_bufsize_hint=size_hint;
if (size>=size_hint-1){
if (error==BELLE_SIP_BUFFER_OVERFLOW){
belle_sip_message("belle_sip_object_to_alloc_string(): hint buffer was too short while doing to_string() for %s, retrying", obj->vptr->type_name);
belle_sip_free(buf);
return belle_sip_object_to_alloc_string(obj,2*size_hint);
}
buf[size]='\0';
buf=belle_sip_realloc(buf,size+1);
buf=belle_sip_realloc(buf,offset+1);
buf[offset]='\0';
return buf;
}
......@@ -333,13 +330,14 @@ char* belle_sip_object_to_string(void* _obj) {
return belle_sip_object_to_alloc_string(obj,obj->vptr->tostring_bufsize_hint);
}else{
char buff[BELLE_SIP_MAX_TO_STRING_SIZE];
int size = belle_sip_object_marshal(obj,buff,0,sizeof(buff));
if (size>=sizeof(buff)-1){
unsigned int offset=0;
belle_sip_error_code error = belle_sip_object_marshal(obj,buff,sizeof(buff),&offset);
if (error==BELLE_SIP_BUFFER_OVERFLOW){
belle_sip_message("belle_sip_object_to_string(): temporary buffer is too short while doing to_string() for %s, retrying", obj->vptr->type_name);
return belle_sip_object_to_alloc_string(obj,get_hint_size(2*size));
return belle_sip_object_to_alloc_string(obj,get_hint_size(2*offset));
}
buff[size]='\0';
obj->vptr->tostring_bufsize_hint=get_hint_size(2*size);
buff[offset]='\0';
obj->vptr->tostring_bufsize_hint=get_hint_size(2*offset);
return belle_sip_strdup(buff);
}
}
......@@ -350,26 +348,26 @@ char * _belle_sip_object_describe_type(belle_sip_object_vptr_t *vptr){
belle_sip_object_vptr_t *it;
int pos=0;
belle_sip_list_t *l=NULL,*elem;
pos+=snprintf(ret+pos,maxbufsize-pos,"Ownership:\n");
pos+=snprintf(ret+pos,maxbufsize-pos,"\t%s is created initially %s\n",vptr->type_name,
belle_sip_snprintf(ret,maxbufsize,&pos,"Ownership:\n");
belle_sip_snprintf(ret,maxbufsize,&pos,"\t%s is created initially %s\n",vptr->type_name,
vptr->initially_unowned ? "unowned" : "owned");
pos+=snprintf(ret+pos,maxbufsize-pos,"\nInheritance diagram:\n");
belle_sip_snprintf(ret,maxbufsize,&pos,"\nInheritance diagram:\n");
for(it=vptr;it!=NULL;it=it->parent){
l=belle_sip_list_prepend(l,it);
}
for(elem=l;elem!=NULL;elem=elem->next){
it=(belle_sip_object_vptr_t*)elem->data;
pos+=snprintf(ret+pos,maxbufsize-pos,"\t%s\n",it->type_name);
belle_sip_snprintf(ret,maxbufsize,&pos,"\t%s\n",it->type_name);
if (elem->next)
pos+=snprintf(ret+pos,maxbufsize-pos,"\t |\n");
belle_sip_snprintf(ret,maxbufsize,&pos,"\t |\n");
}
belle_sip_list_free(l);
pos+=snprintf(ret+pos,maxbufsize-pos,"\nImplemented interfaces:\n");
belle_sip_snprintf(ret,maxbufsize,&pos,"\nImplemented interfaces:\n");
for(it=vptr;it!=NULL;it=it->parent){
belle_sip_interface_desc_t **desc=it->interfaces;
if (desc!=NULL){
for(;*desc!=NULL;desc++){
pos+=snprintf(ret+pos,maxbufsize-pos,"\t* %s\n",(*desc)->ifname);
belle_sip_snprintf(ret,maxbufsize,&pos,"\t* %s\n",(*desc)->ifname);
}
}
}
......
......@@ -41,19 +41,19 @@ static void belle_sip_parameters_clone(belle_sip_parameters_t *params, const bel
}
}
int belle_sip_parameters_marshal(const belle_sip_parameters_t* params, char* buff,unsigned int offset,unsigned int buff_size) {
belle_sip_error_code belle_sip_parameters_marshal(const belle_sip_parameters_t* params, char* buff,unsigned int buff_size,unsigned int *offset) {
belle_sip_list_t* list=params->param_list;
unsigned int current_offset=offset;
belle_sip_error_code error=BELLE_SIP_OK;
for(;list!=NULL;list=list->next){
belle_sip_param_pair_t* container = (belle_sip_param_pair_t* )(list->data);
if (container->value) {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,";%s=%s",container->name,container->value);
error=belle_sip_snprintf(buff,buff_size,offset,";%s=%s",container->name,container->value);
} else {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,";%s",container->name);
error=belle_sip_snprintf(buff,buff_size,offset,";%s",container->name);
}
if (current_offset>=buff_size) return buff_size-offset;
if (error!=BELLE_SIP_OK) return error;
}
return current_offset-offset;
return error;
}
BELLE_SIP_NEW_HEADER(parameters,header,"parameters")
const belle_sip_list_t * belle_sip_parameters_get_parameters(const belle_sip_parameters_t* obj) {
......
......@@ -69,48 +69,48 @@ static void belle_sip_uri_clone(belle_sip_uri_t* uri, const belle_sip_uri_t *ori
}
int belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset;
belle_sip_error_code belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buff, size_t buff_size, unsigned int *offset) {
const belle_sip_list_t* list=belle_sip_parameters_get_parameters(uri->header_list);
belle_sip_error_code error=BELLE_SIP_OK;
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s:",uri->secure?"sips":"sip");
if (current_offset>=buff_size) return buff_size-offset;
error=belle_sip_snprintf(buff,buff_size,offset,"%s:",uri->secure?"sips":"sip");
if (error!=BELLE_SIP_OK) return error;
if (uri->user) {
char* escaped_username=belle_sip_to_escaped_string(uri->user);
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s@",escaped_username);
error=belle_sip_snprintf(buff,buff_size,offset,"%s@",escaped_username);
belle_sip_free(escaped_username);
if (current_offset>=buff_size) return buff_size-offset;
if (error!=BELLE_SIP_OK) return error;
}
if (uri->host) {
if (strchr(uri->host,':')) { /*ipv6*/
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"[%s]",uri->host);
error=belle_sip_snprintf(buff,buff_size,offset,"[%s]",uri->host);
} else {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s",uri->host);
error=belle_sip_snprintf(buff,buff_size,offset,"%s",uri->host);
}
if (current_offset>=buff_size) return buff_size-offset;
if (error!=BELLE_SIP_OK) return error;
} else {
belle_sip_warning("no host found in this uri");
}
if (uri->port>0) {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,":%i",uri->port);
if (current_offset>=buff_size) return buff_size-offset;
error=belle_sip_snprintf(buff,buff_size,offset,":%i",uri->port);
if (error!=BELLE_SIP_OK) return error;
}
current_offset+=belle_sip_parameters_marshal(&uri->params,buff,current_offset,buff_size);
if (current_offset>=buff_size) return buff_size-offset;
error=belle_sip_parameters_marshal(&uri->params,buff,buff_size,offset);
if (error!=BELLE_SIP_OK) return error;
for(;list!=NULL;list=list->next){
belle_sip_param_pair_t* container = list->data;
if (list == belle_sip_parameters_get_parameters(uri->header_list)) {
//first case
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"?%s=%s",container->name,container->value);
error=belle_sip_snprintf(buff,buff_size,offset,"?%s=%s",container->name,container->value);
} else {
//subsequent headers
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"&%s=%s",container->name,container->value);
error=belle_sip_snprintf(buff,buff_size,offset,"&%s=%s",container->name,container->value);
}
if (current_offset>=buff_size) return buff_size-offset;
if (error!=BELLE_SIP_OK) return error;
}
return current_offset-offset;
return error;
}
BELLE_SIP_PARSE(uri);
......
......@@ -106,6 +106,23 @@ char *belle_sip_strdup_printf(const char *fmt,...){
return ret;
}
belle_sip_error_code belle_sip_snprintf(char *buff, unsigned int buff_size, unsigned int *offset, const char *fmt, ...) {
int ret;
belle_sip_error_code error = BELLE_SIP_OK;
va_list args;
va_start(args, fmt);
ret = vsnprintf(buff + *offset, buff_size - *offset, fmt, args);
if ((ret < 0)
|| (ret >= (buff_size - *offset))) {
error = BELLE_SIP_BUFFER_OVERFLOW;
*offset = buff_size;
} else {
*offset += ret;
}
va_end(args);
return error;
}
#if defined(WIN32) || defined(_WIN32_WCE)
#define ENDLINE "\r\n"
#else
......
......@@ -458,12 +458,13 @@ void channel_set_state(belle_sip_channel_t *obj, belle_sip_channel_state_t state
static void _send_message(belle_sip_channel_t *obj, belle_sip_message_t *msg){
char buffer[belle_sip_network_buffer_size];
int len;
unsigned int len=0;
int ret=0;
belle_sip_error_code error=BELLE_SIP_OK;
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(obj->listeners,belle_sip_channel_listener_t,on_sending,obj,msg);
len=belle_sip_object_marshal((belle_sip_object_t*)msg,buffer,0,sizeof(buffer));
if (len>0){
error=belle_sip_object_marshal((belle_sip_object_t*)msg,buffer,sizeof(buffer),&len);
if ((error==BELLE_SIP_OK) && (len>0)){
if (!obj->stack->send_error)
ret=belle_sip_channel_send(obj,buffer,len);
else
......
......@@ -197,8 +197,8 @@ void belle_sip_message_remove_header(belle_sip_message_t *msg, const char *heade
/*
int belle_sip_message_named_headers_marshal(belle_sip_message_t *message, const char* header_name, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset;
belle_sip_error_code belle_sip_message_named_headers_marshal(belle_sip_message_t *message, const char* header_name, char* buff, size_t buff_size, unsigned int *offset) {
belle_sip_error_code error=BELLE_SIP_OK;
belle_sip_list_t* header_list = belle_sip_message_get_headers(message,header_name);
if (!header_list) {
belle_sip_error("headers [%s] not found",header_name);
......@@ -206,10 +206,12 @@ int belle_sip_message_named_headers_marshal(belle_sip_message_t *message, const
}
for(;header_list!=NULL;header_list=header_list->next){
belle_sip_header_t *h=BELLE_SIP_HEADER(header_list->data);
current_offset+=belle_sip_object_marshal(BELLE_SIP_OBJECT(h),buff,current_offset,buff_size);
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","\r\n");
error=belle_sip_object_marshal(BELLE_SIP_OBJECT(h),buff,buff_size,offset);
if (error!=BELLE_SIP_OK) return error;
error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
if (error!=BELLE_SIP_OK) return error;
}
return current_offset-offset;
return error;
}
#define MARSHAL_AND_CHECK_HEADER(header) \
......@@ -244,25 +246,25 @@ belle_sip_list_t* belle_sip_message_get_all_headers(const belle_sip_message_t *m
return headers;
}
int belle_sip_headers_marshal(belle_sip_message_t *message, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset;
belle_sip_error_code belle_sip_headers_marshal(belle_sip_message_t *message, char* buff, size_t buff_size, unsigned int *offset) {
/*FIXME, replace this code by belle_sip_message_for_each_header*/
belle_sip_list_t* headers_list;
belle_sip_list_t* header_list;
belle_sip_error_code error=BELLE_SIP_OK;
for(headers_list=message->header_list;headers_list!=NULL;headers_list=headers_list->next){
for(header_list=((headers_container_t*)(headers_list->data))->header_list
;header_list!=NULL
;header_list=header_list->next) {
belle_sip_header_t *h=BELLE_SIP_HEADER(header_list->data);
current_offset+=belle_sip_object_marshal(BELLE_SIP_OBJECT(h),buff,current_offset,buff_size);
if (current_offset>=buff_size) return buff_size-offset;
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","\r\n");
if (current_offset>=buff_size) return buff_size-offset;
error=belle_sip_object_marshal(BELLE_SIP_OBJECT(h),buff,buff_size,offset);
if (error!=BELLE_SIP_OK) return error;
error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
if (error!=BELLE_SIP_OK) return error;
}
}
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","\r\n");
if (current_offset>=buff_size) return buff_size-offset;
return current_offset-offset;
error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
if (error!=BELLE_SIP_OK) return error;
return error;
}
struct _belle_sip_request {
......@@ -284,22 +286,20 @@ static void belle_sip_request_clone(belle_sip_request_t *request, const belle_si
if (orig->uri) request->uri=(belle_sip_uri_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)orig->uri));
}
int belle_sip_request_marshal(belle_sip_request_t* request, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset;
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s ",belle_sip_request_get_method(request));
if (current_offset>=buff_size) goto end;
current_offset+=belle_sip_uri_marshal(belle_sip_request_get_uri(request),buff,current_offset,buff_size);
if (current_offset>=buff_size) goto end;
current_offset+=snprintf(buff+current_offset,buff_size-current_offset," %s","SIP/2.0\r\n");
if (current_offset>=buff_size) goto end;
current_offset+=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(request),buff,current_offset,buff_size);
if (current_offset>=buff_size) goto end;
belle_sip_error_code belle_sip_request_marshal(belle_sip_request_t* request, char* buff, size_t buff_size, unsigned int *offset) {
belle_sip_error_code error=belle_sip_snprintf(buff,buff_size,offset,"%s ",belle_sip_request_get_method(request));
if (error!=BELLE_SIP_OK) return error;
error=belle_sip_uri_marshal(belle_sip_request_get_uri(request),buff,buff_size,offset);
if (error!=BELLE_SIP_OK) return error;
error=belle_sip_snprintf(buff,buff_size,offset," %s","SIP/2.0\r\n");
if (error!=BELLE_SIP_OK) return error;
error=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(request),buff,buff_size,offset);
if (error!=BELLE_SIP_OK) return error;
if (BELLE_SIP_MESSAGE(request)->body) {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset, "%s",BELLE_SIP_MESSAGE(request)->body);
if (current_offset>=buff_size) goto end;
error=belle_sip_snprintf(buff,buff_size,offset, "%s",BELLE_SIP_MESSAGE(request)->body);
if (error!=BELLE_SIP_OK) return error;
}
end:
return MIN(current_offset-offset,buff_size-offset);
return error;
}
BELLE_SIP_NEW(request,message)
......@@ -466,23 +466,24 @@ static void belle_sip_response_clone(belle_sip_response_t *resp, const belle_sip
if (orig->sip_version) resp->sip_version=belle_sip_strdup(orig->sip_version);
if (orig->reason_phrase) resp->reason_phrase=belle_sip_strdup(orig->reason_phrase);
}
int belle_sip_response_marshal(belle_sip_response_t *resp, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset;
current_offset+=snprintf( buff+current_offset
,buff_size-current_offset
,"SIP/2.0 %i %s\r\n"
,belle_sip_response_get_status_code(resp)
,belle_sip_response_get_reason_phrase(resp));
if (current_offset>=buff_size) goto end;
current_offset+=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(resp),buff,current_offset,buff_size);
if (current_offset>=buff_size) goto end;
belle_sip_error_code belle_sip_response_marshal(belle_sip_response_t *resp, char* buff, size_t buff_size, unsigned int *offset) {
belle_sip_error_code error=belle_sip_snprintf( buff
,buff_size
,offset
,"SIP/2.0 %i %s\r\n"
,belle_sip_response_get_status_code(resp)
,belle_sip_response_get_reason_phrase(resp));
if (error!=BELLE_SIP_OK) return error;
error=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(resp),buff,buff_size,offset);
if (error!=BELLE_SIP_OK) return error;
if (BELLE_SIP_MESSAGE(resp)->body) {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset, "%s",BELLE_SIP_MESSAGE(resp)->body);
if (current_offset>=buff_size) goto end;
error=belle_sip_snprintf(buff,buff_size,offset, "%s",BELLE_SIP_MESSAGE(resp)->body);
if (error!=BELLE_SIP_OK) return error;
}
end:
return MIN(current_offset-offset,buff_size-offset);
return error;
}
BELLE_SIP_NEW(response,message);
BELLE_SIP_PARSE(response)
GET_SET_STRING(belle_sip_response,reason_phrase);
......
......@@ -42,6 +42,7 @@ typedef long long int64_t;
typedef unsigned char uint8_t;
#define strcasecmp(a,b) _stricmp(a,b)
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strdup _strdup
#else
#include <stdint.h>
......
......@@ -174,7 +174,8 @@ static void compute_hash_from_invariants(belle_sip_message_t *msg, char *branchi
if (initial)
belle_sip_md5_append(&ctx,(uint8_t*)initial,strlen(initial));
if (requri){
belle_sip_object_marshal((belle_sip_object_t*)requri,tmp,0,sizeof(tmp)-1);
unsigned int offset=0;
belle_sip_object_marshal((belle_sip_object_t*)requri,tmp,sizeof(tmp)-1,&offset);
belle_sip_md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
}
if (from_tag)
......@@ -185,12 +186,14 @@ static void compute_hash_from_invariants(belle_sip_message_t *msg, char *branchi
belle_sip_md5_append(&ctx,(uint8_t*)&cseq,sizeof(cseq));
if (is_request){
if (prev_via){
belle_sip_object_marshal((belle_sip_object_t*)prev_via,tmp,0,sizeof(tmp)-1);
unsigned int offset=0;
belle_sip_object_marshal((belle_sip_object_t*)prev_via,tmp,sizeof(tmp)-1,&offset);
belle_sip_md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
}
}else{
if (via){
belle_sip_object_marshal((belle_sip_object_t*)via,tmp,0,sizeof(tmp)-1);
unsigned int offset=0;
belle_sip_object_marshal((belle_sip_object_t*)via,tmp,sizeof(tmp)-1,&offset);
belle_sip_md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
}
}
......
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