belle_sip_headers_impl.c 29.1 KB
Newer Older
jehan's avatar
jehan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
	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/headers.h"
jehan's avatar
jehan committed
22
#include "belle-sip/parameters.h"
jehan's avatar
jehan committed
23 24 25 26 27 28 29
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "belle_sip_messageParser.h"
#include "belle_sip_messageLexer.h"
#include "belle_sip_internal.h"

jehan's avatar
jehan committed
30 31 32
/************************
 * header
 ***********************/
jehan's avatar
jehan committed
33

jehan's avatar
jehan committed
34
GET_SET_STRING(belle_sip_header,name);
35

jehan's avatar
jehan committed
36
void belle_sip_header_init(belle_sip_header_t *header) {
Simon Morlat's avatar
Simon Morlat committed
37

jehan's avatar
jehan committed
38
}
39

Simon Morlat's avatar
Simon Morlat committed
40
static void belle_sip_header_destroy(belle_sip_header_t *header){
jehan's avatar
jehan committed
41
	if (header->name) belle_sip_free((void*)header->name);
jehan's avatar
jehan committed
42 43 44 45 46 47 48
	if (header->next) belle_sip_object_unref(BELLE_SIP_OBJECT(header->next));
}
void belle_sip_header_set_next(belle_sip_header_t* header,belle_sip_header_t* next) {
	header->next = next;
}
belle_sip_header_t* belle_sip_header_get_next(const belle_sip_header_t* header) {
	return header->next;
jehan's avatar
jehan committed
49
}
jehan's avatar
jehan committed
50

jehan's avatar
jehan committed
51 52
int belle_sip_header_marshal(belle_sip_header_t* header, char* buff,unsigned int offset,unsigned int buff_size) {
	if (header->name) {
53
		return snprintf(buff+offset,buff_size-offset,"%s: ",header->name);
jehan's avatar
jehan committed
54 55 56 57 58 59
	} else {
		belle_sip_warning("no header name found");
		return 0;
	}
}
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_header_t,belle_sip_object_t,belle_sip_header_destroy,NULL,belle_sip_header_marshal);
Simon Morlat's avatar
Simon Morlat committed
60 61


jehan's avatar
jehan committed
62 63 64 65
/************************
 * header_address
 ***********************/
struct _belle_sip_header_address {
Simon Morlat's avatar
Simon Morlat committed
66
	belle_sip_parameters_t base;
jehan's avatar
jehan committed
67 68 69
	const char* displayname;
	belle_sip_uri_t* uri;
};
Simon Morlat's avatar
Simon Morlat committed
70

jehan's avatar
jehan committed
71 72
static void belle_sip_header_address_init(belle_sip_header_address_t* object){
	belle_sip_parameters_init((belle_sip_parameters_t*)object); /*super*/
jehan's avatar
jehan committed
73 74
}

jehan's avatar
jehan committed
75 76 77
static void belle_sip_header_address_destroy(belle_sip_header_address_t* contact) {
	if (contact->displayname) belle_sip_free((void*)(contact->displayname));
	if (contact->uri) belle_sip_object_unref(BELLE_SIP_OBJECT(contact->uri));
jehan's avatar
jehan committed
78 79
}

80 81 82
static void belle_sip_header_address_clone(belle_sip_header_address_t *addr, const belle_sip_header_address_t *orig){
	addr->displayname=belle_sip_strdup(orig->displayname);
	addr->uri=(belle_sip_uri_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(orig->uri));
Simon Morlat's avatar
Simon Morlat committed
83
}
84

jehan's avatar
jehan committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
int belle_sip_header_address_marshal(belle_sip_header_address_t* header, char* buff,unsigned int offset,unsigned int buff_size) {
	/*1 display name*/
	unsigned int current_offset=offset;
	if (header->displayname) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"\"%s\" ",header->displayname);;
	}
	if (header->uri) {
		if (header->displayname || belle_sip_parameters_get_parameter_names(&header->base) !=NULL) {
			current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","<");
		}
		current_offset+=belle_sip_uri_marshal(header->uri,buff,current_offset,buff_size);
		if (header->displayname || belle_sip_parameters_get_parameter_names(&header->base) !=NULL) {
			current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s",">");
		}
	}
	current_offset+=belle_sip_parameters_marshal(&header->base,buff,current_offset,buff_size);
	return current_offset-offset;
}
Simon Morlat's avatar
Simon Morlat committed
103 104

BELLE_SIP_NEW(header_address,parameters)
jehan's avatar
jehan committed
105 106
GET_SET_STRING(belle_sip_header_address,displayname);

