belle_sip_internal.h 30.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
/*
	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/>.
*/
jehan's avatar
jehan committed
18 19
#ifndef belle_utils_h
#define belle_utils_h
20 21 22

#include <stdlib.h>
#include <string.h>
Simon Morlat's avatar
Simon Morlat committed
23

24
#include <stdio.h>
25 26
#include <stdint.h>
#include <errno.h>
Simon Morlat's avatar
Simon Morlat committed
27
#include <unistd.h>
28

29 30 31 32 33 34
#ifndef WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif

Simon Morlat's avatar
Simon Morlat committed
35
/* include all public headers*/
Simon Morlat's avatar
Simon Morlat committed
36
#include "belle-sip/belle-sip.h"
jehan's avatar
jehan committed
37

jehan's avatar
jehan committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
#ifdef PACKAGE
#undef PACKAGE
#endif
#ifdef PACKAGE_BUGREPORT
#undef PACKAGE_BUGREPORT
#endif
#ifdef PACKAGE_NAME
#undef PACKAGE_NAME
#endif
#ifdef PACKAGE_STRING
#undef PACKAGE_STRING
#endif
#ifdef PACKAGE_TARNAME
#undef PACKAGE_TARNAME
#endif
#ifdef PACKAGE_VERSION
#undef PACKAGE_VERSION
#endif
#ifdef VERSION
#undef VERSION
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

jehan's avatar
jehan committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#if defined(WIN32) || defined(WIN32_WCE)

static inline void close_socket(belle_sip_fd_t s){
	closesocket(s);
}

static inline int get_socket_error(void){
	return WSAGetLastError();
}

const char *getSocketErrorString();
#define belle_sip_get_socket_error_string() getSocketErrorString()
#define belle_sip_get_socket_error_string_from_code(code) getSocketErrorString()
#define usleep(us) Sleep((us)/1000)
static inline int inet_aton(const char *ip, struct in_addr *p){
	*(long*)p=inet_addr(ip);
	return 0;
}

#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS

#else


static inline void close_socket(belle_sip_fd_t s){
	close(s);
}

static inline int get_socket_error(void){
	return errno;
}
#define belle_sip_get_socket_error_string() strerror(errno)
#define belle_sip_get_socket_error_string_from_code(code) strerror(code)

#endif
100 101 102 103
/*etc*/

#define BELLE_SIP_INTERFACE_GET_METHODS(obj,interface) \
	((BELLE_SIP_INTERFACE_METHODS_TYPE(interface)*)belle_sip_object_get_interface_methods((belle_sip_object_t*)obj,BELLE_SIP_INTERFACE_ID(interface)))
Simon Morlat's avatar
Simon Morlat committed
104

Simon Morlat's avatar
Simon Morlat committed
105
#define __BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method) \
106 107 108 109
	if (list!=NULL) {\
		const belle_sip_list_t *__elem=list;\
		do{\
			interface_name *__obj=(interface_name*)__elem->data;\
Simon Morlat's avatar
Simon Morlat committed
110 111
			void *__method=BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->method;\
			if (__method) BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->
112 113 114 115 116 117 118

#define __BELLE_SIP_INVOKE_LISTENER_END \
			__elem=__elem->next;\
		}while(__elem!=NULL);\
	}

#define BELLE_SIP_INVOKE_LISTENERS_VOID(list,interface_name,method) \
Simon Morlat's avatar
Simon Morlat committed
119
			__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
120 121 122 123
			method(__obj);\
			__BELLE_SIP_INVOKE_LISTENER_END

#define BELLE_SIP_INVOKE_LISTENERS_ARG(list,interface_name,method,arg) \
Simon Morlat's avatar
Simon Morlat committed
124
	__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
125 126 127 128 129
	method(__obj,arg);\
	__BELLE_SIP_INVOKE_LISTENER_END


#define BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(list,interface_name,method,arg1,arg2) \
Simon Morlat's avatar
Simon Morlat committed
130
			__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
131 132 133 134 135 136 137 138 139 140 141 142 143 144
			method(__obj,arg1,arg2);\
			__BELLE_SIP_INVOKE_LISTENER_END

#define BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2_ARG3(list,interface_name,method,arg1,arg2,arg3) \
			__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name)\
			method(__obj,arg1,arg2,arg3);\
			__BELLE_SIP_INVOKE_LISTENER_END

typedef struct weak_ref{
	struct weak_ref *next;
	belle_sip_object_destroy_notify_t notify;
	void *userpointer;
}weak_ref_t;

Simon Morlat's avatar
Simon Morlat committed
145

146
void *belle_sip_object_get_interface_methods(belle_sip_object_t *obj, belle_sip_interface_id_t ifid);
147
void belle_sip_object_delete_unowned(void);
Simon Morlat's avatar
Simon Morlat committed
148

149

150
#define BELLE_SIP_OBJECT_VPTR(obj,object_type) ((BELLE_SIP_OBJECT_VPTR_TYPE(object_type)*)(((belle_sip_object_t*)obj)->vptr))
Simon Morlat's avatar
Simon Morlat committed
151 152 153 154 155
#define belle_sip_object_init(obj)		/*nothing*/


