belle_sip_internal.h 39.2 KB
Newer Older
jehan's avatar
jehan committed
1 2
/*
	belle-sip - SIP (RFC3261) library.
3
	Copyright (C) 2010  Belledonne Communications SARL
jehan's avatar
jehan committed
4

5 6
	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
7
	the Free Software Foundation, either version 2 of the License, or
8
	(at your option) any later version.
jehan's avatar
jehan committed
9

10 11 12 13
	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.
jehan's avatar
jehan committed
14

15 16
	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
17
*/
jehan's avatar
jehan committed
18 19
#ifndef belle_utils_h
#define belle_utils_h
20 21 22 23

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
Simon Morlat's avatar
Simon Morlat committed
24
#include <sys/types.h>
25
#include <errno.h>
Simon Morlat's avatar
Simon Morlat committed
26

Simon Morlat's avatar
Simon Morlat committed
27
/* include all public headers*/
Simon Morlat's avatar
Simon Morlat committed
28
#include "belle-sip/belle-sip.h"
jehan's avatar
jehan committed
29

Simon Morlat's avatar
Simon Morlat committed
30 31
#include "port.h"

32 33
#ifdef HAVE_CONFIG_H

jehan's avatar
jehan committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#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 VERSION
#undef VERSION
#endif
52 53 54
#ifdef PACKAGE_VERSION
#undef PACKAGE_VERSION
#endif
jehan's avatar
jehan committed
55 56

#include "config.h"
57

58 59 60
#else

#ifndef PACKAGE_VERSION
61
#error "PACKAGE_VERSION must be defined and equal to the VERSION file included in the belle-sip repository"
62 63
#endif

jehan's avatar
jehan committed
64 65
#endif

66

67 68 69 70
/*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
71

72
#define __BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method) \
73
	if (list!=NULL) {\
Simon Morlat's avatar
Simon Morlat committed
74 75
		belle_sip_list_t *__copy=belle_sip_list_copy_with_data((list), (void* (*)(void*))belle_sip_object_ref);\
		const belle_sip_list_t *__elem=__copy;\
76
		do{\
77
			void *__method;\
78
			interface_name *__obj=(interface_name*)__elem->data;\
79
			__method=BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->method;\
80
			if (__method) BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->
81 82 83 84

#define __BELLE_SIP_INVOKE_LISTENER_END \
			__elem=__elem->next;\
		}while(__elem!=NULL);\
Simon Morlat's avatar
Simon Morlat committed
85
		belle_sip_list_free_with_data(__copy,belle_sip_object_unref);\
86 87 88
	}

#define BELLE_SIP_INVOKE_LISTENERS_VOID(list,interface_name,method) \
89
			__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
90 91 92 93
			method(__obj);\
			__BELLE_SIP_INVOKE_LISTENER_END

#define BELLE_SIP_INVOKE_LISTENERS_ARG(list,interface_name,method,arg) \
94
	__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
95 96 97 98 99
	method(__obj,arg);\
	__BELLE_SIP_INVOKE_LISTENER_END


#define BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(list,interface_name,method,arg1,arg2) \
100
			__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
101 102 103 104 105 106 107 108
			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

Simon Morlat's avatar
Simon Morlat committed
109 110 111
#define BELLE_SIP_INVOKE_LISTENER_ARG(listener,interface_name,method,arg) \
	((BELLE_SIP_INTERFACE_GET_METHODS((listener),interface_name)->method!=NULL)  ? \
		BELLE_SIP_INTERFACE_GET_METHODS((listener),interface_name)->method(listener,(arg)) : 0 )
112

113 114 115 116 117 118
typedef struct weak_ref{
	struct weak_ref *next;
	belle_sip_object_destroy_notify_t notify;
	void *userpointer;
}weak_ref_t;

119

120
void *belle_sip_object_get_interface_methods(belle_sip_object_t *obj, belle_sip_interface_id_t ifid);
121 122
/*used internally by unref()*/
void belle_sip_object_delete(void *obj);
123 124
void belle_sip_object_pool_add(belle_sip_object_pool_t *pool, belle_sip_object_t *obj);
void belle_sip_object_pool_remove(belle_sip_object_pool_t *pool, belle_sip_object_t *obj);
125 126 127 128 129

#define belle_sip_object_init(obj)		/*nothing*/