jehan's avatar
jehan committed
107 108
void belle_sip_header_address_set_quoted_displayname(belle_sip_header_address_t* address,const char* value) {
		if (address->displayname != NULL) belle_sip_free((void*)(address->displayname));
109
		address->displayname=_belle_sip_str_dup_and_unquote_string(value);
jehan's avatar
jehan committed
110
}
jehan's avatar
jehan committed
111 112 113 114 115
belle_sip_uri_t* belle_sip_header_address_get_uri(belle_sip_header_address_t* address) {
	return address->uri;
}

void belle_sip_header_address_set_uri(belle_sip_header_address_t* address, belle_sip_uri_t* uri) {
116
	address->uri=(belle_sip_uri_t*)belle_sip_object_ref(uri);
jehan's avatar
jehan committed
117 118 119 120 121 122 123 124 125 126 127 128
}



/************************
 * header_contact
 ***********************/
struct _belle_sip_header_contact {
	belle_sip_header_address_t address;
	unsigned int wildcard;
 };

jehan's avatar
jehan committed
129
void belle_sip_header_contact_destroy(belle_sip_header_contact_t* contact) {
Simon Morlat's avatar
Simon Morlat committed
130 131 132
}

void belle_sip_header_contact_clone(belle_sip_header_contact_t *contact, const belle_sip_header_contact_t *orig){
jehan's avatar
jehan committed
133
}
jehan's avatar
jehan committed
134 135 136 137 138 139 140 141 142 143
int belle_sip_header_contact_marshal(belle_sip_header_contact_t* contact, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(contact), buff,offset, buff_size);
	if (contact->wildcard) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","*");
	} else {
		current_offset+=belle_sip_header_address_marshal(&contact->address, buff,current_offset, buff_size);
	}
	return current_offset-offset;
}
jehan's avatar
jehan committed
144
BELLE_SIP_NEW_HEADER(header_contact,header_address,"Contact")
jehan's avatar
jehan committed
145
BELLE_SIP_PARSE(header_contact)
jehan's avatar
jehan committed
146

jehan's avatar
jehan committed
147 148
GET_SET_INT_PARAM_PRIVATE(belle_sip_header_contact,expires,int,_)
GET_SET_INT_PARAM_PRIVATE(belle_sip_header_contact,q,float,_);
jehan's avatar
jehan committed
149 150
GET_SET_BOOL(belle_sip_header_contact,wildcard,is);

jehan's avatar
jehan committed
151

jehan's avatar
jehan committed
152 153
int belle_sip_header_contact_set_expires(belle_sip_header_contact_t* contact, int expires) {
	if (expires < 0 ) {
154
		 belle_sip_error("bad expires value [%i] for contact",expires);
jehan's avatar
jehan committed
155 156 157 158 159 160
		return -1;
	}
	_belle_sip_header_contact_set_expires(contact,expires);
	return 0;
 }
int belle_sip_header_contact_set_qvalue(belle_sip_header_contact_t* contact, float qValue) {
jehan's avatar
jehan committed
161
	 if (qValue != -1 && qValue < 0 && qValue >1) {
162
		 belle_sip_error("bad q value [%f] for contact",qValue);
jehan's avatar
jehan committed
163 164
		 return -1;
	 }
jehan's avatar
jehan committed
165
	 _belle_sip_header_contact_set_q(contact,qValue);
jehan's avatar
jehan committed
166 167
	 return 0;
}
168
float	belle_sip_header_contact_get_qvalue(const belle_sip_header_contact_t* contact) {
jehan's avatar
jehan committed
169 170 171
	return belle_sip_header_contact_get_q(contact);
}
/**************************
jehan's avatar
jehan committed
172
* From header object inherent from header_address
jehan's avatar
jehan committed
173
****************************
jehan's avatar
jehan committed
174
*/
jehan's avatar
jehan committed
175 176 177 178 179
#define BELLE_SIP_FROM_LIKE_MARSHAL(header) \
		unsigned int current_offset=offset; \
		current_offset+=belle_sip_##header_marshal(BELLE_SIP_HEADER(header), buff,current_offset, buff_size);\
		current_offset+=belle_sip_header_address_marshal(&header->address, buff,current_offset, buff_size); \
		return current_offset-offset;
180

jehan's avatar
jehan committed
181 182 183 184
struct _belle_sip_header_from  {
	belle_sip_header_address_t address;
};

jehan's avatar
jehan committed
185 186 187
static void belle_sip_header_from_destroy(belle_sip_header_from_t* from) {
}

Simon Morlat's avatar
Simon Morlat committed
188 189
static void belle_sip_header_from_clone(belle_sip_header_from_t* from, const belle_sip_header_from_t* cloned) {
}
jehan's avatar
jehan committed
190 191 192
int belle_sip_header_from_marshal(belle_sip_header_from_t* from, char* buff,unsigned int offset,unsigned int buff_size) {
	BELLE_SIP_FROM_LIKE_MARSHAL(from);
}
Simon Morlat's avatar
Simon Morlat committed
193