/*list of all vptrs (classes) used in belle-sip*/
BELLE_SIP_DECLARE_VPTR(belle_sip_object_t);
156 157 158 159 160 161 162 163 164 165 166 167
BELLE_SIP_DECLARE_VPTR(belle_sip_stack_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_datagram_listening_point_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_provider_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_main_loop_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_source_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_resolver_context_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_dialog_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_address_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_contact_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_from_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_to_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_via_t);
Simon Morlat's avatar
Simon Morlat committed
168
BELLE_SIP_DECLARE_VPTR(belle_sip_uri_t);
169 170 171
BELLE_SIP_DECLARE_VPTR(belle_sip_message_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_request_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_response_t);
Simon Morlat's avatar
Simon Morlat committed
172
BELLE_SIP_DECLARE_VPTR(belle_sip_parameters_t);
173 174 175 176 177 178 179 180 181 182 183
BELLE_SIP_DECLARE_VPTR(belle_sip_header_call_id_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_cseq_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_content_type_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_route_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_record_route_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_user_agent_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_content_length_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_extension_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_authorization_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_www_authenticate_t);
jehan's avatar
jehan committed
184
BELLE_SIP_DECLARE_VPTR(belle_sip_header_proxy_authenticate_t);
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
BELLE_SIP_DECLARE_VPTR(belle_sip_header_proxy_authorization_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_max_forwards_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_expires_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_allow_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_attribute_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_bandwidth_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_connection_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_email_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_info_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_key_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_media_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_media_description_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_origin_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_phone_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_repeate_time_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_session_description_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_session_name_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_time_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_time_description_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_uri_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_version_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_base_description_t);
207
BELLE_SIP_DECLARE_VPTR(belle_sdp_mime_parameter_t);
jehan's avatar
jehan committed
208
BELLE_SIP_DECLARE_VPTR(belle_sip_refresher_t);
jehan's avatar
jehan committed
209
BELLE_SIP_DECLARE_VPTR(belle_sip_header_subscription_state_t);
jehan's avatar
jehan committed
210

Simon Morlat's avatar
Simon Morlat committed
211
typedef void (*belle_sip_source_remove_callback_t)(belle_sip_source_t *);
jehan's avatar
jehan committed
212

jehan's avatar
jehan committed
213 214 215



Simon Morlat's avatar
Simon Morlat committed
216
struct belle_sip_source{
217
	belle_sip_object_t base;
Simon Morlat's avatar
Simon Morlat committed
218 219
	belle_sip_list_t node;
	unsigned long id;
jehan's avatar
jehan committed
220
	belle_sip_fd_t fd;
Simon Morlat's avatar
Simon Morlat committed
221 222 223 224 225 226 227
	unsigned int events;
	int timeout;
	void *data;
	uint64_t expire_ms;
	int index; /* index in pollfd table */
	belle_sip_source_func_t notify;
	belle_sip_source_remove_callback_t on_remove;
Simon Morlat's avatar
Simon Morlat committed
228 229
	unsigned char cancelled;
	unsigned char expired;
Simon Morlat's avatar
Simon Morlat committed
230
};
jehan's avatar
jehan committed
231

jehan's avatar
jehan committed
232
void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t func, void *data, belle_sip_fd_t fd, unsigned int events, unsigned int timeout_value_ms);
jehan's avatar
jehan committed
233 234 235

#define belle_list_next(elem) ((elem)->next)

236
/* include private headers */
237
#include "channel.h"
jehan's avatar
jehan committed
238

239

jehan's avatar
jehan committed
240
#ifdef __cplusplus
241
extern "C" {
jehan's avatar
jehan committed
242 243
#endif

244

245 246 247 248

#define belle_sip_new(type) (type*)belle_sip_malloc(sizeof(type))
#define belle_sip_new0(type) (type*)belle_sip_malloc0(sizeof(type))
	
249
belle_sip_list_t *belle_sip_list_new(void *data);
250
belle_sip_list_t*  belle_sip_list_append_link(belle_sip_list_t* elem,belle_sip_list_t *new_elem);
251
belle_sip_list_t *belle_sip_list_find_custom(belle_sip_list_t *list, belle_sip_compare_func compare_func, const void *user_data);
Simon Morlat's avatar
Simon Morlat committed
252
belle_sip_list_t *belle_sip_list_delete_custom(belle_sip_list_t *list, belle_sip_compare_func compare_func, const void *user_data);
253
belle_sip_list_t * belle_sip_list_free(belle_sip_list_t *list);
254

jehan's avatar
jehan committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268
#define belle_sip_list_next(elem) ((elem)->next)





#undef MIN
#define MIN(a,b)	((a)>(b) ? (b) : (a))
#undef MAX
#define MAX(a,b)	((a)>(b) ? (a) : (b))


char * belle_sip_concat (const char *str, ...);

269 270
uint64_t belle_sip_time_ms(void);

271 272 273 274 275
unsigned int belle_sip_random(void);

char *belle_sip_strdup_printf(const char *fmt,...);


jehan's avatar
jehan committed
276 277
/*parameters accessors*/
#define GET_SET_STRING(object_type,attribute) \
278
	const char* object_type##_get_##attribute (const object_type##_t* obj) {\
jehan's avatar
jehan committed
279 280 281
		return obj->attribute;\
	}\
	void object_type##_set_##attribute (object_type##_t* obj,const char* value) {\