/*list of all vptrs (classes) used in belle-sip*/
130 131 132 133 134 135 136 137 138 139 140
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_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);
141
BELLE_SIP_DECLARE_VPTR(belle_sip_uri_t);
142 143 144
BELLE_SIP_DECLARE_VPTR(belle_sip_message_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_request_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_response_t);
145
BELLE_SIP_DECLARE_VPTR(belle_sip_parameters_t);
146 147 148 149 150 151 152 153 154 155 156
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
157
BELLE_SIP_DECLARE_VPTR(belle_sip_header_proxy_authenticate_t);
158 159 160 161 162 163 164 165 166 167 168 169 170 171
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);
172
BELLE_SIP_DECLARE_VPTR(belle_sdp_raw_attribute_t);
173
BELLE_SIP_DECLARE_VPTR(belle_sdp_repeate_time_t);
174
BELLE_SIP_DECLARE_VPTR(belle_sdp_rtcp_fb_attribute_t);
175
BELLE_SIP_DECLARE_VPTR(belle_sdp_rtcp_xr_attribute_t);
176 177 178 179 180 181 182
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);
183
BELLE_SIP_DECLARE_VPTR(belle_sdp_mime_parameter_t);
jehan's avatar
jehan committed
184
BELLE_SIP_DECLARE_VPTR(belle_sip_refresher_t);
jehan's avatar
jehan committed
185
BELLE_SIP_DECLARE_VPTR(belle_sip_header_subscription_state_t);
jehan's avatar
jehan committed
186
BELLE_SIP_DECLARE_VPTR(belle_sip_header_service_route_t);
jehan's avatar
jehan committed
187
BELLE_SIP_DECLARE_VPTR(belle_sip_header_refer_to_t);
jehan's avatar
jehan committed
188 189
BELLE_SIP_DECLARE_VPTR(belle_sip_header_referred_by_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_replaces_t);
Simon Morlat's avatar
Simon Morlat committed
190
BELLE_SIP_DECLARE_VPTR(belle_sip_header_date_t);
Simon Morlat's avatar
Simon Morlat committed
191
BELLE_SIP_DECLARE_VPTR(belle_sip_hop_t);
192
BELLE_SIP_DECLARE_VPTR(belle_sip_object_pool_t);
jehan's avatar
jehan committed
193
BELLE_SIP_DECLARE_VPTR(belle_sip_header_p_preferred_identity_t);
jehan's avatar
jehan committed
194
BELLE_SIP_DECLARE_VPTR(belle_sip_header_privacy_t);
jehan's avatar
jehan committed
195 196
BELLE_SIP_DECLARE_VPTR(belle_sip_certificates_chain_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_signing_key_t);
197
BELLE_SIP_DECLARE_VPTR(belle_sip_dns_srv_t);
198
BELLE_SIP_DECLARE_VPTR(belle_sip_dict_t)
Simon Morlat's avatar
Simon Morlat committed
199 200 201 202
BELLE_SIP_DECLARE_VPTR(belle_http_provider_t);
BELLE_SIP_DECLARE_VPTR(belle_http_channel_context_t);
BELLE_SIP_DECLARE_VPTR(belle_http_request_t);
BELLE_SIP_DECLARE_VPTR(belle_http_response_t);
203
BELLE_SIP_DECLARE_VPTR(belle_generic_uri_t);
Simon Morlat's avatar
Simon Morlat committed
204
BELLE_SIP_DECLARE_VPTR(belle_http_callbacks_t);
205
BELLE_SIP_DECLARE_VPTR(belle_tls_verify_policy_t);
jehan's avatar
jehan committed
206
BELLE_SIP_DECLARE_VPTR(belle_http_header_authorization_t);
207
BELLE_SIP_DECLARE_VPTR(belle_sip_header_event_t);
jehan's avatar
jehan committed
208

209 210 211
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_resolver_context_t,belle_sip_source_t)
	void (*cancel)(belle_sip_resolver_context_t *);
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
jehan's avatar
jehan committed
212

213 214
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_simple_resolver_context_t,belle_sip_resolver_context_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
jehan's avatar
jehan committed
215

216 217 218
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_combined_resolver_context_t,belle_sip_resolver_context_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

219
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_dual_resolver_context_t,belle_sip_resolver_context_t)
220 221 222
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

typedef void (*belle_sip_source_remove_callback_t)(belle_sip_source_t *);
jehan's avatar
jehan committed
223

Simon Morlat's avatar
Simon Morlat committed
224
struct belle_sip_source{
225
	belle_sip_object_t base;
Simon Morlat's avatar
Simon Morlat committed
226 227
	belle_sip_list_t node;
	unsigned long id;
228
	belle_sip_fd_t fd;
229
	unsigned short events,revents;
230 231 232 233
#ifdef WIN32
	unsigned short armed_events;
	unsigned short pad;
#endif
Simon Morlat's avatar
Simon Morlat committed
234 235 236 237 238 239
	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;
240
	belle_sip_socket_t sock;
Simon Morlat's avatar
Simon Morlat committed
241 242
	unsigned char cancelled;
	unsigned char expired;
Simon Morlat's avatar
Simon Morlat committed
243
	unsigned char oneshot;
244
	unsigned char notify_required; /*for testing purpose, use to ask for being scheduled*/
Simon Morlat's avatar
Simon Morlat committed
245
};
jehan's avatar
jehan committed
246

247
void belle_sip_socket_source_init(belle_sip_source_t *s, belle_sip_source_func_t func, void *data, belle_sip_socket_t fd, unsigned int events, unsigned int timeout_value_ms);
248
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);
249
void belle_sip_source_uninit(belle_sip_source_t *s);
250
void belle_sip_source_set_notify(belle_sip_source_t *s, belle_sip_source_func_t func);
251

252

jehan's avatar
jehan committed
253

254
/* include private headers */
255
#include "channel.h"
jehan's avatar
jehan committed
256

257

258

259 260 261

#define belle_sip_new(type) (type*)belle_sip_malloc(sizeof(type))
#define belle_sip_new0(type) (type*)belle_sip_malloc0(sizeof(type))
262