194 195 196 197 198 199 200 201
belle_sip_header_from_t* belle_sip_header_from_create(const char *address, const char *tag){
	char *tmp=belle_sip_strdup_printf("From: %s",address);
	belle_sip_header_from_t *from=belle_sip_header_from_parse(tmp);
	if (tag) belle_sip_header_from_set_tag(from,tag);
	belle_sip_free(tmp);
	return from;
}

jehan's avatar
jehan committed
202
BELLE_SIP_NEW_HEADER(header_from,header_address,"From")
jehan's avatar
jehan committed
203
BELLE_SIP_PARSE(header_from)
jehan's avatar
jehan committed
204 205 206
GET_SET_STRING_PARAM(belle_sip_header_from,tag);

/**************************
Simon Morlat's avatar
Simon Morlat committed
207
* To header object inherits from header_address
jehan's avatar
jehan committed
208 209 210 211 212
****************************
*/
struct _belle_sip_header_to  {
	belle_sip_header_address_t address;
};
jehan's avatar
jehan committed
213

jehan's avatar
jehan committed
214
static void belle_sip_header_to_destroy(belle_sip_header_to_t* to) {
Simon Morlat's avatar
Simon Morlat committed
215 216 217
}

void belle_sip_header_to_clone(belle_sip_header_to_t *contact, const belle_sip_header_to_t *orig){
jehan's avatar
jehan committed
218
}
jehan's avatar
jehan committed
219 220 221
int belle_sip_header_to_marshal(belle_sip_header_to_t* to, char* buff,unsigned int offset,unsigned int buff_size) {
	BELLE_SIP_FROM_LIKE_MARSHAL(to)
}
jehan's avatar
jehan committed
222

jehan's avatar
jehan committed
223
BELLE_SIP_NEW_HEADER(header_to,header_address,"To")
jehan's avatar
jehan committed
224 225
BELLE_SIP_PARSE(header_to)
GET_SET_STRING_PARAM(belle_sip_header_to,tag);
226

227 228 229 230 231 232 233 234
belle_sip_header_to_t* belle_sip_header_to_create(const char *address, const char *tag){
	char *tmp=belle_sip_strdup_printf("To: %s",address);
	belle_sip_header_to_t *to=belle_sip_header_to_parse(tmp);
	if (tag) belle_sip_header_to_set_tag(to,tag);
	belle_sip_free(tmp);
	return to;
}

jehan's avatar
jehan committed
235
/**************************
Simon Morlat's avatar
Simon Morlat committed
236
* Via header object inherits from parameters
jehan's avatar
jehan committed
237 238 239
****************************
*/
struct _belle_sip_header_via  {
240
	belle_sip_parameters_t params_list;
Simon Morlat's avatar
Simon Morlat committed
241 242 243
	char* protocol;
	char* transport;
	char* host;
244
	int port;
jehan's avatar
jehan committed
245 246
};

247
static void belle_sip_header_via_destroy(belle_sip_header_via_t* via) {
Simon Morlat's avatar
Simon Morlat committed
248 249 250 251 252
	if (via->host) belle_sip_free(via->host);
	if (via->protocol) belle_sip_free(via->protocol);
}

static void belle_sip_header_via_clone(belle_sip_header_via_t* via, const belle_sip_header_via_t*orig){
jehan's avatar
jehan committed
253
}
254

jehan's avatar
jehan committed
255 256 257 258 259 260 261 262 263 264 265
int belle_sip_header_via_marshal(belle_sip_header_via_t* via, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(via), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s/%s",via->protocol,via->transport);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset," %s",via->host);
	if (via->port > 0) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,":%i",via->port);
	}
	current_offset+=belle_sip_parameters_marshal(&via->params_list, buff,current_offset, buff_size);
	return current_offset-offset;
}
jehan's avatar
jehan committed
266

267 268 269 270 271 272 273 274 275 276
belle_sip_header_via_t* belle_sip_header_via_create(const char *host, int port, const char *transport, const char *branch){
	belle_sip_header_via_t *via=belle_sip_header_via_new();
	via->host=belle_sip_strdup(host);
	via->port=port;
	via->transport=belle_sip_strdup(transport);
	via->protocol=belle_sip_strdup("SIP/2.0");
	belle_sip_header_via_set_branch(via,branch);
	return via;
}

jehan's avatar
jehan committed
277
BELLE_SIP_NEW_HEADER(header_via,header_address,"Via")
jehan's avatar
jehan committed
278
BELLE_SIP_PARSE(header_via)
279 280 281 282 283 284 285 286 287 288 289
GET_SET_STRING(belle_sip_header_via,protocol);
GET_SET_STRING(belle_sip_header_via,transport);
GET_SET_STRING(belle_sip_header_via,host);
GET_SET_INT_PRIVATE(belle_sip_header_via,port,int,_);