Simon Morlat's avatar
Simon Morlat committed
282
		if (obj->attribute != NULL) belle_sip_free((void*)obj->attribute);\
283
		if (value) {\
Simon Morlat's avatar
Simon Morlat committed
284
			obj->attribute=belle_sip_malloc(strlen(value)+1);\
285 286
			strcpy((char*)(obj->attribute),value);\
		} else obj->attribute=NULL;\
jehan's avatar
jehan committed
287
	}
jehan's avatar
jehan committed
288 289 290 291 292 293
/*#define GET_SET_STRING_PARAM_NULL_ALLOWED(object_type,attribute) \
	GET_STRING_PARAM2(object_type,attribute,attribute) \
	void object_type##_set_##func_name (object_type##_t* obj,const char* value) {\
		belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(obj),#attribute,value);\
	}
*/
jehan's avatar
jehan committed
294 295
#define GET_SET_STRING_PARAM(object_type,attribute) GET_SET_STRING_PARAM2(object_type,attribute,attribute)
#define GET_SET_STRING_PARAM2(object_type,attribute,func_name) \
jehan's avatar
jehan committed
296 297 298 299 300 301 302 303 304
	GET_STRING_PARAM2(object_type,attribute,func_name) \
	void object_type##_set_##func_name (object_type##_t* obj,const char* value) {\
	if (belle_sip_parameters_is_parameter(BELLE_SIP_PARAMETERS(obj),#attribute) && !value) {\
		belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(obj),#attribute); \
	} else \
		belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(obj),#attribute,value);\
	}

#define GET_STRING_PARAM2(object_type,attribute,func_name) \
305
	const char* object_type##_get_##func_name (const object_type##_t* obj) {\
jehan's avatar
jehan committed
306 307
	const char* l_value = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
	if (l_value == NULL) { \
Simon Morlat's avatar
Simon Morlat committed
308
		/*belle_sip_warning("cannot find parameters [%s]",#attribute);*/\
jehan's avatar
jehan committed
309 310 311 312 313
		return NULL;\
	}\
	return l_value;\
	}

jehan's avatar
jehan committed
314 315
#define DESTROY_STRING(object,attribute) if (object->attribute) belle_sip_free((void*)object->attribute);

jehan's avatar
jehan committed
316 317 318
#define CLONE_STRING_GENERIC(object_type_src,object_type_dest,attribute,dest,src) \
		if ( object_type_src##_get_##attribute (src)) {\
			object_type_dest##_set_##attribute(dest,object_type_src##_get_##attribute(src));\
319
		}
jehan's avatar
jehan committed
320

jehan's avatar
jehan committed
321 322
#define CLONE_STRING(object_type,attribute,dest,src) CLONE_STRING_GENERIC(object_type,object_type,attribute,dest,src)

jehan's avatar
jehan committed
323 324 325
#define GET_SET_INT(object_type,attribute,type) GET_SET_INT_PRIVATE(object_type,attribute,type,)

#define GET_SET_INT_PRIVATE(object_type,attribute,type,set_prefix) \
326
	type  object_type##_get_##attribute (const object_type##_t* obj) {\
jehan's avatar
jehan committed
327 328 329 330 331
		return obj->attribute;\
	}\
	void set_prefix##object_type##_set_##attribute (object_type##_t* obj,type  value) {\
		obj->attribute=value;\
	}
jehan's avatar
jehan committed
332 333 334 335 336 337 338 339 340 341 342 343
#define GET_SET_INT_PARAM(object_type,attribute,type) GET_SET_INT_PARAM_PRIVATE(object_type,attribute,type,)
#define GET_SET_INT_PARAM2(object_type,attribute,type,func_name) GET_SET_INT_PARAM_PRIVATE2(object_type,attribute,type,,func_name)

#define ATO_(type,value) ATO_##type(value)
#define ATO_int(value) atoi(value)
#define ATO_float(value) strtof(value,NULL)
#define FORMAT_(type) FORMAT_##type
#define FORMAT_int    "%i"
#define FORMAT_float  "%f"

#define GET_SET_INT_PARAM_PRIVATE(object_type,attribute,type,set_prefix) GET_SET_INT_PARAM_PRIVATE2(object_type,attribute,type,set_prefix,attribute)
#define GET_SET_INT_PARAM_PRIVATE2(object_type,attribute,type,set_prefix,func_name) \
344
	type  object_type##_get_##func_name (const object_type##_t* obj) {\