263
#define belle_list_next(elem) ((elem)->next)
264
belle_sip_list_t *belle_sip_list_new(void *data);
265
belle_sip_list_t*  belle_sip_list_append_link(belle_sip_list_t* elem,belle_sip_list_t *new_elem);
Simon Morlat's avatar
Simon Morlat committed
266
belle_sip_list_t *belle_sip_list_delete_custom(belle_sip_list_t *list, belle_sip_compare_func compare_func, const void *user_data);
267
belle_sip_list_t*  _belle_sip_list_remove(belle_sip_list_t* first, void *data, int warn_if_not_found);
268

jehan's avatar
jehan committed
269 270 271
#define belle_sip_list_next(elem) ((elem)->next)


272 273 274 275
/* dictionary */
struct belle_sip_dict {
	belle_sip_object_t base;
};
jehan's avatar
jehan committed
276 277 278 279 280 281 282 283


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


Ghislain MARY's avatar
Ghislain MARY committed
284
BELLESIP_INTERNAL_EXPORT char * belle_sip_concat (const char *str, ...);
jehan's avatar
jehan committed
285

286

jehan's avatar
jehan committed
287 288
/*parameters accessors*/
#define GET_SET_STRING(object_type,attribute) \
289
	const char* object_type##_get_##attribute (const object_type##_t* obj) {\
jehan's avatar
jehan committed
290 291 292
		return obj->attribute;\
	}\
	void object_type##_set_##attribute (object_type##_t* obj,const char* value) {\
293
		const char* previous_value = obj->attribute;  /*preserve if same value re-asigned*/ \
294
		if (value) {\
Simon Morlat's avatar
Simon Morlat committed
295
			obj->attribute=belle_sip_strdup(value); \
296
		} else obj->attribute=NULL;\
297 298
		if (previous_value != NULL) belle_sip_free((void*)previous_value);\
}
jehan's avatar
jehan committed
299 300 301 302 303 304
/*#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);\
	}
*/
305 306
#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
307 308
	GET_STRING_PARAM2(object_type,attribute,func_name) \
	void object_type##_set_##func_name (object_type##_t* obj,const char* value) {\
309
	if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(obj),#attribute) && !value) {\
jehan's avatar
jehan committed
310 311 312 313 314 315
		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) \
316
	const char* object_type##_get_##func_name (const object_type##_t* obj) {\
317 318
	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
319
		/*belle_sip_warning("cannot find parameters [%s]",#attribute);*/\
320 321 322 323 324
		return NULL;\
	}\
	return l_value;\
	}

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

jehan's avatar
jehan committed
327 328 329
#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));\
330
		}
331

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

jehan's avatar
jehan committed
334 335 336
#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) \
337
	type  object_type##_get_##attribute (const object_type##_t* obj) {\
jehan's avatar
jehan committed
338 339 340 341 342
		return obj->attribute;\
	}\
	void set_prefix##object_type##_set_##attribute (object_type##_t* obj,type  value) {\
		obj->attribute=value;\
	}
343 344 345 346 347
#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)
348
#define ATO_float(value) (float)strtod(value,NULL)
349 350 351 352 353 354
#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) \
355
	type  object_type##_get_##func_name (const object_type##_t* obj) {\
356 357
		const char* l_value = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
		if (l_value == NULL) { \
jehan's avatar
jehan committed
358
			/*belle_sip_error("cannot find parameters [%s]",#attribute);*/\
359 360 361 362 363 364
			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];\
365 366 367 368
		if (value == -1) { \
			belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
			return;\
		}\
369 370 371
		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
372 373

#define GET_SET_BOOL(object_type,attribute,getter) \
374
	unsigned int object_type##_##getter##_##attribute (const object_type##_t* obj) {\
jehan's avatar
jehan committed
375 376 377 378 379
		return obj->attribute;\
	}\
	void object_type##_set_##attribute (object_type##_t* obj,unsigned int value) {\
		obj->attribute=value;\
	}
380
#define GET_SET_BOOL_PARAM2(object_type,attribute,getter,func_name) \
381
	unsigned int object_type##_##getter##_##func_name (const object_type##_t* obj) {\
382
		return belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(obj),#attribute);\
383 384 385 386
	}\
	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
387

