diff --git a/src/plugins/janus_nosip.c b/src/plugins/janus_nosip.c index 9ed3179400..969fe8f642 100644 --- a/src/plugins/janus_nosip.c +++ b/src/plugins/janus_nosip.c @@ -78,7 +78,8 @@ { "event" : "generated", "type" : "", - "sdp" : "" + "sdp" : "", + "unique_id" : " } \endverbatim * @@ -104,7 +105,8 @@ \verbatim { "event" : "processed", - "srtp" : "" + "srtp" : "", + "unique_id" : " } \endverbatim * @@ -354,6 +356,7 @@ typedef struct janus_nosip_media { typedef struct janus_nosip_session { janus_plugin_session *handle; + char *unique_id; gint64 sdp_version; janus_nosip_media media; /* Media gatewaying stuff (same stuff as the SIP plugin) */ janus_sdp *sdp; /* The SDP this user sent */ @@ -369,6 +372,7 @@ typedef struct janus_nosip_session { janus_mutex mutex; } janus_nosip_session; static GHashTable *sessions; +static GHashTable *unique_ids; static janus_mutex sessions_mutex = JANUS_MUTEX_INITIALIZER; static void janus_nosip_srtp_cleanup(janus_nosip_session *session); @@ -387,6 +391,8 @@ static void janus_nosip_session_free(const janus_refcount *session_ref) { /* This session can be destroyed, free all the resources */ janus_sdp_destroy(session->sdp); session->sdp = NULL; + g_free(session->unique_id); + session->unique_id = NULL; g_free(session->media.remote_audio_ip); session->media.remote_audio_ip = NULL; g_free(session->media.remote_video_ip); @@ -842,6 +848,7 @@ int janus_nosip_init(janus_callbacks *callback, const char *config_path) { JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip); sessions = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)janus_nosip_session_destroy); + unique_ids = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); messages = g_async_queue_new_full((GDestroyNotify) janus_nosip_message_free); /* This is the callback we'll need to invoke to contact the Janus core */ gateway = callback; @@ -901,6 +908,8 @@ void janus_nosip_destroy(void) { janus_mutex_lock(&sessions_mutex); g_hash_table_destroy(sessions); sessions = NULL; + g_hash_table_destroy(unique_ids); + unique_ids = NULL; janus_mutex_unlock(&sessions_mutex); g_async_queue_unref(messages); messages = NULL; @@ -1017,6 +1026,14 @@ void janus_nosip_create_session(janus_plugin_session *handle, int *error) { janus_mutex_lock(&sessions_mutex); g_hash_table_insert(sessions, handle, session); + while(session->unique_id == NULL) { + session->unique_id = janus_random_uuid(); + if(g_hash_table_lookup(unique_ids, session->unique_id) != NULL) { + g_free(session->unique_id); + session->unique_id = NULL; + } + g_hash_table_insert(unique_ids, g_strdup(session->unique_id), session); + } janus_mutex_unlock(&sessions_mutex); return; @@ -1037,6 +1054,8 @@ void janus_nosip_destroy_session(janus_plugin_session *handle, int *error) { } JANUS_LOG(LOG_VERB, "Destroying NoSIP session (%p)...\n", session); janus_nosip_hangup_media_internal(handle); + if(session->unique_id) + g_hash_table_remove(sessions, session->unique_id); g_hash_table_remove(sessions, handle); janus_mutex_unlock(&sessions_mutex); return; @@ -1057,6 +1076,7 @@ json_t *janus_nosip_query_session(janus_plugin_session *handle) { janus_mutex_unlock(&sessions_mutex); /* Provide some generic info, e.g., if we're in a call and with whom */ json_t *info = json_object(); + json_object_set_new(info, "unique_id", json_string(session->unique_id)); if(session->sdp) { json_object_set_new(info, "srtp-required", json_string(session->media.require_srtp ? "yes" : "no")); json_object_set_new(info, "sdes-local", json_string(session->media.has_srtp_local ? "yes" : "no")); @@ -1552,6 +1572,7 @@ static void *janus_nosip_handler(void *data) { json_object_set_new(info, "event", json_string("generated")); json_object_set_new(info, "type", json_string(offer ? "offer" : "answer")); json_object_set_new(info, "sdp", json_string(sdp)); + json_object_set_new(info, "unique_id", json_string(session->unique_id)); gateway->notify_event(&janus_nosip_plugin, session->handle, info); } /* If the user negotiated simulcasting, just stick with the base substream */ @@ -1576,6 +1597,7 @@ static void *janus_nosip_handler(void *data) { json_object_set_new(result, "sdp", json_string(sdp)); if(sdp_update) json_object_set_new(result, "update", json_true()); + json_object_set_new(result, "unique_id", json_string(session->unique_id)); g_free(sdp); } else { /* We got a barebone offer or answer from our peer: process it accordingly */ @@ -1612,6 +1634,7 @@ static void *janus_nosip_handler(void *data) { json_object_set_new(info, "event", json_string("processed")); json_object_set_new(info, "type", json_string(offer ? "offer" : "answer")); json_object_set_new(info, "sdp", json_string(msg_sdp)); + json_object_set_new(info, "unique_id", json_string(session->unique_id)); gateway->notify_event(&janus_nosip_plugin, session->handle, info); } /* Send SDP to the browser */ @@ -1623,6 +1646,7 @@ static void *janus_nosip_handler(void *data) { } if(sdp_update) json_object_set_new(result, "update", json_true()); + json_object_set_new(result, "unique_id", json_string(session->unique_id)); localjsep = json_pack("{ssss}", "type", msg_sdp_type, "sdp", msg_sdp); } /* If this is an answer, start the media */ diff --git a/src/plugins/janus_sip.c b/src/plugins/janus_sip.c index f117ca23ab..ef21617c42 100644 --- a/src/plugins/janus_sip.c +++ b/src/plugins/janus_sip.c @@ -150,7 +150,8 @@ "event" : "registered", "username" : , "register_sent" : , - "master_id" : + "master_id" : , + "unique_id" : " } } \endverbatim @@ -1117,6 +1118,7 @@ typedef struct janus_sip_dtmf { typedef struct janus_sip_session { janus_plugin_session *handle; + char *unique_id; ssip_t *stack; janus_sip_account account; janus_sip_call_status status; @@ -1162,6 +1164,7 @@ static GHashTable *callids; static GHashTable *messageids; static GHashTable *masters; static GHashTable *transfers; +static GHashTable *unique_ids; static janus_mutex sessions_mutex = JANUS_MUTEX_INITIALIZER; static void janus_sip_srtp_cleanup(janus_sip_session *session); @@ -1275,6 +1278,10 @@ static void janus_sip_session_free(const janus_refcount *session_ref) { janus_sdp_destroy(session->sdp); session->sdp = NULL; } + if(session->unique_id) { + g_free(session->unique_id); + session->unique_id = NULL; + } if(session->transaction) { g_free(session->transaction); session->transaction = NULL; @@ -2197,6 +2204,7 @@ int janus_sip_init(janus_callbacks *callback, const char *config_path) { messageids = g_hash_table_new_full(NULL, NULL, (GDestroyNotify)g_free, (GDestroyNotify)janus_sip_session_dereference); masters = g_hash_table_new(NULL, NULL); transfers = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)janus_sip_transfer_destroy); + unique_ids = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); messages = g_async_queue_new_full((GDestroyNotify) janus_sip_message_free); /* This is the callback we'll need to invoke to contact the Janus core */ gateway = callback; @@ -2260,12 +2268,14 @@ void janus_sip_destroy(void) { g_hash_table_destroy(identities); g_hash_table_destroy(masters); g_hash_table_destroy(transfers); + g_hash_table_destroy(unique_ids); sessions = NULL; callids = NULL; messageids = NULL; identities = NULL; masters = NULL; transfers = NULL; + unique_ids = NULL; janus_mutex_unlock(&sessions_mutex); g_async_queue_unref(messages); messages = NULL; @@ -2424,6 +2434,14 @@ void janus_sip_create_session(janus_plugin_session *handle, int *error) { janus_mutex_lock(&sessions_mutex); g_hash_table_insert(sessions, handle, session); + while(session->unique_id == NULL) { + session->unique_id = janus_random_uuid(); + if(g_hash_table_lookup(unique_ids, session->unique_id) != NULL) { + g_free(session->unique_id); + session->unique_id = NULL; + } + g_hash_table_insert(unique_ids, g_strdup(session->unique_id), session); + } janus_mutex_unlock(&sessions_mutex); return; @@ -2490,6 +2508,8 @@ void janus_sip_destroy_session(janus_plugin_session *handle, int *error) { nua_shutdown(session->stack->s_nua); janus_mutex_unlock(&session->stack->smutex); } + if(session->unique_id) + g_hash_table_remove(sessions, session->unique_id); g_hash_table_remove(sessions, handle); janus_mutex_unlock(&sessions_mutex); return; @@ -2510,6 +2530,7 @@ json_t *janus_sip_query_session(janus_plugin_session *handle) { janus_mutex_unlock(&sessions_mutex); /* Provide some generic info, e.g., if we're in a call and with whom */ json_t *info = json_object(); + json_object_set_new(info, "unique_id", json_string(session->unique_id)); if(session->master != NULL) { /* This is an helper session, provide the details for the master session */ json_object_set_new(info, "helper", json_true()); @@ -3084,6 +3105,7 @@ static void *janus_sip_handler(void *data) { json_object_set_new(result, "register_sent", json_false()); json_object_set_new(result, "helper", json_true()); json_object_set_new(result, "master_id", json_integer(session->master_id)); + json_object_set_new(result, "unique_id", json_string(session->unique_id)); /* Also notify event handlers */ if(notify_events && gateway->events_is_enabled()) { json_t *info = json_object(); @@ -3092,6 +3114,7 @@ static void *janus_sip_handler(void *data) { json_object_set_new(info, "type", json_string("guest")); json_object_set_new(info, "helper", json_true()); json_object_set_new(info, "master_id", json_integer(session->master_id)); + json_object_set_new(info, "unique_id", json_string(session->unique_id)); gateway->notify_event(&janus_sip_plugin, session->handle, info); } goto done; @@ -3441,6 +3464,7 @@ static void *janus_sip_handler(void *data) { TAG_END()); result = json_object(); json_object_set_new(result, "event", json_string("registering")); + json_object_set_new(result, "unique_id", json_string(session->unique_id)); } else { JANUS_LOG(LOG_VERB, "Not sending a SIP REGISTER: either send_register was set to false or guest mode was enabled\n"); session->account.registration_status = janus_sip_registration_status_disabled; @@ -3449,6 +3473,7 @@ static void *janus_sip_handler(void *data) { json_object_set_new(result, "username", json_string(session->account.username)); json_object_set_new(result, "register_sent", json_false()); json_object_set_new(result, "master_id", json_integer(session->master_id)); + json_object_set_new(result, "unique_id", json_string(session->unique_id)); /* Also notify event handlers */ if(notify_events && gateway->events_is_enabled()) { json_t *info = json_object(); @@ -3456,6 +3481,7 @@ static void *janus_sip_handler(void *data) { json_object_set_new(info, "identity", json_string(session->account.identity)); json_object_set_new(info, "type", json_string("guest")); json_object_set_new(info, "master_id", json_integer(session->master_id)); + json_object_set_new(info, "unique_id", json_string(session->unique_id)); gateway->notify_event(&janus_sip_plugin, session->handle, info); } } @@ -6347,6 +6373,7 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase, json_t *headers = janus_sip_get_incoming_headers(sip, session); json_object_set_new(reging, "headers", headers); } + json_object_set_new(reg, "unique_id", json_string(session->unique_id)); json_object_set_new(reg, "result", reging); int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, reg, NULL); JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));