jehan's avatar
jehan committed
345 346
		const char* l_value = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
		if (l_value == NULL) { \
jehan's avatar
jehan committed
347
			/*belle_sip_error("cannot find parameters [%s]",#attribute);*/\
jehan's avatar
jehan committed
348 349 350 351 352 353
			return -1;\
		}\
		return ATO_(type,l_value);\
	}\
	void set_prefix##object_type##_set_##func_name (object_type##_t* obj,type  value) {\
		char l_str_value[16];\
354 355 356 357
		if (value == -1) { \
			belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
			return;\
		}\
jehan's avatar
jehan committed
358 359 360
		snprintf(l_str_value,16,FORMAT_(type),value);\
		belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(obj),#attribute,(const char*)l_str_value);\
	}
jehan's avatar
jehan committed
361 362

#define GET_SET_BOOL(object_type,attribute,getter) \
363
	unsigned int object_type##_##getter##_##attribute (const object_type##_t* obj) {\
jehan's avatar
jehan committed
364 365 366 367 368
		return obj->attribute;\
	}\
	void object_type##_set_##attribute (object_type##_t* obj,unsigned int value) {\
		obj->attribute=value;\
	}
jehan's avatar
jehan committed
369
#define GET_SET_BOOL_PARAM2(object_type,attribute,getter,func_name) \
370
	unsigned int object_type##_##getter##_##func_name (const object_type##_t* obj) {\
jehan's avatar
jehan committed
371 372 373 374 375
		return belle_sip_parameters_is_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
	}\
	void object_type##_set_##func_name (object_type##_t* obj,unsigned int value) {\
		belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(obj),#attribute,NULL);\
	}
jehan's avatar
jehan committed
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394

#define BELLE_SIP_PARSE(object_type) \
belle_sip_##object_type##_t* belle_sip_##object_type##_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),\
			NULL);\
	lex    = belle_sip_messageLexerNew                (input);\
	tokens = antlr3CommonTokenStreamSourceNew  (ANTLR3_SIZE_HINT, TOKENSOURCE(lex));\
	parser = belle_sip_messageParserNew               (tokens);\
	belle_sip_##object_type##_t* l_parsed_object = parser->object_type(parser);\
	parser ->free(parser);\
	tokens ->free(tokens);\
	lex    ->free(lex);\
	input  ->close(input);\
jehan's avatar
jehan committed
395
	if (l_parsed_object == NULL) belle_sip_error(#object_type" parser error for [%s]",value);\
jehan's avatar
jehan committed
396 397 398
	return l_parsed_object;\
}

399 400 401
#define BELLE_SIP_NEW(object_type,super_type) \
	BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_##object_type##_t); \
	BELLE_SIP_INSTANCIATE_VPTR(	belle_sip_##object_type##_t\
jehan's avatar
jehan committed
402 403 404
									, belle_sip_##super_type##_t\
									, belle_sip_##object_type##_destroy\
									, belle_sip_##object_type##_clone\
405
									, belle_sip_##object_type##_marshal, TRUE); \
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
	belle_sip_##object_type##_t* belle_sip_##object_type##_new () { \
		belle_sip_##object_type##_t* l_object = belle_sip_object_new(belle_sip_##object_type##_t);\
		belle_sip_##super_type##_init((belle_sip_##super_type##_t*)l_object); \
		belle_sip_##object_type##_init((belle_sip_##object_type##_t*) l_object); \
		return l_object;\
	}

	
#define BELLE_SIP_NEW_HEADER(object_type,super_type,name) BELLE_SIP_NEW_HEADER_INIT(object_type,super_type,name,header)
#define BELLE_SIP_NEW_HEADER_INIT(object_type,super_type,name,init_type) \
	BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_##object_type##_t); \
	BELLE_SIP_INSTANCIATE_VPTR(	belle_sip_##object_type##_t\
								, belle_sip_##super_type##_t\
								, belle_sip_##object_type##_destroy\
								, belle_sip_##object_type##_clone\
								, belle_sip_##object_type##_marshal, TRUE); \
	belle_sip_##object_type##_t* belle_sip_##object_type##_new () { \
Simon Morlat's avatar
Simon Morlat committed
423
		belle_sip_##object_type##_t* l_object = belle_sip_object_new(belle_sip_##object_type##_t);\
424
		belle_sip_##super_type##_init((belle_sip_##super_type##_t*)l_object); \
jehan's avatar
jehan committed
425
		belle_sip_##init_type##_init((belle_sip_##init_type##_t*) l_object); \
jehan's avatar
jehan committed
426
		if (name) belle_sip_header_set_name(BELLE_SIP_HEADER(l_object),name);\
427 428
		return l_object;\
	}
jehan's avatar
jehan committed
429 430 431 432 433 434 435 436 437
typedef struct belle_sip_param_pair_t {
	int ref;
	char* name;
	char* value;
} belle_sip_param_pair_t;


belle_sip_param_pair_t* belle_sip_param_pair_new(const char* name,const char* value);