GET_SET_STRING_PARAM(belle_sip_header_via,branch);
GET_SET_STRING_PARAM(belle_sip_header_via,maddr);
GET_SET_STRING_PARAM(belle_sip_header_via,received);

GET_SET_INT_PARAM_PRIVATE(belle_sip_header_via,rport,int,_)
GET_SET_INT_PARAM_PRIVATE(belle_sip_header_via,ttl,int,_)
Simon Morlat's avatar
Simon Morlat committed
290

291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
int belle_sip_header_via_set_rport (belle_sip_header_via_t* obj,int  value) {
	if (value ==-1 || (value>0 && value<65536)) {
		_belle_sip_header_via_set_rport(obj,value);
		return 0;
	} else {
		belle_sip_error("bad rport value [%i] for via",value);
		return -1;
	}
}
int belle_sip_header_via_set_ttl (belle_sip_header_via_t* obj,int  value) {
	if (value ==-1 || (value>0 && value<=255)) {
		_belle_sip_header_via_set_ttl(obj,value);
		return 0;
	} else {
		belle_sip_error("bad ttl value [%i] for via",value);
		return -1;
	}
}
309

310 311 312 313 314 315 316 317 318
int belle_sip_header_via_set_port (belle_sip_header_via_t* obj,int  value) {
	if (value ==-1 || (value>0 && value<65536)) {
		_belle_sip_header_via_set_port(obj,value);
		return 0;
	} else {
		belle_sip_error("bad port value [%i] for via",value);
		return -1;
	}
}
Simon Morlat's avatar
Simon Morlat committed
319

320
int belle_sip_header_via_get_listening_port(const belle_sip_header_via_t *via){
Simon Morlat's avatar
Simon Morlat committed
321 322 323 324 325
	int ret=belle_sip_header_via_get_port(via);
	if (ret==-1) ret=belle_sip_listening_point_get_well_known_port(via->protocol);
	return ret;
}

326
/**************************
Simon Morlat's avatar
Simon Morlat committed
327
* call_id header object inherits from object
328 329
****************************
*/
jehan's avatar
jehan committed
330
struct _belle_sip_header_call_id  {
jehan's avatar
jehan committed
331
	belle_sip_header_t header;
jehan's avatar
jehan committed
332
	const char* call_id;
333
};
jehan's avatar
jehan committed
334

jehan's avatar
jehan committed
335 336
static void belle_sip_header_call_id_destroy(belle_sip_header_call_id_t* call_id) {
	if (call_id->call_id) belle_sip_free((void*)call_id->call_id);
Simon Morlat's avatar
Simon Morlat committed
337
}
jehan's avatar
jehan committed
338

Simon Morlat's avatar
Simon Morlat committed
339
static void belle_sip_header_call_id_clone(belle_sip_header_call_id_t* call_id,const belle_sip_header_call_id_t *orig){
340
}
jehan's avatar
jehan committed
341 342 343 344 345 346
int belle_sip_header_call_id_marshal(belle_sip_header_call_id_t* call_id, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(call_id), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s",call_id->call_id);
	return current_offset-offset;
}
347

jehan's avatar
jehan committed
348
BELLE_SIP_NEW_HEADER(header_call_id,header,"Call-ID")
jehan's avatar
jehan committed
349 350
BELLE_SIP_PARSE(header_call_id)
GET_SET_STRING(belle_sip_header_call_id,call_id);
351 352 353 354 355
/**************************
* cseq header object inherent from object
****************************
*/
struct _belle_sip_header_cseq  {
jehan's avatar
jehan committed
356
	belle_sip_header_t header;
357
	char* method;
358 359
	unsigned int seq_number;
};
jehan's avatar
jehan committed
360

361
static void belle_sip_header_cseq_destroy(belle_sip_header_cseq_t* cseq) {
362
	if (cseq->method) belle_sip_free(cseq->method);
Simon Morlat's avatar
Simon Morlat committed
363
}
364

