diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 9ba2e90c71..8c78720841 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -1504,4 +1504,60 @@ int ast_sip_add_global_response_header(const char *name, const char *value, int int ast_sip_initialize_sorcery_global(struct ast_sorcery *sorcery); +/*! + * \brief Retrieves the value associated with the given key. + * + * \param ht the hash table/dictionary to search + * \param key the key to find + * + * \retval the value associated with the key, NULL otherwise. + */ +void *ast_sip_dict_get(void *ht, const char *key); + +/*! + * \brief Using the dictionary stored in mod_data array at a given id, + * retrieve the value associated with the given key. + * + * \param mod_data a module data array + * \param id the mod_data array index + * \param key the key to find + * + * \retval the value associated with the key, NULL otherwise. + */ +#define ast_sip_mod_data_get(mod_data, id, key) \ + ast_sip_dict_get(mod_data[id], key) + +/*! + * \brief Set the value for the given key. + * + * Note - if the hash table does not exist one is created first, the key/value + * pair is set, and the hash table returned. + * + * \param pool the pool to allocate memory in + * \param ht the hash table/dictionary in which to store the key/value pair + * \param key the key to associate a value with + * \param val the value to associate with a key + * + * \retval the given, or newly created, hash table. + */ +void *ast_sip_dict_set(pj_pool_t* pool, void *ht, + const char *key, void *val); + +/*! + * \brief Utilizing a mod_data array for a given id, set the value + * associated with the given key. + * + * For a given structure's mod_data array set the element indexed by id to + * be a dictionary containing the key/val pair. + * + * \param pool a memory allocation pool + * \param mod_data a module data array + * \param id the mod_data array index + * \param key the key to find + * \param val the value to associate with a key + */ +#define ast_sip_mod_data_set(pool, mod_data, id, key, val) \ + mod_data[id] = ast_sip_dict_set(pool, mod_data[id], key, val) + + #endif /* _RES_PJSIP_H */ diff --git a/res/res_pjsip.c b/res/res_pjsip.c index eab9b14037..c102803a2e 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1836,6 +1836,29 @@ int ast_sip_thread_is_servant(void) return *servant_id == SIP_SERVANT_ID; } +void *ast_sip_dict_get(void *ht, const char *key) +{ + unsigned int hval; + + if (!ht) { + return NULL; + } + + return pj_hash_get(ht, key, PJ_HASH_KEY_STRING, &hval); +} + +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); diff --git a/res/res_pjsip.exports.in b/res/res_pjsip.exports.in index d896ee60d0..5afafc481e 100644 --- a/res/res_pjsip.exports.in +++ b/res/res_pjsip.exports.in @@ -70,6 +70,8 @@ LINKER_SYMBOL_PREFIXast_sip_initialize_sorcery_global; LINKER_SYMBOL_PREFIXast_sip_auth_array_init; LINKER_SYMBOL_PREFIXast_sip_auth_array_destroy; + LINKER_SYMBOL_PREFIXast_sip_dict_get; + LINKER_SYMBOL_PREFIXast_sip_dict_set; local: *; }; diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index cac4c2fc58..54e03f531c 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -45,6 +45,9 @@ #define SDP_HANDLER_BUCKETS 11 +#define MOD_DATA_ON_RESPONSE "on_response" +#define MOD_DATA_NAT_HOOK "nat_hook" + /* Some forward declarations */ static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata); static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata); @@ -127,7 +130,7 @@ int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *han } } AST_LIST_INSERT_TAIL(&handler_list->list, handler, next); - ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type); + ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type); ast_module_ref(ast_module_info->self); return 0; } @@ -144,7 +147,7 @@ int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *han if (!ao2_link(sdp_handlers, handler_list)) { return -1; } - ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type); + ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type); ast_module_ref(ast_module_info->self); return 0; } @@ -925,7 +928,9 @@ void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip return; } - tdata->mod_data[session_module.id] = on_response; + ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id, + MOD_DATA_ON_RESPONSE, on_response); + handle_outgoing_request(session, tdata); pjsip_inv_send_msg(session->inv_session, tdata); return; @@ -1641,7 +1646,7 @@ static void reschedule_reinvite(struct ast_sip_session *session, ast_sip_session pjsip_inv_session *inv = session->inv_session; struct reschedule_reinvite_data *rrd = reschedule_reinvite_data_alloc(session, delay); pj_time_val tv; - + if (!rrd || !delay) { return; } @@ -1850,6 +1855,7 @@ static void session_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e) static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) { + ast_sip_session_response_cb cb; struct ast_sip_session *session = inv->mod_data[session_module.id]; print_debug_details(inv, tsx, e); if (!session) { @@ -1904,8 +1910,8 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans handle_incoming_request(session, e->body.tsx_state.src.rdata); } } - if (tsx->mod_data[session_module.id]) { - ast_sip_session_response_cb cb = tsx->mod_data[session_module.id]; + if ((cb = ast_sip_mod_data_get(tsx->mod_data, session_module.id, + MOD_DATA_ON_RESPONSE))) { cb(session, e->body.tsx_state.src.rdata); } case PJSIP_EVENT_TRANSPORT_ERROR: @@ -2073,7 +2079,8 @@ static pjsip_inv_callback inv_callback = { /*! \brief Hook for modifying outgoing messages with SDP to contain the proper address information */ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_transport *transport) { - struct ast_sip_nat_hook *hook = tdata->mod_data[session_module.id]; + struct ast_sip_nat_hook *hook = ast_sip_mod_data_get( + tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK); struct pjmedia_sdp_session *sdp; int stream; @@ -2107,7 +2114,7 @@ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_trans } /* We purposely do this so that the hook will not be invoked multiple times, ie: if a retransmit occurs */ - tdata->mod_data[session_module.id] = nat_hook; + ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK, nat_hook); } static int load_module(void)