jehan's avatar
jehan committed
438
void belle_sip_param_pair_destroy(belle_sip_param_pair_t*  pair) ;
jehan's avatar
jehan committed
439 440 441 442 443 444 445 446

int belle_sip_param_pair_comp_func(const belle_sip_param_pair_t *a, const char*b) ;

belle_sip_param_pair_t* belle_sip_param_pair_ref(belle_sip_param_pair_t* obj);

void belle_sip_param_pair_unref(belle_sip_param_pair_t* obj);


jehan's avatar
jehan committed
447
void belle_sip_header_address_set_quoted_displayname(belle_sip_header_address_t* address,const char* value);
jehan's avatar
jehan committed
448

jehan's avatar
jehan committed
449 450 451
/*calss header*/
struct _belle_sip_header {
	belle_sip_object_t base;
jehan's avatar
jehan committed
452
	belle_sip_header_t* next;
jehan's avatar
jehan committed
453 454
	const char* name;
};
Simon Morlat's avatar
Simon Morlat committed
455

jehan's avatar
jehan committed
456 457
void belle_sip_header_set_next(belle_sip_header_t* header,belle_sip_header_t* next);
belle_sip_header_t* belle_sip_header_get_next(const belle_sip_header_t* headers);
Simon Morlat's avatar
Simon Morlat committed
458
void belle_sip_response_fill_for_dialog(belle_sip_response_t *obj, belle_sip_request_t *req);
459
void belle_sip_util_copy_headers(belle_sip_message_t *orig, belle_sip_message_t *dest, const char*header, int multiple);
jehan's avatar
jehan committed
460

jehan's avatar
jehan committed
461
void belle_sip_header_init(belle_sip_header_t* obj);
jehan's avatar
jehan committed
462 463
/*class parameters*/
struct _belle_sip_parameters {
jehan's avatar
jehan committed
464
	belle_sip_header_t base;
jehan's avatar
jehan committed
465 466 467 468 469 470
	belle_sip_list_t* param_list;
	belle_sip_list_t* paramnames_list;
};

void belle_sip_parameters_init(belle_sip_parameters_t *obj);

Simon Morlat's avatar
Simon Morlat committed
471
/*
472
 * Listening points
Simon Morlat's avatar
Simon Morlat committed
473 474
*/

475

476 477 478 479
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_listening_point_t,belle_sip_object_t)
const char *transport;
belle_sip_channel_t * (*create_channel)(belle_sip_listening_point_t *,const char *dest_ip, int port);
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
Simon Morlat's avatar
Simon Morlat committed
480

481 482

#define BELLE_SIP_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_listening_point_t)
Simon Morlat's avatar
wip  
Simon Morlat committed
483
void belle_sip_listening_point_remove_channel(belle_sip_listening_point_t *lp, belle_sip_channel_t *chan);
Simon Morlat's avatar
Simon Morlat committed
484

485 486 487 488 489 490 491

/*
 belle_sip_stack_t
*/
struct belle_sip_stack{
	belle_sip_object_t base;
	belle_sip_main_loop_t *ml;
492
	belle_sip_timer_config_t timer_config;
493
	int transport_timeout;
Simon Morlat's avatar
Simon Morlat committed
494
	int tx_delay; /*used to simulate network transmission delay, for tests*/
495 496 497 498
};

void belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req, belle_sip_hop_t *hop);

499
const belle_sip_timer_config_t *belle_sip_stack_get_timer_config(const belle_sip_stack_t *stack);
500 501 502 503

/*
 belle_sip_provider_t
*/
504 505 506 507 508 509

struct belle_sip_provider{
	belle_sip_object_t base;
	belle_sip_stack_t *stack;
	belle_sip_list_t *lps; /*listening points*/
	belle_sip_list_t *listeners;
jehan's avatar
jehan committed
510
	belle_sip_list_t *internal_listeners; /*for transaction internaly managed by belle-sip. I.E by refreshers*/
Simon Morlat's avatar
Simon Morlat committed
511
	belle_sip_list_t *client_transactions;
Simon Morlat's avatar
Simon Morlat committed
512
	belle_sip_list_t *server_transactions;
Simon Morlat's avatar
Simon Morlat committed
513
	belle_sip_list_t *dialogs;
514
	belle_sip_list_t *auth_contexts;
515 516
};

517
belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp);
Simon Morlat's avatar
Simon Morlat committed
518 519 520
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);
Simon Morlat's avatar
Simon Morlat committed
521 522 523 524
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);
525
void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t);
526
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const char *name, int port, const char *transport);
Simon Morlat's avatar
Simon Morlat committed
527 528
void belle_sip_provider_add_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
void belle_sip_provider_remove_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
529
void belle_sip_provider_release_channel(belle_sip_provider_t *p, belle_sip_channel_t *chan);
jehan's avatar
jehan committed
530
void belle_sip_provider_add_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l);
531

532 533 534 535 536
typedef struct listener_ctx{
	belle_sip_listener_t *listener;
	void *data;
}listener_ctx_t;