Simon Morlat's avatar
Simon Morlat committed
365
static void belle_sip_header_cseq_clone(belle_sip_header_cseq_t* cseq, const belle_sip_header_cseq_t *orig) {
366 367
	if (cseq->method) belle_sip_free(cseq->method);
	cseq->method=belle_sip_strdup(orig->method);
368
}
jehan's avatar
jehan committed
369 370 371 372 373 374
int belle_sip_header_cseq_marshal(belle_sip_header_cseq_t* cseq, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(cseq), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%i %s",cseq->seq_number,cseq->method);
	return current_offset-offset;
}
375 376 377 378 379 380
belle_sip_header_cseq_t * belle_sip_header_cseq_create(unsigned int number, const char *method){
	belle_sip_header_cseq_t *cseq=belle_sip_header_cseq_new();
	cseq->method=belle_sip_strdup(method);
	cseq->seq_number=number;
	return cseq;
}
jehan's avatar
jehan committed
381
BELLE_SIP_NEW_HEADER(header_cseq,header,"CSeq")
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
BELLE_SIP_PARSE(header_cseq)
GET_SET_STRING(belle_sip_header_cseq,method);
GET_SET_INT(belle_sip_header_cseq,seq_number,unsigned int)
/**************************
* content type header object inherent from parameters
****************************
*/
struct _belle_sip_header_content_type  {
	belle_sip_parameters_t params_list;
	const char* type;
	const char* subtype;
};

static void belle_sip_header_content_type_destroy(belle_sip_header_content_type_t* content_type) {
	if (content_type->type) belle_sip_free((void*)content_type->type);
	if (content_type->subtype) belle_sip_free((void*)content_type->subtype);
}
jehan's avatar
jehan committed
399

Simon Morlat's avatar
Simon Morlat committed
400 401
static void belle_sip_header_content_type_clone(belle_sip_header_content_type_t* content_type, const belle_sip_header_content_type_t* orig){
}
jehan's avatar
jehan committed
402 403 404 405 406 407 408
int belle_sip_header_content_type_marshal(belle_sip_header_content_type_t* content_type, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(content_type), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s/%s",content_type->type, content_type->subtype);
	current_offset+=belle_sip_parameters_marshal(&content_type->params_list, buff,current_offset, buff_size);
	return current_offset-offset;
}
jehan's avatar
jehan committed
409
BELLE_SIP_NEW_HEADER(header_content_type,parameters,"Content-Type")
410 411 412
BELLE_SIP_PARSE(header_content_type)
GET_SET_STRING(belle_sip_header_content_type,type);
GET_SET_STRING(belle_sip_header_content_type,subtype);
jehan's avatar
jehan committed
413 414 415 416 417 418 419 420 421
/**************************
* Route header object inherent from header_address
****************************
*/
struct _belle_sip_header_route  {
	belle_sip_header_address_t address;
};

static void belle_sip_header_route_destroy(belle_sip_header_route_t* route) {
Simon Morlat's avatar
Simon Morlat committed
422 423 424
}

static void belle_sip_header_route_clone(belle_sip_header_route_t* route, const belle_sip_header_route_t* orig) {
jehan's avatar
jehan committed
425
}
jehan's avatar
jehan committed
426 427 428
int belle_sip_header_route_marshal(belle_sip_header_route_t* route, char* buff,unsigned int offset,unsigned int buff_size) {
	BELLE_SIP_FROM_LIKE_MARSHAL(route)
}
jehan's avatar
jehan committed
429
BELLE_SIP_NEW_HEADER(header_route,header_address,"Route")
jehan's avatar
jehan committed
430 431 432 433 434 435 436 437 438 439
BELLE_SIP_PARSE(header_route)
/**************************
* Record route header object inherent from header_address
****************************
*/
struct _belle_sip_header_record_route  {
	belle_sip_header_address_t address;
};

static void belle_sip_header_record_route_destroy(belle_sip_header_record_route_t* record_route) {
Simon Morlat's avatar
Simon Morlat committed
440 441 442 443
}

static void belle_sip_header_record_route_clone(belle_sip_header_record_route_t* record_route,
                                const belle_sip_header_record_route_t* orig               ) {
jehan's avatar
jehan committed
444
}
jehan's avatar
jehan committed
445 446 447
int belle_sip_header_record_route_marshal(belle_sip_header_record_route_t* record_route, char* buff,unsigned int offset,unsigned int buff_size) {
	BELLE_SIP_FROM_LIKE_MARSHAL(record_route)
}
jehan's avatar
jehan committed
448
BELLE_SIP_NEW_HEADER(header_record_route,header_address,"Record-Route")
jehan's avatar
jehan committed
449
BELLE_SIP_PARSE(header_record_route)
jehan's avatar
jehan committed
450 451 452 453 454
/**************************
* content length header object inherent from object
****************************
*/
struct _belle_sip_header_content_length  {
jehan's avatar
jehan committed
455
	belle_sip_header_t header;
jehan's avatar
jehan committed
456 457 458 459
	unsigned int content_length;
};

static void belle_sip_header_content_length_destroy(belle_sip_header_content_length_t* content_length) {
Simon Morlat's avatar
Simon Morlat committed
460
}
jehan's avatar
jehan committed
461

