Newer
Older
void *ast_sip_dict_set(pj_pool_t* pool, void *ht,
const char *key, void *val)
{
if (!ht) {
ht = pj_hash_create(pool, 11);
}
pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
return ht;
}
static void remove_request_headers(pjsip_endpoint *endpt)
{
const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
pjsip_hdr *iter = request_headers->next;
while (iter != request_headers) {
pjsip_hdr *to_erase = iter;
iter = iter->next;
pj_list_erase(to_erase);
}
}
static int load_module(void)
{
/* The third parameter is just copied from
* example code from PJLIB. This can be adjusted
* if necessary.
struct ast_threadpool_options options;
if (pj_init() != PJ_SUCCESS) {
return AST_MODULE_LOAD_DECLINE;
}
if (pjlib_util_init() != PJ_SUCCESS) {
pj_shutdown();
return AST_MODULE_LOAD_DECLINE;
}
pj_caching_pool_init(&caching_pool, NULL, 1024 * 1024);
if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
/* PJSIP will automatically try to add a Max-Forwards header. Since we want to control that,
* we need to stop PJSIP from doing it automatically
*/
remove_request_headers(ast_pjsip_endpoint);
memory_pool = pj_pool_create(&caching_pool.factory, "SIP", 1024, 1024, NULL);
if (!memory_pool) {
ast_log(LOG_ERROR, "Failed to create memory pool for SIP. Aborting load\n");
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
if (ast_sip_initialize_system()) {
ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
pj_pool_release(memory_pool);
memory_pool = NULL;
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
sip_get_threadpool_options(&options);
options.thread_start = sip_thread_start;
sip_threadpool = ast_threadpool_create("SIP", NULL, &options);
if (!sip_threadpool) {
ast_log(LOG_ERROR, "Failed to create SIP threadpool. Aborting load\n");
pj_pool_release(memory_pool);
memory_pool = NULL;
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
monitor_continue = 1;
status = pj_thread_create(memory_pool, "SIP", (pj_thread_proc *) &monitor_thread_exec,
NULL, PJ_THREAD_DEFAULT_STACK_SIZE * 2, 0, &monitor_thread);
if (status != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Failed to start SIP monitor thread. Aborting load\n");
pj_pool_release(memory_pool);
memory_pool = NULL;
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
ast_sip_initialize_global_headers();
if (ast_res_pjsip_initialize_configuration(ast_module_info)) {
ast_log(LOG_ERROR, "Failed to initialize SIP configuration. Aborting load\n");
ast_sip_destroy_global_headers();
stop_monitor_thread();
pj_pool_release(memory_pool);
memory_pool = NULL;
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
}
if (ast_sip_initialize_distributor()) {
ast_log(LOG_ERROR, "Failed to register distributor module. Aborting load\n");
ast_res_pjsip_destroy_configuration();
ast_sip_destroy_global_headers();
stop_monitor_thread();
pj_pool_release(memory_pool);
memory_pool = NULL;
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
}
if (ast_sip_initialize_outbound_authentication()) {
ast_log(LOG_ERROR, "Failed to initialize outbound authentication. Aborting load\n");
ast_sip_destroy_distributor();
ast_res_pjsip_destroy_configuration();
ast_sip_destroy_global_headers();
stop_monitor_thread();
pj_pool_release(memory_pool);
memory_pool = NULL;
pjsip_endpt_destroy(ast_pjsip_endpoint);
ast_pjsip_endpoint = NULL;
pj_caching_pool_destroy(&caching_pool);
return AST_MODULE_LOAD_DECLINE;
ast_res_pjsip_init_options_handling(0);
ast_module_ref(ast_module_info->self);
return AST_MODULE_LOAD_SUCCESS;
}
static int reload_module(void)
{
if (ast_res_pjsip_reload_configuration()) {
return AST_MODULE_LOAD_DECLINE;
}
ast_res_pjsip_init_options_handling(1);
return 0;
}
static int unload_module(void)
{
/* This will never get called as this module can't be unloaded */
return 0;
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Basic SIP resource",
.load = load_module,
.unload = unload_module,
.reload = reload_module,
.load_pri = AST_MODPRI_CHANNEL_DEPEND - 5,