Ghislain MARY's avatar
Ghislain MARY committed
388
#ifdef HAVE_ANTLR_STRING_STREAM_NEW
389 390 391 392 393 394 395 396
#define ANTLR_STREAM_NEW(object_type, value,length) \
antlr3StringStreamNew((pANTLR3_UINT8)value,ANTLR3_ENC_8BIT,(ANTLR3_UINT32)length,(pANTLR3_UINT8)#object_type)
#else
#define ANTLR_STREAM_NEW(object_type, value, length) \
antlr3NewAsciiStringCopyStream((pANTLR3_UINT8)value,(ANTLR3_UINT32)length,NULL)
#endif /*HAVE_ANTLR_STRING_STREAM_NEW*/


397 398
#define BELLE_PARSE(parser_name, object_type_prefix, object_type) \
	object_type_prefix##object_type##_t* object_type_prefix##object_type##_parse (const char* value) { \
jehan's avatar
jehan committed
399
	pANTLR3_INPUT_STREAM           input; \
jehan's avatar
jehan committed
400
	pbelle_sip_messageLexer               lex; \
jehan's avatar
jehan committed
401
	pANTLR3_COMMON_TOKEN_STREAM    tokens; \
402
	p##parser_name              parser; \
403
	object_type_prefix##object_type##_t* l_parsed_object; \
404
	input  = ANTLR_STREAM_NEW(object_type,value,strlen(value));\
jehan's avatar
jehan committed
405
	lex    = belle_sip_messageLexerNew                (input);\
jehan's avatar
jehan committed
406
	tokens = antlr3CommonTokenStreamSourceNew  (ANTLR3_SIZE_HINT, TOKENSOURCE(lex));\
407
	parser = parser_name##New               (tokens);\
408
	l_parsed_object = parser->object_type(parser);\
jehan's avatar
jehan committed
409 410 411 412
	parser ->free(parser);\
	tokens ->free(tokens);\
	lex    ->free(lex);\
	input  ->close(input);\
413
	if (l_parsed_object == NULL) belle_sip_error(#object_type" parser error for [%s]",value);\
jehan's avatar
jehan committed
414 415
	return l_parsed_object;\
}
416
#define BELLE_SIP_PARSE(object_type) BELLE_PARSE(belle_sip_messageParser,belle_sip_,object_type)
417 418 419 420 421 422 423 424 425 426 427 428

#define BELLE_NEW(object_type,super_type) \
	BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(object_type##_t); \
	BELLE_SIP_INSTANCIATE_VPTR(	object_type##_t\
								, super_type##_t\
								, object_type##_destroy\
								, object_type##_clone\
								, object_type##_marshal, TRUE); \
		object_type##_t* object_type##_new () { \
		object_type##_t* l_object = belle_sip_object_new(object_type##_t);\
		super_type##_init((super_type##_t*)l_object); \
		object_type##_init((object_type##_t*) l_object); \
429 430 431
		return l_object;\
	}

432
#define BELLE_SIP_NEW(object_type,super_type) BELLE_NEW (belle_sip_##object_type, belle_sip_##super_type)
433

434 435 436 437 438 439 440 441 442
#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 () { \
443
		belle_sip_##object_type##_t* l_object = belle_sip_object_new(belle_sip_##object_type##_t);\
444
		belle_sip_##super_type##_init((belle_sip_##super_type##_t*)l_object); \
445
		belle_sip_##init_type##_init((belle_sip_##init_type##_t*) l_object); \
446
		if (name) belle_sip_header_set_name(BELLE_SIP_HEADER(l_object),name);\
447 448
		return l_object;\
	}
449
struct belle_sip_param_pair {
jehan's avatar
jehan committed
450 451 452
	int ref;
	char* name;
	char* value;
453
} ;
jehan's avatar
jehan committed
454

455
void belle_sip_param_pair_destroy(belle_sip_param_pair_t*  pair) ;
jehan's avatar
jehan committed
456 457

int belle_sip_param_pair_comp_func(const belle_sip_param_pair_t *a, const char*b) ;
jehan's avatar
jehan committed
458
int belle_sip_param_pair_case_comp_func(const belle_sip_param_pair_t *a, const char*b) ;
jehan's avatar
jehan committed
459 460 461 462 463 464

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);


465

jehan's avatar
jehan committed
466

jehan's avatar
jehan committed
467 468 469
/*calss header*/
struct _belle_sip_header {
	belle_sip_object_t base;
jehan's avatar
jehan committed
470
	belle_sip_header_t* next;
Simon Morlat's avatar
Simon Morlat committed
471 472
	char *name;
	char *unparsed_value;
jehan's avatar
jehan committed
473
};
474

475

Simon Morlat's avatar
Simon Morlat committed
476
void belle_sip_response_fill_for_dialog(belle_sip_response_t *obj, belle_sip_request_t *req);
477
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
478

jehan's avatar
jehan committed
479
void belle_sip_header_init(belle_sip_header_t* obj);
480 481
/*class parameters*/
struct _belle_sip_parameters {
jehan's avatar
jehan committed
482
	belle_sip_header_t base;
483 484 485 486 487 488
	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
489
/*
490
 * Listening points
Simon Morlat's avatar
Simon Morlat committed
491 492
*/

493
#include "listeningpoint_internal.h"
494

Simon Morlat's avatar
Simon Morlat committed
495 496 497

struct belle_sip_hop{
	belle_sip_object_t base;
498
	char *cname;
Simon Morlat's avatar
Simon Morlat committed
499 500 501 502 503 504
	char *host;
	char *transport;
	int port;
};


505 506 507 508 509 510
/*
 belle_sip_stack_t
*/
struct belle_sip_stack{
	belle_sip_object_t base;
	belle_sip_main_loop_t *ml;
511
	belle_sip_timer_config_t timer_config;
512
	int transport_timeout;
513
	int inactive_transport_timeout;
514
	int dns_timeout;
Simon Morlat's avatar
Simon Morlat committed
515
	int tx_delay; /*used to simulate network transmission delay, for tests*/
516
	int send_error; /* used to simulate network error. if <0, channel_send will return this value*/
517 518
	int resolver_tx_delay; /*used to simulate network transmission delay, for tests*/
	int resolver_send_error;	/* used to simulate network error*/
Simon Morlat's avatar
Simon Morlat committed
519
	int dscp;
jehan's avatar
jehan committed
520
	char *dns_user_hosts_file; /* used to load additional hosts file for tests */
Simon Morlat's avatar
Simon Morlat committed
521
	char *dns_resolv_conf; /*used to load custom resolv.conf, for tests*/
522
	unsigned char dns_srv_enabled;
523 524
};

525
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port);
Simon Morlat's avatar
Simon Morlat committed
526
belle_sip_hop_t* belle_sip_hop_new_from_uri(const belle_sip_uri_t *uri);
Simon Morlat's avatar
Simon Morlat committed
527
belle_sip_hop_t* belle_sip_hop_new_from_generic_uri(const belle_generic_uri_t *uri);
528