Simon Morlat's avatar
Simon Morlat committed
462 463
static void belle_sip_header_content_length_clone(belle_sip_header_content_length_t* content_length,
                                                 const belle_sip_header_content_length_t *orig ) {
jehan's avatar
jehan committed
464
}
Simon Morlat's avatar
Simon Morlat committed
465

jehan's avatar
jehan committed
466 467 468 469 470 471
int belle_sip_header_content_length_marshal(belle_sip_header_content_length_t* content_length, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(content_length), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%i",content_length->content_length);
	return current_offset-offset;
}
jehan's avatar
jehan committed
472
BELLE_SIP_NEW_HEADER(header_content_length,header,"Content-Length")
jehan's avatar
jehan committed
473 474
BELLE_SIP_PARSE(header_content_length)
GET_SET_INT(belle_sip_header_content_length,content_length,unsigned int)
jehan's avatar
jehan committed
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
/******************************
 * Extension header hinerite from header
 *
 ******************************/
struct _belle_sip_header_extension  {
	belle_sip_header_t header;
	const char* value;
};

static void belle_sip_header_extension_destroy(belle_sip_header_extension_t* extension) {
	if (extension->value) belle_sip_free((void*)extension->value);
}

static void belle_sip_header_extension_clone(belle_sip_header_extension_t* extension, const belle_sip_header_extension_t* orig){
}
jehan's avatar
jehan committed
490 491 492 493 494
int belle_sip_header_extension_marshal(belle_sip_header_extension_t* extension, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(extension), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s",extension->value);
	return current_offset-offset;
jehan's avatar
jehan committed
495

jehan's avatar
jehan committed
496
}
jehan's avatar
jehan committed
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
BELLE_SIP_NEW_HEADER(header_extension,header,NULL)

/**
 * special case for this header. I don't know why
 */
belle_sip_header_extension_t* belle_sip_header_extension_parse (const char* value) {
	pANTLR3_INPUT_STREAM           input;
	pbelle_sip_messageLexer               lex;
	pANTLR3_COMMON_TOKEN_STREAM    tokens;
	pbelle_sip_messageParser              parser;
	input  = antlr3NewAsciiStringCopyStream	(
			(pANTLR3_UINT8)value,
			(ANTLR3_UINT32)strlen(value),
			((void *)0));
	lex    = belle_sip_messageLexerNew                (input);
	tokens = antlr3CommonTokenStreamSourceNew  (1025, lex->pLexer->rec->state->tokSource);
	parser = belle_sip_messageParserNew               (tokens);
	belle_sip_messageParser_header_extension_return l_parsed_object = parser->header_extension(parser,FALSE);
	parser ->free(parser);
	tokens ->free(tokens);
	lex    ->free(lex);
	input  ->close(input);
	if (l_parsed_object.ret == NULL) belle_sip_error("Parser error for [%s]",value);\
	return BELLE_SIP_HEADER_EXTENSION(l_parsed_object.ret);
}
GET_SET_STRING(belle_sip_header_extension,value);
523
/**************************
524
*Authorization header object inherent from parameters
525 526
****************************
*/
jehan's avatar
jehan committed
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
#define AUTH_BASE \
	belle_sip_parameters_t params_list; \
	const char* scheme; \
	const char* realm; \
	const char* nonce; \
	const char* algorithm; \
	const char* opaque; \
	const char* qop; \

#define AUTH_BASE_DESTROY(obj) \
	if (obj->scheme) belle_sip_free((void*)obj->scheme);\
	if (obj->realm) belle_sip_free((void*)obj->realm);\
	if (obj->nonce) belle_sip_free((void*)obj->nonce);\
	if (obj->algorithm) belle_sip_free((void*)obj->algorithm);\
	if (obj->opaque) belle_sip_free((void*)obj->opaque);\
	if (obj->qop) belle_sip_free((void*)obj->qop);\
jehan's avatar
jehan committed
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
	/*if (obj->params_list) FIXME free list*/


#define AUTH_BASE_MARSHAL(header) \
	unsigned int current_offset=offset;\
	char* border=" ";\
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(header), buff,current_offset, buff_size);\
	const belle_sip_list_t* list=belle_sip_parameters_get_parameters(&header->params_list);\
	if (header->scheme) { \
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset," %s",header->scheme);\
		} else { \
			belle_sip_error("missing mandatory scheme"); \
		} \
	for(;list!=NULL;list=list->next){\
		belle_sip_param_pair_t* container = list->data;\
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s%s=%s",border, container->name,container->value);\
		border=", ";\
	}\
	if (header->realm) {\
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%srealm=\"%s\"",border,header->realm);\
		border=", ";\
		}\
	if (header->nonce) {\
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%snonce=\"%s\"",border,header->nonce);\
		border=", ";\
		}\
	if (header->algorithm) {\
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%salgorithm=%s",border,header->algorithm);\
		border=", ";\
		}\
	if (header->opaque) {\
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%sopaque=\"%s\"",border,header->opaque);\
		border=", ";\
		}



