Fix a random one way audio issue in PJSIP.
[asterisk/asterisk.git] / res / res_pjsip_session.c
index c6c3953..9cb85dc 100644 (file)
 
 #define SDP_HANDLER_BUCKETS 11
 
+#define MOD_DATA_ON_RESPONSE "on_response"
+#define MOD_DATA_NAT_HOOK "nat_hook"
+
+/* Hostname used for origin line within SDP */
+static const pj_str_t *hostname;
+
 /* 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 +133,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 +150,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;
 }
@@ -466,6 +472,7 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
        successful = ao2_callback(session->media, OBJ_MULTIPLE, handle_negotiated_sdp_session_media, &callback_data);
        if (successful && ao2_container_count(successful->c) == ao2_container_count(session->media)) {
                /* Nothing experienced a catastrophic failure */
+               ast_queue_frame(session->channel, &ast_null_frame);
                return 0;
        }
        return -1;
@@ -925,7 +932,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 +1650,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 +1859,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 +1914,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:
@@ -1985,7 +1995,7 @@ static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, stru
        pj_strdup2(inv->pool, &local->origin.user, session->endpoint->media.sdpowner);
        local->origin.net_type = STR_IN;
        local->origin.addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4;
-       local->origin.addr = *pj_gethostname();
+       local->origin.addr = *hostname;
        pj_strdup2(inv->pool, &local->name, session->endpoint->media.sdpsession);
 
        /* Now let the handlers add streams of various types, pjmedia will automatically reorder the media streams for us */
@@ -2073,7 +2083,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 +2118,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)
@@ -2130,21 +2141,20 @@ static int load_module(void)
        pjsip_inv_usage_init(endpt, &inv_callback);
        pjsip_100rel_init_module(endpt);
        pjsip_timer_init_module(endpt);
+       hostname = pj_gethostname();
        if (ast_sip_register_service(&session_module)) {
                return AST_MODULE_LOAD_DECLINE;
        }
        ast_sip_register_service(&session_reinvite_module);
+
+       ast_module_ref(ast_module_info->self);
+
        return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-       ast_sip_unregister_service(&session_module);
-       ast_sip_unregister_service(&session_reinvite_module);
-       if (nat_hook) {
-               ast_sorcery_delete(ast_sip_get_sorcery(), nat_hook);
-               nat_hook = NULL;
-       }
+       /* This will never get called as this module can't be unloaded */
        return 0;
 }