jehan's avatar
jehan committed
537 538 539 540 541
#define BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(t,callback,event) \
		BELLE_SIP_PROVIDER_INVOKE_LISTENERS((t)->is_internal?t->provider->internal_listeners:t->provider->listeners,callback,event)

#define BELLE_SIP_PROVIDER_INVOKE_LISTENERS(listeners,callback,event) \
	BELLE_SIP_INVOKE_LISTENERS_ARG((listeners),belle_sip_listener_t,callback,(event))
542

543 544 545 546 547

/*
 belle_sip_transaction_t
*/

548 549 550 551
struct belle_sip_transaction{
	belle_sip_object_t base;
	belle_sip_provider_t *provider; /*the provider that created this transaction */
	belle_sip_request_t *request;
552
	belle_sip_response_t *last_response;
Simon Morlat's avatar
Simon Morlat committed
553
	belle_sip_channel_t *channel;
Simon Morlat's avatar
Simon Morlat committed
554
	belle_sip_dialog_t *dialog;
555 556
	char *branch_id;
	belle_sip_transaction_state_t state;
jehan's avatar
jehan committed
557
	belle_sip_transaction_state_t previous_state; /*just to provide user with information regarding state transition*/
558 559
	uint64_t start_time;
	void *appdata;
jehan's avatar
jehan committed
560
	unsigned int  is_internal;
561 562
};

Simon Morlat's avatar
Simon Morlat committed
563 564 565 566 567 568 569 570 571 572 573 574

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_transaction_t,belle_sip_object_t)
	void (*on_terminate)(belle_sip_transaction_t *obj);
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

static inline const belle_sip_timer_config_t * belle_sip_transaction_get_timer_config(belle_sip_transaction_t *obj){
	return belle_sip_stack_get_timer_config(obj->provider->stack);
}

static inline void belle_sip_transaction_start_timer(belle_sip_transaction_t *obj, belle_sip_source_t *timer){
	belle_sip_main_loop_add_source(obj->provider->stack->ml,timer);
}
575
/** */
Simon Morlat's avatar
Simon Morlat committed
576 577 578 579 580
static inline void belle_sip_transaction_stop_timer(belle_sip_transaction_t *obj, belle_sip_source_t *timer){
	belle_sip_main_loop_remove_source(obj->provider->stack->ml,timer);
}

void belle_sip_transaction_notify_timeout(belle_sip_transaction_t *t);
Simon Morlat's avatar
Simon Morlat committed
581 582 583 584 585 586 587 588 589 590 591

/*
 *
 *
 *	Client transaction
 *
 *
*/

struct belle_sip_client_transaction{
	belle_sip_transaction_t base;
jehan's avatar
jehan committed
592
	belle_sip_header_route_t* preset_route; /*use to store first remove route header, will be helpful for refresher*/
Simon Morlat's avatar
Simon Morlat committed
593 594 595 596
};

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_client_transaction_t,belle_sip_transaction_t)
	void (*send_request)(belle_sip_client_transaction_t *);
597
	void (*on_response)(belle_sip_client_transaction_t *obj, belle_sip_response_t *resp);
Simon Morlat's avatar
Simon Morlat committed
598
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
599

Simon Morlat's avatar
Simon Morlat committed
600
void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, belle_sip_provider_t *prov, belle_sip_request_t *req);
601 602
void belle_sip_client_transaction_add_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp);
void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp);
603

Simon Morlat's avatar
Simon Morlat committed
604 605
struct belle_sip_ict{
	belle_sip_client_transaction_t base;
606 607 608
	belle_sip_source_t *timer_A;
	belle_sip_source_t *timer_B;
	belle_sip_source_t *timer_D;
609
	belle_sip_source_t *timer_M;
610
	belle_sip_request_t *ack;
Simon Morlat's avatar
Simon Morlat committed
611 612 613 614 615 616 617 618 619 620 621
};

typedef struct belle_sip_ict belle_sip_ict_t;

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_ict_t,belle_sip_client_transaction_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

belle_sip_ict_t * belle_sip_ict_new(belle_sip_provider_t *prov, belle_sip_request_t *req);

struct belle_sip_nict{
	belle_sip_client_transaction_t base;
Simon Morlat's avatar
Simon Morlat committed
622 623 624
	belle_sip_source_t *timer_F;
	belle_sip_source_t *timer_E;
	belle_sip_source_t *timer_K;
Simon Morlat's avatar
Simon Morlat committed
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
};

typedef struct belle_sip_nict belle_sip_nict_t;

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_nict_t,belle_sip_client_transaction_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

belle_sip_nict_t * belle_sip_nict_new(belle_sip_provider_t *prov, belle_sip_request_t *req);


/*
 *
 *
 *	Server transaction
 *
 *
*/

struct belle_sip_server_transaction{
	belle_sip_transaction_t base;
645
	char to_tag[8];
Simon Morlat's avatar
Simon Morlat committed
646 647 648
};

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_server_transaction_t,belle_sip_transaction_t)
649 650
	int (*send_new_response)(belle_sip_server_transaction_t *, belle_sip_response_t *resp);
	void (*on_request_retransmission)(belle_sip_server_transaction_t *obj);