Simon Morlat's avatar
Simon Morlat committed
529
belle_sip_hop_t * belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req);
530 531 532 533

/*
 belle_sip_provider_t
*/
534 535 536 537 538 539

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
540
	belle_sip_list_t *internal_listeners; /*for transaction internaly managed by belle-sip. I.E by refreshers*/
541
	belle_sip_list_t *client_transactions;
Simon Morlat's avatar
Simon Morlat committed
542
	belle_sip_list_t *server_transactions;
Simon Morlat's avatar
Simon Morlat committed
543
	belle_sip_list_t *dialogs;
544
	belle_sip_list_t *auth_contexts;
545 546
	unsigned char rport_enabled; /*0 if rport should not be set in via header*/
	unsigned char nat_helper;
547
	unsigned char unconditional_answer_enabled;
548 549
};

550
BELLESIP_INTERNAL_EXPORT belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp);
551 552 553
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
554
void belle_sip_provider_add_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
555
BELLESIP_INTERNAL_EXPORT belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t *prov,belle_sip_request_t *req);
Simon Morlat's avatar
Simon Morlat committed
556
void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
557
void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t);
558
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const belle_sip_hop_t *hop);
Simon Morlat's avatar
Simon Morlat committed
559 560
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);
561
void belle_sip_provider_release_channel(belle_sip_provider_t *p, belle_sip_channel_t *chan);
562
void belle_sip_provider_add_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l, int prepend);
563
void belle_sip_provider_remove_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l);
564 565
belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transaction_from_req(belle_sip_provider_t *prov, belle_sip_request_t *req);
belle_sip_dialog_t *belle_sip_provider_find_dialog_from_message(belle_sip_provider_t *prov, belle_sip_message_t *msg, int as_uas);
566
/*for testing purpose only:*/
567
BELLESIP_INTERNAL_EXPORT void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, belle_sip_message_t *msg);
568

569 570 571 572 573
typedef struct listener_ctx{
	belle_sip_listener_t *listener;
	void *data;
}listener_ctx_t;

jehan's avatar
jehan committed
574
#define BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(t,callback,event) \
Simon Morlat's avatar
Simon Morlat committed
575
		BELLE_SIP_PROVIDER_INVOKE_LISTENERS((t)->is_internal?(t)->provider->internal_listeners:(t)->provider->listeners,callback,event)
jehan's avatar
jehan committed
576 577 578

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

Simon Morlat's avatar
Simon Morlat committed
580 581 582
/*
 * http provider
 */
Simon Morlat's avatar
Simon Morlat committed
583
belle_http_provider_t *belle_http_provider_new(belle_sip_stack_t *s, const char *bind_ip);
584

Simon Morlat's avatar
Simon Morlat committed
585 586 587 588

/*
 * SIP and http messages
**/
589
#define BELLESIP_MULTIPART_BOUNDARY "---------------------------14737809831466499882746641449"
Simon Morlat's avatar
Simon Morlat committed
590 591 592

void belle_sip_message_init(belle_sip_message_t *message);

593 594 595
struct _belle_sip_message {
	belle_sip_object_t base;
	belle_sip_list_t* header_list;
596
	belle_sip_body_handler_t *body_handler;
597
};
598

599
struct _belle_sip_request {
600
	belle_sip_message_t base;
601 602
	char* method;
	belle_sip_uri_t* uri;
603
	belle_generic_uri_t *absolute_uri;
604
	belle_sip_dialog_t *dialog;/*set if request was created by a dialog to avoid to search in dialog list*/
605
	char *rfc2543_branch; /*computed 'branch' id in case we receive this request from an old RFC2543 stack*/
606 607
	unsigned char dialog_queued;
};
Simon Morlat's avatar
Simon Morlat committed
608 609


Simon Morlat's avatar
Simon Morlat committed
610 611 612 613 614 615 616
/** HTTP request**/

struct belle_http_request{
	belle_sip_message_t base;
	belle_generic_uri_t *req_uri;
	char* method;
	belle_http_request_listener_t *listener;
617
	belle_generic_uri_t *orig_uri;/*original uri before removing host and user/passwd*/
Simon Morlat's avatar
Simon Morlat committed
618
	belle_http_response_t *response;
619
	belle_sip_channel_t *channel;
Simon Morlat's avatar
Simon Morlat committed
620
	int auth_attempt_count;
621
	int background_task_id;
622
	int cancelled;
Simon Morlat's avatar
Simon Morlat committed
623 624 625
};

