void janus_videocall_destroy_session(janus_plugin_session *handle, int *error) { if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) { *error = -1; return; } janus_videocall_session *session = (janus_videocall_session *)handle->plugin_handle; if(!session) { JANUS_LOG(LOG_ERR, "No VideoCall session associated with this handle...\n"); *error = -2; return; } if(session->destroyed) { JANUS_LOG(LOG_VERB, "VideoCall session already destroyed...\n"); return; } JANUS_LOG(LOG_VERB, "Removing VideoCall user %s session...\n", session->username ? session->username : "******"); janus_videocall_hangup_media(handle); if(session->username != NULL) { janus_mutex_lock(&sessions_mutex); int res = g_hash_table_remove(sessions, (gpointer)session->username); JANUS_LOG(LOG_VERB, " -- Removed: %d\n", res); janus_mutex_unlock(&sessions_mutex); } /* Cleaning up and removing the session is done in a lazy way */ session->destroyed = janus_get_monotonic_time(); janus_mutex_lock(&sessions_mutex); old_sessions = g_list_append(old_sessions, session); janus_mutex_unlock(&sessions_mutex); return; }
static gboolean janus_websockets_is_allowed(const char *ip, gboolean admin) { JANUS_LOG(LOG_VERB, "Checking if %s is allowed to contact %s interface\n", ip, admin ? "admin" : "janus"); if(ip == NULL) return FALSE; if(!admin && janus_websockets_access_list == NULL) { JANUS_LOG(LOG_VERB, "Yep\n"); return TRUE; } if(admin && janus_websockets_admin_access_list == NULL) { JANUS_LOG(LOG_VERB, "Yeah\n"); return TRUE; } janus_mutex_lock(&access_list_mutex); GList *temp = admin ? janus_websockets_admin_access_list : janus_websockets_access_list; while(temp) { const char *allowed = (const char *)temp->data; if(allowed != NULL && strstr(ip, allowed)) { janus_mutex_unlock(&access_list_mutex); return TRUE; } temp = temp->next; } janus_mutex_unlock(&access_list_mutex); JANUS_LOG(LOG_VERB, "Nope...\n"); return FALSE; }
int janus_websockets_send_message(void *transport, void *request_id, gboolean admin, json_t *message) { if(message == NULL) return -1; if(transport == NULL) { g_free(message); return -1; } /* Make sure this is not related to a closed /freed WebSocket session */ janus_mutex_lock(&old_wss_mutex); janus_websockets_client *client = (janus_websockets_client *)transport; if(g_list_find(old_wss, client) != NULL) { g_free(message); message = NULL; transport = NULL; } else if(!client->context || !client->wsi) { g_free(message); message = NULL; } if(message == NULL) { janus_mutex_unlock(&old_wss_mutex); return -1; } janus_mutex_lock(&client->mutex); /* Convert to string and enqueue */ char *payload = json_dumps(message, JSON_INDENT(3) | JSON_PRESERVE_ORDER); g_async_queue_push(client->messages, payload); libwebsocket_callback_on_writable(client->context, client->wsi); janus_mutex_unlock(&client->mutex); janus_mutex_unlock(&old_wss_mutex); json_decref(message); return 0; }
void janus_websockets_session_over(void *transport, guint64 session_id, gboolean timeout) { if(transport == NULL || !timeout) return; /* We only care if it's a timeout: if so, close the connection */ janus_websockets_client *client = (janus_websockets_client *)transport; /* Make sure this is not related to a closed WebSocket session */ janus_mutex_lock(&old_wss_mutex); if(g_list_find(old_wss, client) == NULL && client->context && client->wsi){ janus_mutex_lock(&client->mutex); client->session_timeout = 1; libwebsocket_callback_on_writable(client->context, client->wsi); janus_mutex_unlock(&client->mutex); } janus_mutex_unlock(&old_wss_mutex); }
static void janus_websockets_destroy_client( janus_websockets_client *ws_client, #ifdef HAVE_LIBWEBSOCKETS_NEWAPI struct lws *wsi, #else struct libwebsocket *wsi, #endif const char *log_prefix) { if(!ws_client || ws_client->destroy) return; /* Notify handlers about this transport being gone */ if(notify_events && gateway->events_is_enabled()) { json_t *info = json_object(); json_object_set_new(info, "event", json_string("disconnected")); gateway->notify_event(&janus_websockets_transport, ws_client, info); } /* Notify core */ gateway->transport_gone(&janus_websockets_transport, ws_client); /* Mark the session as closed */ janus_mutex_lock(&old_wss_mutex); old_wss = g_list_append(old_wss, ws_client); janus_mutex_unlock(&old_wss_mutex); /* Cleanup */ janus_mutex_lock(&ws_client->mutex); JANUS_LOG(LOG_INFO, "[%s-%p] Destroying WebSocket client\n", log_prefix, wsi); ws_client->destroy = 1; #ifndef HAVE_LIBWEBSOCKETS_NEWAPI ws_client->context = NULL; #endif ws_client->wsi = NULL; /* Remove messages queue too, if needed */ if(ws_client->messages != NULL) { char *response = NULL; while((response = g_async_queue_try_pop(ws_client->messages)) != NULL) { g_free(response); } g_async_queue_unref(ws_client->messages); } /* ... and the shared buffers */ g_free(ws_client->incoming); ws_client->incoming = NULL; g_free(ws_client->buffer); ws_client->buffer = NULL; ws_client->buflen = 0; ws_client->bufpending = 0; ws_client->bufoffset = 0; janus_mutex_unlock(&ws_client->mutex); }
int janus_sctp_association_setup(janus_sctp_association *sctp) { if(sctp == NULL) return -1; struct socket *sock = sctp->sock; struct sockaddr_conn sconn; /* Operating as client */ JANUS_LOG(LOG_VERB, "[%"SCNu64"] Connecting the SCTP association\n", sctp->handle_id); memset(&sconn, 0, sizeof(struct sockaddr_conn)); sconn.sconn_family = AF_CONN; sconn.sconn_port = htons(sctp->remote_port); sconn.sconn_addr = (void *)sctp; #ifdef HAVE_SCONN_LEN sconn.sconn_len = sizeof(struct sockaddr_conn); #endif sctp->ready = TRUE; if(usrsctp_connect(sock, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] Error connecting to SCTP server at port %"SCNu16"\n", sctp->handle_id, sctp->remote_port); return -1; } JANUS_LOG(LOG_INFO, "[%"SCNu64"] Connected to the DataChannel peer\n", sctp->handle_id); janus_mutex_lock(&sctp->mutex); sctp->sock = sock; janus_mutex_unlock(&sctp->mutex); return 0; }
void janus_serial_create_session(janus_plugin_session *handle, int *error) { if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) { *error = -1; return; } janus_serial_session *session = (janus_serial_session *)calloc(1, sizeof(janus_serial_session)); if(session == NULL) { JANUS_LOG(LOG_FATAL, "Memory error!\n"); *error = -2; return; } session->handle = handle; session->has_audio = FALSE; session->has_video = FALSE; session->audio_active = TRUE; session->video_active = TRUE; session->bitrate = 0; /* No limit */ session->destroyed = 0; g_atomic_int_set(&session->hangingup, 0); handle->plugin_handle = session; janus_mutex_lock(&sessions_mutex); g_hash_table_insert(sessions, handle, session); janus_mutex_unlock(&sessions_mutex); return; }
void *janus_echotest_watchdog(void *data) { JANUS_LOG(LOG_INFO, "Echotest watchdog started\n"); gint64 now = 0; while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) { janus_mutex_lock(&sessions_mutex); /* Iterate on all the sessions */ now = janus_get_monotonic_time(); if(old_sessions != NULL) { GList *sl = old_sessions; JANUS_LOG(LOG_VERB, "Checking %d old sessions\n", g_list_length(old_sessions)); while(sl) { janus_echotest_session *session = (janus_echotest_session *)sl->data; if(!session) { sl = sl->next; continue; } if(now-session->destroyed >= 5*G_USEC_PER_SEC) { /* We're lazy and actually get rid of the stuff only after a few seconds */ GList *rm = sl->next; old_sessions = g_list_delete_link(old_sessions, sl); sl = rm; session->handle = NULL; g_free(session); session = NULL; continue; } sl = sl->next; } } janus_mutex_unlock(&sessions_mutex); g_usleep(2000000); } JANUS_LOG(LOG_INFO, "EchoTest watchdog stopped\n"); return NULL; }
void janus_videocall_destroy_session(janus_plugin_session *handle, int *error) { if(stopping || !initialized) { *error = -1; return; } janus_videocall_session *session = (janus_videocall_session *)handle->plugin_handle; if(!session) { JANUS_LOG(LOG_ERR, "No session associated with this handle...\n"); *error = -2; return; } if(session->destroy) { JANUS_LOG(LOG_VERB, "Session already destroyed...\n"); return; } JANUS_LOG(LOG_VERB, "Removing user %s session...\n", session->username ? session->username : "******"); janus_videocall_hangup_media(handle); if(session->username != NULL) { janus_mutex_lock(&sessions_mutex); int res = g_hash_table_remove(sessions, (gpointer)session->username); JANUS_LOG(LOG_VERB, " -- Removed: %d\n", res); janus_mutex_unlock(&sessions_mutex); } /* Cleaning up and removing the session is done in a lazy way */ session->destroy = TRUE; return; }
void janus_pfunix_session_over(void *transport, guint64 session_id, gboolean timeout) { /* We only care if it's a timeout: if so, close the connection */ if(transport == NULL || !timeout) return; /* FIXME Should we really close the connection in case of a timeout? */ janus_pfunix_client *client = (janus_pfunix_client *)transport; janus_mutex_lock(&clients_mutex); if(g_hash_table_lookup(clients, client) != NULL) { client->session_timeout = TRUE; if(client->fd != -1) { /* Shutdown the client socket */ shutdown(client->fd, SHUT_WR); } else { /* Destroy the client */ g_hash_table_remove(clients_by_path, client->addr.sun_path); g_hash_table_remove(clients, client); if(client->messages != NULL) { char *response = NULL; while((response = g_async_queue_try_pop(client->messages)) != NULL) { g_free(response); } g_async_queue_unref(client->messages); } g_free(client); } } janus_mutex_unlock(&clients_mutex); }
void janus_videocall_hangup_media(janus_plugin_session *handle) { JANUS_LOG(LOG_INFO, "No WebRTC media anymore\n"); if(stopping || !initialized) return; janus_videocall_session *session = (janus_videocall_session *)handle->plugin_handle; if(!session) { JANUS_LOG(LOG_ERR, "No session associated with this handle...\n"); return; } if(session->destroy) return; janus_mutex_lock(&sessions_mutex); if(session->peer) { /* Send event to our peer too */ json_t *call = json_object(); json_object_set_new(call, "videocall", json_string("event")); json_t *calling = json_object(); json_object_set_new(calling, "event", json_string("hangup")); json_object_set_new(calling, "username", json_string(session->username)); json_object_set_new(calling, "reason", json_string("Remote hangup")); json_object_set_new(call, "result", calling); char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER); json_decref(call); JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text); int ret = gateway->push_event(session->peer->handle, &janus_videocall_plugin, NULL, call_text, NULL, NULL); JANUS_LOG(LOG_VERB, " >> %d (%s)\n", ret, janus_get_api_error(ret)); g_free(call_text); } session->peer = NULL; /* Reset controls */ session->audio_active = TRUE; session->video_active = TRUE; session->bitrate = 0; janus_mutex_unlock(&sessions_mutex); }
static void janus_dtls_cb_openssl_lock(int mode, int type, const char *file, int line) { if((mode & CRYPTO_LOCK)) { janus_mutex_lock(&janus_dtls_locks[type]); } else { janus_mutex_unlock(&janus_dtls_locks[type]); } }
void janus_source_destroy_session(janus_plugin_session *handle, int *error) { if (g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) { *error = -1; return; } janus_source_session *session = (janus_source_session *)handle->plugin_handle; if (!session) { JANUS_LOG(LOG_ERR, "No session associated with this handle...\n"); *error = -2; return; } JANUS_LOG(LOG_VERB, "Removing Source Plugin session...\n"); janus_source_close_session(session); janus_mutex_lock(&sessions_mutex); if (!session->destroyed) { session->destroyed = janus_get_monotonic_time(); g_hash_table_remove(sessions, handle); /* Cleaning up and removing the session is done in a lazy way */ old_sessions = g_list_append(old_sessions, session); } janus_mutex_unlock(&sessions_mutex); return; }
void janus_serial_destroy(void) { if(!g_atomic_int_get(&initialized)) return; g_atomic_int_set(&stopping, 1); if(handler_thread != NULL) { g_thread_join(handler_thread); handler_thread = NULL; } if(watchdog != NULL) { g_thread_join(watchdog); watchdog = NULL; } /* FIXME We should destroy the sessions cleanly */ janus_mutex_lock(&sessions_mutex); g_hash_table_destroy(sessions); janus_mutex_unlock(&sessions_mutex); g_async_queue_unref(messages); messages = NULL; sessions = NULL; g_atomic_int_set(&initialized, 0); g_atomic_int_set(&stopping, 0); JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SERIAL_NAME); }
void *janus_source_keepalive(void *data) { JANUS_LOG(LOG_INFO, "SourcePlugin keepalive started\n"); CURL *curl = curl_init(); gchar *body_str = g_strdup_printf("{\"pid\": \"%s\", \"dly\": \"%lu\"}", PID, (uint64_t)(keepalive_interval/G_USEC_PER_SEC)); json_t *res_json_object = NULL; while (g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) { janus_mutex_lock(&keepalive_mutex); gboolean retCode = curl_request(curl, keepalive_service_url, body_str, "POST", &res_json_object); if (retCode != TRUE) { JANUS_LOG(LOG_ERR, "Could not send the request to the server.\n"); }else{ if (json_is_object(res_json_object)) json_decref(res_json_object); else JANUS_LOG(LOG_ERR, "Not valid json object.\n"); } janus_mutex_unlock(&keepalive_mutex); g_usleep(keepalive_interval); } if (body_str) { g_free(body_str); } curl_cleanup(curl); JANUS_LOG(LOG_INFO, "SourcePlugin keepalive stopped\n"); return NULL; }
void janus_videocall_hangup_media(janus_plugin_session *handle) { JANUS_LOG(LOG_INFO, "No WebRTC media anymore\n"); if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) return; janus_videocall_session *session = (janus_videocall_session *)handle->plugin_handle; if(!session) { JANUS_LOG(LOG_ERR, "No session associated with this handle...\n"); return; } if(session->destroyed) return; if(g_atomic_int_add(&session->hangingup, 1)) return; /* Get rid of the recorders, if available */ janus_mutex_lock(&session->rec_mutex); if(session->arc) { janus_recorder_close(session->arc); JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", session->arc->filename ? session->arc->filename : "??"); janus_recorder_free(session->arc); } session->arc = NULL; if(session->vrc) { janus_recorder_close(session->vrc); JANUS_LOG(LOG_INFO, "Closed video recording %s\n", session->vrc->filename ? session->vrc->filename : "??"); janus_recorder_free(session->vrc); } session->vrc = NULL; janus_mutex_unlock(&session->rec_mutex); if(session->peer) { /* Send event to our peer too */ json_t *call = json_object(); json_object_set_new(call, "videocall", json_string("event")); json_t *calling = json_object(); json_object_set_new(calling, "event", json_string("hangup")); json_object_set_new(calling, "username", json_string(session->username)); json_object_set_new(calling, "reason", json_string("Remote WebRTC hangup")); json_object_set_new(call, "result", calling); gateway->close_pc(session->peer->handle); int ret = gateway->push_event(session->peer->handle, &janus_videocall_plugin, NULL, call, NULL); JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret)); json_decref(call); /* Also notify event handlers */ if(notify_events && gateway->events_is_enabled()) { json_t *info = json_object(); json_object_set_new(info, "event", json_string("hangup")); json_object_set_new(info, "reason", json_string("Remote WebRTC hangup")); gateway->notify_event(&janus_videocall_plugin, session->peer->handle, info); } } session->peer = NULL; /* Reset controls */ session->has_audio = FALSE; session->has_video = FALSE; session->audio_active = TRUE; session->video_active = TRUE; session->bitrate = 0; }
void janus_sctp_data_from_dtls(janus_sctp_association *sctp, char *buf, int len) { if(sctp == NULL || sctp->dtls == NULL || buf == NULL || len <= 0) return; JANUS_LOG(LOG_VERB, "[%"SCNu64"] Data from DTLS to SCTP stack: %d bytes\n", sctp->handle_id, len); janus_mutex_lock(&sctp->mutex); if(sctp->in_messages != NULL) g_queue_push_tail(sctp->in_messages, janus_sctp_message_create(buf, len)); janus_mutex_unlock(&sctp->mutex); }
void janus_turnrest_deinit(void) { /* Cleanup the libcurl initialization */ curl_global_cleanup(); janus_mutex_lock(&api_mutex); if(api_server != NULL) g_free((char *)api_server); if(api_key != NULL) g_free((char *)api_key); janus_mutex_unlock(&api_mutex); }
void janus_sctp_association_destroy(janus_sctp_association *sctp) { if(sctp == NULL) return; JANUS_LOG(LOG_INFO, "[%"SCNu64"] Destroying SCTP association\n", sctp->handle_id); usrsctp_deregister_address(sctp); usrsctp_shutdown(sctp->sock, SHUT_RDWR); usrsctp_close(sctp->sock); janus_mutex_lock(&sctp->mutex); sctp->dtls = NULL; /* This will get rid of the thread */ janus_mutex_unlock(&sctp->mutex); }
static void janus_websockets_allow_address(const char *ip, gboolean admin) { if(ip == NULL) return; /* Is this an IP or an interface? */ janus_mutex_lock(&access_list_mutex); if(!admin) janus_websockets_access_list = g_list_append(janus_websockets_access_list, (gpointer)ip); else janus_websockets_admin_access_list = g_list_append(janus_websockets_admin_access_list, (gpointer)ip); janus_mutex_unlock(&access_list_mutex); }
int janus_sctp_data_to_dtls(void *instance, void *buffer, size_t length, uint8_t tos, uint8_t set_df) { janus_sctp_association *sctp = (janus_sctp_association *)instance; if(sctp == NULL || sctp->dtls == NULL) return -1; JANUS_LOG(LOG_VERB, "[%"SCNu64"] Data from SCTP to DTLS stack: %zu bytes\n", sctp->handle_id, length); janus_mutex_lock(&sctp->mutex); if(sctp->out_messages != NULL) g_queue_push_tail(sctp->out_messages, janus_sctp_message_create(buffer, length)); janus_mutex_unlock(&sctp->mutex); return 0; }
int janus_pfunix_send_message(void *transport, void *request_id, gboolean admin, json_t *message) { if(message == NULL) return -1; if(transport == NULL) { json_decref(message); return -1; } /* Make sure this is related to a still valid Unix Sockets session */ janus_pfunix_client *client = (janus_pfunix_client *)transport; janus_mutex_lock(&clients_mutex); if(g_hash_table_lookup(clients, client) == NULL) { janus_mutex_unlock(&clients_mutex); JANUS_LOG(LOG_WARN, "Outgoing message for invalid client %p\n", client); json_decref(message); message = NULL; return -1; } janus_mutex_unlock(&clients_mutex); /* Convert to string */ char *payload = json_dumps(message, json_format); json_decref(message); if(client->fd != -1) { /* SOCK_SEQPACKET, enqueue the packet and have poll tell us when it's time to send it */ g_async_queue_push(client->messages, payload); /* Notify the thread there's data to send */ int res = 0; do { res = write(write_fd[1], "x", 1); } while(res == -1 && errno == EINTR); } else { /* SOCK_DGRAM, send it right away */ int res = 0; do { res = sendto(client->admin ? admin_pfd : pfd, payload, strlen(payload), 0, (struct sockaddr *)&client->addr, sizeof(struct sockaddr_un)); } while(res == -1 && errno == EINTR); free(payload); } return 0; }
int janus_websockets_send_message(janus_transport_session *transport, void *request_id, gboolean admin, json_t *message) { if(message == NULL) return -1; if(transport == NULL || g_atomic_int_get(&transport->destroyed)) { json_decref(message); return -1; } janus_mutex_lock(&transport->mutex); janus_websockets_client *client = (janus_websockets_client *)transport->transport_p; if(!client) { json_decref(message); janus_mutex_unlock(&transport->mutex); return -1; } /* Convert to string and enqueue */ char *payload = json_dumps(message, json_format); g_async_queue_push(client->messages, payload); lws_callback_on_writable(client->wsi); janus_mutex_unlock(&transport->mutex); json_decref(message); return 0; }
void *janus_rmq_out_thread(void *data) { if(rmq_client == NULL) { JANUS_LOG(LOG_ERR, "No RabbitMQ connection??\n"); return NULL; } JANUS_LOG(LOG_VERB, "Joining RabbitMQ out thread\n"); while(!rmq_client->destroy && !g_atomic_int_get(&stopping)) { /* We send messages from here as well, not only notifications */ janus_rabbitmq_response *response = g_async_queue_pop(rmq_client->messages); if(response == NULL) continue; if(response == &exit_message) break; if(!rmq_client->destroy && !g_atomic_int_get(&stopping) && response->payload) { janus_mutex_lock(&rmq_client->mutex); /* Gotcha! Convert json_t to string */ char *payload_text = json_dumps(response->payload, json_format); json_decref(response->payload); response->payload = NULL; JANUS_LOG(LOG_VERB, "Sending %s API message to RabbitMQ (%zu bytes)...\n", response->admin ? "Admin" : "Janus", strlen(payload_text)); JANUS_LOG(LOG_VERB, "%s\n", payload_text); amqp_basic_properties_t props; props._flags = 0; props._flags |= AMQP_BASIC_REPLY_TO_FLAG; props.reply_to = amqp_cstring_bytes("Janus"); if(response->correlation_id) { props._flags |= AMQP_BASIC_CORRELATION_ID_FLAG; props.correlation_id = amqp_cstring_bytes(response->correlation_id); } props._flags |= AMQP_BASIC_CONTENT_TYPE_FLAG; props.content_type = amqp_cstring_bytes("application/json"); amqp_bytes_t message = amqp_cstring_bytes(payload_text); int status = amqp_basic_publish(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->janus_exchange, response->admin ? rmq_client->from_janus_admin_queue : rmq_client->from_janus_queue, 0, 0, &props, message); if(status != AMQP_STATUS_OK) { JANUS_LOG(LOG_ERR, "Error publishing... %d, %s\n", status, amqp_error_string2(status)); } g_free(response->correlation_id); response->correlation_id = NULL; free(payload_text); payload_text = NULL; g_free(response); response = NULL; janus_mutex_unlock(&rmq_client->mutex); } } g_async_queue_unref(rmq_client->messages); JANUS_LOG(LOG_INFO, "Leaving RabbitMQ out thread\n"); return NULL; }
void janus_pfunix_session_over(janus_transport_session *transport, guint64 session_id, gboolean timeout, gboolean claimed) { /* We only care if it's a timeout: if so, close the connection */ if(transport == NULL || transport->transport_p == NULL || !timeout) return; /* FIXME Should we really close the connection in case of a timeout? */ janus_pfunix_client *client = (janus_pfunix_client *)transport->transport_p; janus_mutex_lock(&clients_mutex); if(g_hash_table_lookup(clients, client) != NULL) { client->session_timeout = TRUE; /* Notify the thread about this */ int res = 0; do { res = write(write_fd[1], "x", 1); } while(res == -1 && errno == EINTR); } janus_mutex_unlock(&clients_mutex); }
void janus_turnrest_set_backend(const char *server, const char *key) { janus_mutex_lock(&api_mutex); /* Get rid of the old values first */ if(api_server != NULL) g_free((char *)api_server); api_server = NULL; if(api_key != NULL) g_free((char *)api_key); api_key = NULL; if(server != NULL) { /* Set a new server now */ api_server = g_strdup(server); if(key != NULL) api_key = g_strdup(key); } janus_mutex_unlock(&api_mutex); }
void janus_streaming_create_session(janus_plugin_session *handle, int *error) { if(stopping || !initialized) { *error = -1; return; } janus_streaming_session *session = (janus_streaming_session *)calloc(1, sizeof(janus_streaming_session)); if(session == NULL) { JANUS_LOG(LOG_FATAL, "Memory error!\n"); *error = -2; return; } session->handle = handle; session->mountpoint = NULL; /* This will happen later */ session->started = FALSE; /* This will happen later */ handle->plugin_handle = session; janus_mutex_lock(&sessions_mutex); g_hash_table_insert(sessions, handle, session); janus_mutex_unlock(&sessions_mutex); return; }
void janus_streaming_destroy_session(janus_plugin_session *handle, int *error) { if(stopping || !initialized) { *error = -1; return; } janus_streaming_session *session = (janus_streaming_session *)handle->plugin_handle; if(!session) { JANUS_LOG(LOG_ERR, "No session associated with this handle...\n"); *error = -2; return; } JANUS_LOG(LOG_VERB, "Removing streaming session...\n"); if(session->mountpoint) { session->mountpoint->listeners = g_list_remove_all(session->mountpoint->listeners, session); } janus_mutex_lock(&sessions_mutex); g_hash_table_remove(sessions, handle); janus_mutex_unlock(&sessions_mutex); /* Cleaning up and removing the session is done in a lazy way */ session->destroy = TRUE; return; }
static void janus_websockets_destroy_client( janus_websockets_client *ws_client, struct lws *wsi, const char *log_prefix) { if(!ws_client || !g_atomic_int_compare_and_exchange(&ws_client->destroyed, 0, 1)) return; /* Cleanup */ janus_mutex_lock(&ws_client->ts->mutex); JANUS_LOG(LOG_INFO, "[%s-%p] Destroying WebSocket client\n", log_prefix, wsi); ws_client->wsi = NULL; /* Notify handlers about this transport being gone */ if(notify_events && gateway->events_is_enabled()) { json_t *info = json_object(); json_object_set_new(info, "event", json_string("disconnected")); gateway->notify_event(&janus_websockets_transport, ws_client->ts, info); } /* Notify core */ gateway->transport_gone(&janus_websockets_transport, ws_client->ts); ws_client->ts->transport_p = NULL; /* Remove messages queue too, if needed */ if(ws_client->messages != NULL) { char *response = NULL; while((response = g_async_queue_try_pop(ws_client->messages)) != NULL) { g_free(response); } g_async_queue_unref(ws_client->messages); } /* ... and the shared buffers */ g_free(ws_client->incoming); ws_client->incoming = NULL; g_free(ws_client->buffer); ws_client->buffer = NULL; ws_client->buflen = 0; ws_client->bufpending = 0; ws_client->bufoffset = 0; janus_mutex_unlock(&ws_client->ts->mutex); janus_transport_session_destroy(ws_client->ts); }
void janus_source_create_session(janus_plugin_session *handle, int *error) { if (g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) { *error = -1; return; } janus_source_session *session = (janus_source_session *)g_malloc0(sizeof(janus_source_session)); session->handle = handle; session->audio_active = TRUE; session->video_active = TRUE; session->rtsp_url = NULL; session->db_entry_session_id = NULL; session->id = NULL; session->status_service_url=status_service_url; session->keepalive_service_url=keepalive_service_url; session->pid=PID; session->curl_handle=curl_handle; for (int stream = 0; stream < JANUS_SOURCE_STREAM_MAX; stream++) { session->codec[stream] = IDILIA_CODEC_INVALID; session->codec_pt[stream] = -1; } session->bitrate = 0; /* No limit */ session->destroyed = 0; g_atomic_int_set(&session->hangingup, 0); handle->plugin_handle = session; janus_mutex_lock(&sessions_mutex); g_hash_table_insert(sessions, handle, session); janus_mutex_unlock(&sessions_mutex); return; }