Simon Morlat's avatar
Simon Morlat committed
651 652
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

653
void belle_sip_server_transaction_init(belle_sip_server_transaction_t *t, belle_sip_provider_t *prov,belle_sip_request_t *req);
Simon Morlat's avatar
Simon Morlat committed
654
void belle_sip_server_transaction_on_request(belle_sip_server_transaction_t *t, belle_sip_request_t *req);
655

Simon Morlat's avatar
Simon Morlat committed
656 657
struct belle_sip_ist{
	belle_sip_server_transaction_t base;
658 659 660
	belle_sip_source_t *timer_G;
	belle_sip_source_t *timer_H;
	belle_sip_source_t *timer_I;
661
	belle_sip_source_t *timer_L;
Simon Morlat's avatar
Simon Morlat committed
662 663 664 665 666 667 668 669
};

typedef struct belle_sip_ist belle_sip_ist_t;

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_ist_t,belle_sip_server_transaction_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

belle_sip_ist_t * belle_sip_ist_new(belle_sip_provider_t *prov, belle_sip_request_t *req);
670 671
/* returns 0 if the ack should be notified to TU, or -1 otherwise*/
int belle_sip_ist_process_ack(belle_sip_ist_t *obj, belle_sip_message_t *ack);
Simon Morlat's avatar
Simon Morlat committed
672 673 674

struct belle_sip_nist{
	belle_sip_server_transaction_t base;
675
	belle_sip_source_t *timer_J;
Simon Morlat's avatar
Simon Morlat committed
676 677 678 679 680 681 682 683 684
};

typedef struct belle_sip_nist belle_sip_nist_t;

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_nist_t,belle_sip_server_transaction_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

belle_sip_nist_t * belle_sip_nist_new(belle_sip_provider_t *prov, belle_sip_request_t *req);

Simon Morlat's avatar
Simon Morlat committed
685 686 687 688 689 690

/*
 * Dialogs
 */ 
struct belle_sip_dialog{
	belle_sip_object_t base;
691
	void *appdata;
Simon Morlat's avatar
Simon Morlat committed
692 693
	belle_sip_provider_t *provider;
	belle_sip_request_t *last_out_invite;
694 695 696 697
	belle_sip_request_t *last_out_ack; /*so that it can be retransmitted when needed*/
	belle_sip_response_t *last_200Ok;
	belle_sip_source_t *timer_200Ok;
	belle_sip_source_t *timer_200Ok_end;
Simon Morlat's avatar
Simon Morlat committed
698
	belle_sip_dialog_state_t state;
jehan's avatar
jehan committed
699
	belle_sip_dialog_state_t previous_state;
Simon Morlat's avatar
Simon Morlat committed
700 701 702 703 704 705 706 707 708 709 710 711
	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;
712
	int needs_ack:1;
Simon Morlat's avatar
Simon Morlat committed
713 714 715
};

belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t);
jehan's avatar
jehan committed
716
belle_sip_dialog_t * belle_sip_provider_create_dialog_internal(belle_sip_provider_t *prov, belle_sip_transaction_t *t,unsigned int check_last_resp);
Simon Morlat's avatar
Simon Morlat committed
717 718 719 720
/*returns 1 if message belongs to the dialog, 0 otherwise */
int _belle_sip_dialog_match(belle_sip_dialog_t *obj, const char *call_id, const char *local_tag, const char *remote_tag);
int belle_sip_dialog_match(belle_sip_dialog_t *obj, belle_sip_message_t *msg, int as_uas);
int belle_sip_dialog_update(belle_sip_dialog_t *obj,belle_sip_request_t *req, belle_sip_response_t *resp, int as_uas);
Simon Morlat's avatar
Simon Morlat committed
721
void belle_sip_dialog_check_ack_sent(belle_sip_dialog_t*obj);
722
int belle_sip_dialog_handle_ack(belle_sip_dialog_t *obj, belle_sip_request_t *ack);
jehan's avatar
jehan committed
723

Simon Morlat's avatar
Simon Morlat committed
724 725 726 727 728
/*
 belle_sip_response_t
*/
void belle_sip_response_get_return_hop(belle_sip_response_t *msg, belle_sip_hop_t *hop);