void belle_http_request_set_listener(belle_http_request_t *req, belle_http_request_listener_t *l);
626
void belle_http_request_set_channel(belle_http_request_t *req, belle_sip_channel_t *chan);
Simon Morlat's avatar
Simon Morlat committed
627
void belle_http_request_set_response(belle_http_request_t *req, belle_http_response_t *resp);
628 629 630 631
/*
 belle_sip_transaction_t
*/

632 633 634 635
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;
636
	belle_sip_response_t *last_response;
637
	belle_sip_channel_t *channel;
Simon Morlat's avatar
Simon Morlat committed
638
	belle_sip_dialog_t *dialog;
639 640 641
	char *branch_id;
	belle_sip_transaction_state_t state;
	void *appdata;
642
	unsigned char is_internal;
643
	unsigned char timed_out;
644
	unsigned char sent_by_dialog_queue;
645 646
};

647 648 649 650 651

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

652
static BELLESIP_INLINE const belle_sip_timer_config_t * belle_sip_transaction_get_timer_config(belle_sip_transaction_t *obj){
653 654 655
	return belle_sip_stack_get_timer_config(obj->provider->stack);
}

656
static BELLESIP_INLINE void belle_sip_transaction_start_timer(belle_sip_transaction_t *obj, belle_sip_source_t *timer){
657 658
	belle_sip_main_loop_add_source(obj->provider->stack->ml,timer);
}
659
/** */
660
static BELLESIP_INLINE void belle_sip_transaction_stop_timer(belle_sip_transaction_t *obj, belle_sip_source_t *timer){
661 662 663 664
	belle_sip_main_loop_remove_source(obj->provider->stack->ml,timer);
}

void belle_sip_transaction_notify_timeout(belle_sip_transaction_t *t);
665

666 667
void belle_sip_transaction_set_dialog(belle_sip_transaction_t *t, belle_sip_dialog_t *dialog);

668 669
void belle_sip_transaction_set_state(belle_sip_transaction_t *t, belle_sip_transaction_state_t state);

670 671 672 673 674 675 676 677 678 679
/*
 *
 *
 *	Client transaction
 *
 *
*/

struct belle_sip_client_transaction{
	belle_sip_transaction_t base;
680
	belle_sip_uri_t* preset_route; /*use to store outbound proxy, will be helpful for refresher*/
681
	belle_sip_hop_t* next_hop; /*use to send cancel request*/
682 683 684 685
};

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_client_transaction_t,belle_sip_transaction_t)
	void (*send_request)(belle_sip_client_transaction_t *);
686
	void (*on_response)(belle_sip_client_transaction_t *obj, belle_sip_response_t *resp);
687
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
688

689
void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, belle_sip_provider_t *prov, belle_sip_request_t *req);
690 691
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);
692

693 694
struct belle_sip_ict{
	belle_sip_client_transaction_t base;
695 696 697
	belle_sip_source_t *timer_A;
	belle_sip_source_t *timer_B;
	belle_sip_source_t *timer_D;
698
	belle_sip_source_t *timer_M;
699
	belle_sip_request_t *ack;
700 701 702 703 704 705 706 707 708 709 710
};

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;
711 712 713
	belle_sip_source_t *timer_F;
	belle_sip_source_t *timer_E;
	belle_sip_source_t *timer_K;
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
};

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;
734
	char to_tag[8];
735 736 737
};

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_server_transaction_t,belle_sip_transaction_t)
738 739
	int (*send_new_response)(belle_sip_server_transaction_t *, belle_sip_response_t *resp);
	void (*on_request_retransmission)(belle_sip_server_transaction_t *obj);
740 741
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

742
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
743
void belle_sip_server_transaction_on_request(belle_sip_server_transaction_t *t, belle_sip_request_t *req);
744

745 746
struct belle_sip_ist{
	belle_sip_server_transaction_t base;
747 748 749
	belle_sip_source_t *timer_G;
	belle_sip_source_t *timer_H;
	belle_sip_source_t *timer_I;
750
	belle_sip_source_t *timer_L;
751 752 753 754 755 756 757 758
};

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);
759 760
/* 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);
761 762 763

struct belle_sip_nist{
	belle_sip_server_transaction_t base;
764
	belle_sip_source_t *timer_J;
765 766 767 768 769 770 771 772 773
};

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
774 775 776

/*
 * Dialogs
777
 */
Simon Morlat's avatar
Simon Morlat committed
778 779
struct belle_sip_dialog{
	belle_sip_object_t base;
780
	void *appdata;
Simon Morlat's avatar
Simon Morlat committed
781 782
	belle_sip_provider_t *provider;
	belle_sip_request_t *last_out_invite;
783 784 785 786
	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
787
	belle_sip_dialog_state_t state;
jehan's avatar
jehan committed
788
	belle_sip_dialog_state_t previous_state;
Simon Morlat's avatar
Simon Morlat committed
789 790 791 792 793 794 795 796 797
	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;
798
	belle_sip_transaction_t* last_transaction;
jehan's avatar
jehan committed
799
	belle_sip_header_privacy_t* privacy;
800 801 802 803 804
	belle_sip_list_t *queued_ct;/* queued client transactions*/
	unsigned char is_server;
	unsigned char is_secure;
	unsigned char terminate_on_bye;
	unsigned char needs_ack;
Simon Morlat's avatar
Simon Morlat committed
805 806 807
};

belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t);
jehan's avatar
jehan committed
808
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);
809
int belle_sip_dialog_is_authorized_transaction(const belle_sip_dialog_t *dialog,const char* method) ;
Simon Morlat's avatar
Simon Morlat committed
810 811 812
/*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);
813
int belle_sip_dialog_update(belle_sip_dialog_t *obj,belle_sip_transaction_t* transaction, int as_uas);
Simon Morlat's avatar
Simon Morlat committed
814
void belle_sip_dialog_check_ack_sent(belle_sip_dialog_t*obj);
815
int belle_sip_dialog_handle_ack(belle_sip_dialog_t *obj, belle_sip_request_t *ack);
816
void belle_sip_dialog_queue_client_transaction(belle_sip_dialog_t *dialog, belle_sip_client_transaction_t *tr);
jehan's avatar
jehan committed
817

Simon Morlat's avatar
Simon Morlat committed
818 819 820
/*
 belle_sip_response_t
*/
821
belle_sip_hop_t* belle_sip_response_get_return_hop(belle_sip_response_t *msg);
Simon Morlat's avatar
Simon Morlat committed
822

823

jehan's avatar
jehan committed
824 825 826 827 828 829 830 831 832
/*********************************************************
 * 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; \
833
	belle_sdp_##object_type##_t* l_parsed_object; \
834
	input  = ANTLR_STREAM_NEW(object_type, value,strlen(value));\
jehan's avatar
jehan committed
835 836 837
	lex    = belle_sdpLexerNew                (input);\
	tokens = antlr3CommonTokenStreamSourceNew  (ANTLR3_SIZE_HINT, TOKENSOURCE(lex));\
	parser = belle_sdpParserNew               (tokens);\
838
	l_parsed_object = parser->object_type(parser).ret;\
jehan's avatar
jehan committed
839 840 841 842 843 844 845 846
	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) \
847
		BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sdp_##object_type##_t); \
jehan's avatar
jehan committed
848 849 850 851
		BELLE_SIP_INSTANCIATE_VPTR(	belle_sdp_##object_type##_t\
									, super_type##_t\
									, belle_sdp_##object_type##_destroy\
									, belle_sdp_##object_type##_clone\
852
									, belle_sdp_##object_type##_marshal, TRUE); \
jehan's avatar
jehan committed
853 854 855 856 857
		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
858
#define BELLE_SDP_NEW_WITH_CTR(object_type,super_type) \
859
		BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sdp_##object_type##_t); \
jehan's avatar
jehan committed
860 861 862 863
		BELLE_SIP_INSTANCIATE_VPTR(	belle_sdp_##object_type##_t\
									, super_type##_t\
									, belle_sdp_##object_type##_destroy\
									, belle_sdp_##object_type##_clone\
864
									, belle_sdp_##object_type##_marshal,TRUE); \
jehan's avatar
jehan committed
865 866 867 868 869 870
		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
871 872 873



jehan's avatar
jehan committed
874 875 876 877 878 879
struct belle_sip_dialog_terminated_event{
	belle_sip_provider_t *source;
	belle_sip_dialog_t *dialog;
};

struct belle_sip_io_error_event{
880
	belle_sip_object_t *source;  /*the object impacted by this error*/
jehan's avatar
jehan committed
881 882
	const char *transport;
	const char *host;
883
	unsigned int port;
jehan's avatar
jehan committed
884 885 886
};

struct belle_sip_request_event{
887
	belle_sip_object_t *source;
jehan's avatar
jehan committed
888 889 890 891 892 893
	belle_sip_server_transaction_t *server_transaction;
	belle_sip_dialog_t *dialog;
	belle_sip_request_t *request;
};

struct belle_sip_response_event{
894
	belle_sip_object_t *source;
jehan's avatar
jehan committed
895 896 897 898 899 900
	belle_sip_client_transaction_t *client_transaction;
	belle_sip_dialog_t *dialog;
	belle_sip_response_t *response;
};

struct belle_sip_timeout_event{
901
	belle_sip_object_t *source;
jehan's avatar
jehan committed
902 903 904 905 906 907 908 909 910 911
	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;
};

912
struct belle_sip_auth_event {
913
	belle_sip_object_t *source;
jehan's avatar
jehan committed
914
	belle_sip_auth_mode_t mode;
915 916 917 918 919
	char* username;
	char* userid;
	char* realm;
	char* passwd;
	char* ha1;
920 921
	char* domain;
	char* distinguished_name;
jehan's avatar
jehan committed
922 923
	belle_sip_certificates_chain_t * cert;
	belle_sip_signing_key_t* key;
924
};
jehan's avatar
jehan committed
925

926
belle_sip_auth_event_t* belle_sip_auth_event_create(belle_sip_object_t *source, const char* realm,const belle_sip_uri_t * from_uri);
jehan's avatar
jehan committed
927

jehan's avatar
jehan committed
928 929
void belle_sip_auth_event_set_distinguished_name(belle_sip_auth_event_t* event,const char* value);

