Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
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);
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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);
}
Esempio n. 20
0
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);
}
Esempio n. 21
0
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;
}
Esempio n. 22
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;
}
Esempio n. 23
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;
}
Esempio n. 24
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;
}
Esempio n. 25
0
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);
}
Esempio n. 26
0
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;
}
Esempio n. 29
0
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;
}