jehan's avatar
jehan committed
729 730
#define IS_TOKEN(token) \
		(INPUT->toStringTT(INPUT,LT(1),LT(strlen(#token)))->chars ?\
jehan's avatar
jehan committed
731
		strcasecmp(#token,(const char*)(INPUT->toStringTT(INPUT,LT(1),LT(strlen(#token)))->chars)) == 0:0)
732
char* _belle_sip_str_dup_and_unquote_string(const char* quoted_string);
733

jehan's avatar
jehan committed
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
/*********************************************************
 * SDP
 */
#define BELLE_SDP_PARSE(object_type) \
belle_sdp_##object_type##_t* belle_sdp_##object_type##_parse (const char* value) { \
	pANTLR3_INPUT_STREAM           input; \
	pbelle_sdpLexer               lex; \
	pANTLR3_COMMON_TOKEN_STREAM    tokens; \
	pbelle_sdpParser              parser; \
	input  = antlr3NewAsciiStringCopyStream	(\
			(pANTLR3_UINT8)value,\
			(ANTLR3_UINT32)strlen(value),\
			NULL);\
	lex    = belle_sdpLexerNew                (input);\
	tokens = antlr3CommonTokenStreamSourceNew  (ANTLR3_SIZE_HINT, TOKENSOURCE(lex));\
	parser = belle_sdpParserNew               (tokens);\
	belle_sdp_##object_type##_t* l_parsed_object = parser->object_type(parser).ret;\
	parser ->free(parser);\
	tokens ->free(tokens);\
	lex    ->free(lex);\
	input  ->close(input);\
	if (l_parsed_object == NULL) belle_sip_error(#object_type" parser error for [%s]",value);\
	return l_parsed_object;\
}
#define BELLE_SDP_NEW(object_type,super_type) \
759
		BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sdp_##object_type##_t); \
jehan's avatar
jehan committed
760 761 762 763
		BELLE_SIP_INSTANCIATE_VPTR(	belle_sdp_##object_type##_t\
									, super_type##_t\
									, belle_sdp_##object_type##_destroy\
									, belle_sdp_##object_type##_clone\
Simon Morlat's avatar
Simon Morlat committed
764
									, belle_sdp_##object_type##_marshal, TRUE); \
jehan's avatar
jehan committed
765 766 767 768 769
		belle_sdp_##object_type##_t* belle_sdp_##object_type##_new () { \
		belle_sdp_##object_type##_t* l_object = belle_sip_object_new(belle_sdp_##object_type##_t);\
		super_type##_init((super_type##_t*)l_object); \
		return l_object;\
	}
jehan's avatar
jehan committed
770
#define BELLE_SDP_NEW_WITH_CTR(object_type,super_type) \
771
		BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sdp_##object_type##_t); \
jehan's avatar
jehan committed
772 773 774 775
		BELLE_SIP_INSTANCIATE_VPTR(	belle_sdp_##object_type##_t\
									, super_type##_t\
									, belle_sdp_##object_type##_destroy\
									, belle_sdp_##object_type##_clone\
Simon Morlat's avatar
Simon Morlat committed
776
									, belle_sdp_##object_type##_marshal,TRUE); \
jehan's avatar
jehan committed
777 778 779 780 781 782
		belle_sdp_##object_type##_t* belle_sdp_##object_type##_new () { \
		belle_sdp_##object_type##_t* l_object = belle_sip_object_new(belle_sdp_##object_type##_t);\
		super_type##_init((super_type##_t*)l_object); \
		belle_sdp_##object_type##_init(l_object); \
		return l_object;\
	}
jehan's avatar
jehan committed
783 784 785



jehan's avatar
jehan committed
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
struct belle_sip_dialog_terminated_event{
	belle_sip_provider_t *source;
	belle_sip_dialog_t *dialog;
};

struct belle_sip_io_error_event{
	belle_sip_provider_t *source;
	const char *transport;
	const char *host;
	int port;
};

struct belle_sip_request_event{
	belle_sip_provider_t *source;
	belle_sip_server_transaction_t *server_transaction;
	belle_sip_dialog_t *dialog;
	belle_sip_request_t *request;
};

struct belle_sip_response_event{
	belle_sip_provider_t *source;
	belle_sip_client_transaction_t *client_transaction;
	belle_sip_dialog_t *dialog;
	belle_sip_response_t *response;
};

struct belle_sip_timeout_event{
	belle_sip_provider_t *source;
	belle_sip_transaction_t *transaction;
	int is_server_transaction;
};

struct belle_sip_transaction_terminated_event{
	belle_sip_provider_t *source;
	belle_sip_transaction_t *transaction;
	int is_server_transaction;
};

824 825 826 827 828 829 830 831 832
struct belle_sip_auth_event {
	char* username;
	char* userid;
	char* realm;
	char* passwd;
	char* ha1;
};
belle_sip_auth_event_t* belle_sip_auth_event_create(const char* realm,const char* username);
void belle_sip_auth_event_destroy(belle_sip_auth_event_t* event);
jehan's avatar
jehan committed
833

jehan's avatar
jehan committed
834 835 836 837
/*
 * refresher
 * */
belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* transaction);
jehan's avatar
jehan committed
838 839 840 841
#ifdef __cplusplus
}
#endif

jehan's avatar
jehan committed
842

Simon Morlat's avatar
Simon Morlat committed
843 844
/*include private headers */
#include "belle_sip_resolver.h"
845 846

#define BELLE_SIP_SOCKET_TIMEOUT 30000
Simon Morlat's avatar
Simon Morlat committed
847

jehan's avatar
jehan committed
848
#endif