jehan's avatar
jehan committed
930 931 932 933
/*
 * refresher
 * */
belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* transaction);
934

jehan's avatar
jehan committed
935

jehan's avatar
jehan committed
936 937 938
/*
 * returns a char, even if entry is escaped*/
int belle_sip_get_char (const char*a,int n,char*out);
939
/*return an escaped string*/
940
BELLESIP_INTERNAL_EXPORT	char* belle_sip_uri_to_escaped_username(const char* buff) ;
jehan's avatar
jehan committed
941
BELLESIP_INTERNAL_EXPORT	char* belle_sip_uri_to_escaped_userpasswd(const char* buff) ;
942
BELLESIP_INTERNAL_EXPORT	char* belle_sip_uri_to_escaped_parameter(const char* buff) ;
943
BELLESIP_INTERNAL_EXPORT	char* belle_sip_uri_to_escaped_header(const char* buff) ;
jehan's avatar
jehan committed
944 945


946 947 948 949
/*(uri RFC 2396)*/

BELLESIP_INTERNAL_EXPORT char* belle_generic_uri_to_escaped_query(const char* buff);
BELLESIP_INTERNAL_EXPORT char* belle_generic_uri_to_escaped_path(const char* buff);
950 951

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

953 954 955
#define BELLE_SIP_BRANCH_ID_LENGTH 10
/*Shall not be less than 32bit */
#define BELLE_SIP_TAG_LENGTH 6
956
#define BELLE_SIP_MAX_TO_STRING_SIZE 2048
957

958
void belle_sip_header_contact_set_unknown(belle_sip_header_contact_t *a, int value);
959
void belle_sip_request_set_dialog(belle_sip_request_t *req, belle_sip_dialog_t *dialog);
960
void belle_sip_request_set_rfc2543_branch(belle_sip_request_t *req, const char *rfc2543branch);
961
void belle_sip_dialog_update_request(belle_sip_dialog_t *dialog, belle_sip_request_t *req);
962

jehan's avatar
jehan committed
963 964
belle_sip_error_code belle_sip_headers_marshal(belle_sip_message_t *message, char* buff, size_t buff_size, size_t *offset);

965 966 967 968 969 970 971
#define SET_OBJECT_PROPERTY(obj,property_name,new_value) \
	if (new_value) belle_sip_object_ref(new_value); \
	if (obj->property_name){ \
		belle_sip_object_unref(obj->property_name); \
	}\
	obj->property_name=new_value;

Simon Morlat's avatar
Simon Morlat committed
972 973
#include "parserutils.h"

jehan's avatar
jehan committed
974 975 976 977 978 979 980 981 982 983 984
/******************************
 *
 * private Extension header inherit from header
 *
 ******************************/
typedef struct _belle_sip_header_extension belle_sip_header_extension_t;

belle_sip_header_extension_t* belle_sip_header_extension_new();

belle_sip_header_extension_t* belle_sip_header_extension_parse (const char* extension) ;
belle_sip_header_extension_t* belle_sip_header_extension_create (const char* name,const char* value);
985
BELLESIP_INTERNAL_EXPORT const char* belle_sip_header_extension_get_value(const belle_sip_header_extension_t* extension);
jehan's avatar
jehan committed
986 987 988
void belle_sip_header_extension_set_value(belle_sip_header_extension_t* extension,const char* value);
#define BELLE_SIP_HEADER_EXTENSION(t) BELLE_SIP_CAST(t,belle_sip_header_extension_t)

989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011

/****************
 * belle_sip_body_handler_t object
 ***************/


BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_body_handler_t,belle_sip_object_t)
	void (*chunk_recv)(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, size_t offset, const uint8_t *buf, size_t size);
	int (*chunk_send)(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, size_t offset, uint8_t *buf, size_t * size);
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

void belle_sip_body_handler_begin_transfer(belle_sip_body_handler_t *obj);
void belle_sip_body_handler_recv_chunk(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, const uint8_t *buf, size_t size);
int belle_sip_body_handler_send_chunk(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, uint8_t *buf, size_t *size);
void belle_sip_body_handler_end_transfer(belle_sip_body_handler_t *obj);


BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_memory_body_handler_t,belle_sip_body_handler_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_user_body_handler_t,belle_sip_body_handler_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

1012 1013 1014
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_file_body_handler_t,belle_sip_body_handler_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

1015 1016 1017
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_multipart_body_handler_t,belle_sip_body_handler_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
/**
 * file manipulation
 */
/**
 * Parse a directory and return all files in it.
 *
 * @param[in]	path		The directory to be parsed
 * @param[in]	file_type	if not NULL return only the file with the given extension, must include the '.', ex:".pem"
 * @return		a belle_sip list containing all found file or NULL if no file were found or directory doesn't exist. List must be destroyed using belle_sip_list_free_with_data(<ret_list>, belle_sip_free)
 */
belle_sip_list_t *belle_sip_parse_directory(const char *path, const char *file_type); 

/**
 * create a directory if it doesn't already exists
 *
 * @param[in] 	path		The directory to be created
 * @return 0 in case of succes, -1 otherwise, note it returns -1 if the directory already exists
 */
int belle_sip_mkdir(const char *path);
jehan's avatar
jehan committed
1037
#endif