jehan's avatar
jehan committed
580

jehan's avatar
jehan committed
581
	struct _belle_sip_header_authorization  {
jehan's avatar
jehan committed
582
	AUTH_BASE
583
	const char* username;
jehan's avatar
jehan committed
584
	belle_sip_uri_t* uri;
jehan's avatar
jehan committed
585
	const char* response;
586 587
	const char* cnonce;
	int nonce_count;
588 589 590 591 592 593

};


static void belle_sip_header_authorization_destroy(belle_sip_header_authorization_t* authorization) {
	if (authorization->username) belle_sip_free((void*)authorization->username);
jehan's avatar
jehan committed
594 595 596
	if (authorization->uri) {
			belle_sip_object_unref(BELLE_SIP_OBJECT(authorization->uri));
	}
597
	if (authorization->cnonce) belle_sip_free((void*)authorization->cnonce);
jehan's avatar
jehan committed
598
	AUTH_BASE_DESTROY(authorization)
599 600 601 602 603
}

static void belle_sip_header_authorization_clone(belle_sip_header_authorization_t* authorization,
                                                 const belle_sip_header_authorization_t *orig ) {
}
604 605
static void belle_sip_header_authorization_init(belle_sip_header_authorization_t* authorization) {
}
606

jehan's avatar
jehan committed
607 608 609
belle_sip_uri_t* belle_sip_header_authorization_get_uri(const belle_sip_header_authorization_t* authorization) {
	return authorization->uri;
}
610

jehan's avatar
jehan committed
611 612 613 614 615 616 617
void belle_sip_header_authorization_set_uri(belle_sip_header_authorization_t* authorization, belle_sip_uri_t* uri) {
	if (authorization->uri) {
		belle_sip_object_unref(BELLE_SIP_OBJECT(authorization->uri));
	}
	authorization->uri=uri;
	if (authorization->uri) belle_sip_object_ref(authorization->uri);
}
jehan's avatar
jehan committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
int belle_sip_header_authorization_marshal(belle_sip_header_authorization_t* authorization, char* buff,unsigned int offset,unsigned int buff_size) {
	AUTH_BASE_MARSHAL(authorization)
	if (authorization->username) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%susername=\"%s\"",border,authorization->username);\
		border=", ";
		}
	if (authorization->uri) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s uri=\"",border);
		border=", ";
		current_offset+=belle_sip_uri_marshal(authorization->uri,buff,current_offset,buff_size);
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","\"");
		}
	if (authorization->algorithm) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%salgorithm=%s",border,authorization->algorithm);
		border=", ";
		}
	if (authorization->response) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%sresponse=\"%s\"",border,authorization->response);
		border=", ";
		}
	if (authorization->cnonce) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%scnonce=\"%s\"",border,authorization->cnonce);
		border=", ";
		}
	if (authorization->nonce_count>0) {
jehan's avatar
jehan committed
643 644 645 646 647 648
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%snc=%08i",border,authorization->nonce_count);
		border=", ";
	}
	if (authorization->qop) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%sqop=%s",border,authorization->qop);
	}
jehan's avatar
jehan committed
649 650
	return current_offset-offset;
}
651
BELLE_SIP_NEW_HEADER(header_authorization,parameters,"Authorization")
652
BELLE_SIP_PARSE(header_authorization)
jehan's avatar
jehan committed
653
GET_SET_STRING(belle_sip_header_authorization,scheme);
654
GET_SET_STRING(belle_sip_header_authorization,username);
jehan's avatar
jehan committed
655 656
GET_SET_STRING(belle_sip_header_authorization,realm);
GET_SET_STRING(belle_sip_header_authorization,nonce);
jehan's avatar
jehan committed
657
GET_SET_STRING(belle_sip_header_authorization,response);
jehan's avatar
jehan committed
658
GET_SET_STRING(belle_sip_header_authorization,algorithm);
659 660
GET_SET_STRING(belle_sip_header_authorization,cnonce);
GET_SET_STRING(belle_sip_header_authorization,opaque);
jehan's avatar
jehan committed
661
GET_SET_STRING(belle_sip_header_authorization,qop);
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
GET_SET_INT(belle_sip_header_authorization,nonce_count,int)

/**************************
*Proxy-Authorization header object inherent from parameters
****************************
*/
struct _belle_sip_header_proxy_authorization  {
	belle_sip_header_authorization_t authorization;
};


static void belle_sip_header_proxy_authorization_destroy(belle_sip_header_proxy_authorization_t* proxy_authorization) {
}

static void belle_sip_header_proxy_authorization_clone(belle_sip_header_proxy_authorization_t* proxy_authorization,
                                                 const belle_sip_header_proxy_authorization_t *orig ) {
}
jehan's avatar
jehan committed
679 680 681
int belle_sip_header_proxy_authorization_marshal(belle_sip_header_proxy_authorization_t* proxy_authorization, char* buff,unsigned int offset,unsigned int buff_size) {
	return belle_sip_header_authorization_marshal(&proxy_authorization->authorization,buff,offset,buff_size);
}
682 683
BELLE_SIP_NEW_HEADER(header_proxy_authorization,header_authorization,"Proxy-Authorization")
BELLE_SIP_PARSE(header_proxy_authorization)
jehan's avatar
jehan committed
684 685 686 687 688 689 690 691 692 693 694 695
/**************************
*WWW-Authorization header object inherent from parameters
****************************
*/
struct _belle_sip_header_www_authenticate  {
	AUTH_BASE
	const char* domain;
	unsigned int stale;
};


static void belle_sip_header_www_authenticate_destroy(belle_sip_header_www_authenticate_t* www_authenticate) {
jehan's avatar
jehan committed
696 697 698 699
	if (www_authenticate->domain) belle_sip_free((void*)www_authenticate->domain);
}
void belle_sip_header_www_authenticate_init(belle_sip_header_www_authenticate_t* www_authenticate) {
	www_authenticate->stale=-1;
jehan's avatar
jehan committed
700 701 702 703
}
static void belle_sip_header_www_authenticate_clone(belle_sip_header_www_authenticate_t* www_authenticate,
                                                 const belle_sip_header_www_authenticate_t *orig ) {
}
jehan's avatar
jehan committed
704 705 706 707 708 709 710
int belle_sip_header_www_authenticate_marshal(belle_sip_header_www_authenticate_t* www_authenticate, char* buff,unsigned int offset,unsigned int buff_size) {
	AUTH_BASE_MARSHAL(www_authenticate)
	if (www_authenticate->domain) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%sdomain=\"%s\"",border,www_authenticate->domain);\
		border=", ";
		}
	if (www_authenticate->stale>=0) {
jehan's avatar
jehan committed
711
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%sstale=%s",border,www_authenticate->stale?"true":"false");
jehan's avatar
jehan committed
712
		}
jehan's avatar
jehan committed
713 714 715 716
	if (www_authenticate->qop) {
		current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%sqop=\"%s\"",border,www_authenticate->qop);
		border=", ";
	}
jehan's avatar
jehan committed
717 718 719
	return current_offset-offset;
}
BELLE_SIP_NEW_HEADER_INIT(header_www_authenticate,parameters,"WWW-Authenticate",header_www_authenticate)
jehan's avatar
jehan committed
720 721 722 723 724 725 726 727 728
BELLE_SIP_PARSE(header_www_authenticate)
GET_SET_STRING(belle_sip_header_www_authenticate,scheme);
GET_SET_STRING(belle_sip_header_www_authenticate,realm);
GET_SET_STRING(belle_sip_header_www_authenticate,nonce);
GET_SET_STRING(belle_sip_header_www_authenticate,algorithm);
GET_SET_STRING(belle_sip_header_www_authenticate,opaque);
GET_SET_STRING(belle_sip_header_www_authenticate,qop);
GET_SET_STRING(belle_sip_header_www_authenticate,domain)
GET_SET_BOOL(belle_sip_header_www_authenticate,stale,is)
jehan's avatar
jehan committed
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
/**************************
* max forwards header object inherent from header
****************************
*/
struct _belle_sip_header_max_forwards  {
	belle_sip_header_t header;
	int max_forwards;
};

static void belle_sip_header_max_forwards_destroy(belle_sip_header_max_forwards_t* max_forwards) {
}

static void belle_sip_header_max_forwards_clone(belle_sip_header_max_forwards_t* max_forwards,
                                                 const belle_sip_header_max_forwards_t *orig ) {
}

int belle_sip_header_max_forwards_marshal(belle_sip_header_max_forwards_t* max_forwards, char* buff,unsigned int offset,unsigned int buff_size) {
	unsigned int current_offset=offset;
	current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(max_forwards), buff,current_offset, buff_size);
	current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%i",max_forwards->max_forwards);
	return current_offset-offset;
}
BELLE_SIP_NEW_HEADER(header_max_forwards,header,"Max-Forwards")
BELLE_SIP_PARSE(header_max_forwards)
GET_SET_INT(belle_sip_header_max_forwards,max_forwards,int)
int belle_sip_header_max_forwards_decrement_max_forwards(belle_sip_header_max_forwards_t* max_forwards) {
	return max_forwards->max_forwards--;
}