[Pkg-voip-commits] [janus] 56/163: Implemented way to edit some room properties dynamically in AudioBridge, VideoRoom and TextRoom (see #939)
Jonas Smedegaard
dr at jones.dk
Sat Oct 28 01:22:09 UTC 2017
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/0.2.5-1
in repository janus.
commit e2fff24cd07253a831faaad17bb551702a997435
Author: Lorenzo Miniero <lminiero at gmail.com>
Date: Wed Aug 2 14:00:03 2017 +0200
Implemented way to edit some room properties dynamically in AudioBridge, VideoRoom and TextRoom (see #939)
---
plugins/janus_audiobridge.c | 170 +++++++++++++++++++++++++++++++++++++++++---
plugins/janus_textroom.c | 127 ++++++++++++++++++++++++++++++++-
plugins/janus_videoroom.c | 142 +++++++++++++++++++++++++++++++++++-
3 files changed, 426 insertions(+), 13 deletions(-)
diff --git a/plugins/janus_audiobridge.c b/plugins/janus_audiobridge.c
index 83d1c83..00cf23a 100644
--- a/plugins/janus_audiobridge.c
+++ b/plugins/janus_audiobridge.c
@@ -39,11 +39,12 @@ record_file = /path/to/recording.wav (where to save the recording)
* (invalid JSON, invalid request) which will always result in a
* synchronous error response even for asynchronous requests.
*
- * \c create , \c destroy , \c exists, \c allowed, \c kick, \c list,
+ * \c create , \c edit , \c destroy , \c exists, \c allowed, \c kick, \c list,
* \c listparticipants and \c resetdecoder are synchronous requests,
* which means you'll get a response directly within the context of the
* transaction. \c create allows you to create a new audio conference bridge
- * dynamically, as an alternative to using the configuration file;
+ * dynamically, as an alternative to using the configuration file; \c edit
+ * allows you to dynamically edit some room properties (e.g., the PIN);
* \c destroy removes an audio conference bridge and destroys it, kicking
* all the users out as part of the process; \c exists allows you to
* check whether a specific audio conference exists; \c allowed allows
@@ -125,6 +126,36 @@ record_file = /path/to/recording.wav (where to save the recording)
* include the correct \c admin_key value in an "admin_key" property
* will succeed, and will be rejected otherwise.
*
+ * Once a room has been created, you can still edit some (but not all)
+ * of its properties using the \c edit request. This allows you to modify
+ * the room description, secret, pin and whether it's private or not: you
+ * won't be able to modify other more static properties, like the room ID,
+ * the sampling rate, the extensions-related stuff and so on. If you're
+ * interested in changing the ACL, instead, check the \c allowed message.
+ * An \c edit request has to be formatted as follows:
+ *
+\verbatim
+{
+ "request" : "edit",
+ "room" : <unique numeric ID of the room to destroy>,
+ "secret" : "<room secret, mandatory if configured>",
+ "new_description" : "<new pretty name of the room, optional>",
+ "new_secret" : "<new password required to edit/destroy the room, optional>",
+ "new_pin" : "<new password required to join the room, optional>",
+ "new_is_private" : <true|false, whether the room should appear in a list request>,
+ "permanent" : <true|false, whether the room should be also removed from the config file, default false>
+}
+\endverbatim
+ *
+ * A successful destruction procedure will result in an \c edited response:
+ *
+\verbatim
+{
+ "audiobridge" : "edited",
+ "room" : <unique numeric ID>
+}
+\endverbatim
+ *
* On the other hand, \c destroy can be used to destroy an existing audio
* room, whether created dynamically or statically, and has to be
* formatted as follows:
@@ -632,6 +663,15 @@ static struct janus_json_parameter create_parameters[] = {
{"audio_level_average", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
{"room", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}
};
+static struct janus_json_parameter edit_parameters[] = {
+ {"room", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE},
+ {"secret", JSON_STRING, 0},
+ {"new_description", JSON_STRING, 0},
+ {"new_secret", JSON_STRING, 0},
+ {"new_pin", JSON_STRING, 0},
+ {"new_is_private", JANUS_JSON_BOOL, 0},
+ {"permanent", JANUS_JSON_BOOL, 0}
+};
static struct janus_json_parameter destroy_parameters[] = {
{"room", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE},
{"permanent", JANUS_JSON_BOOL, 0}
@@ -1625,16 +1665,124 @@ struct janus_plugin_result *janus_audiobridge_handle_message(janus_plugin_sessio
response = json_object();
json_object_set_new(response, "audiobridge", json_string("created"));
json_object_set_new(response, "room", json_integer(audiobridge->room_id));
+ json_object_set_new(response, "permanent", save ? json_true() : json_false());
/* Also notify event handlers */
if(notify_events && gateway->events_is_enabled()) {
json_t *info = json_object();
json_object_set_new(info, "event", json_string("created"));
json_object_set_new(info, "room", json_integer(audiobridge->room_id));
- json_object_set_new(info, "permanent", save ? json_true() : json_false());
gateway->notify_event(&janus_audiobridge_plugin, session->handle, info);
}
janus_mutex_unlock(&rooms_mutex);
goto plugin_response;
+ } else if(!strcasecmp(request_text, "edit")) {
+ JANUS_LOG(LOG_VERB, "Attempt to edit an existing audiobridge room\n");
+ JANUS_VALIDATE_JSON_OBJECT(root, edit_parameters,
+ error_code, error_cause, TRUE,
+ JANUS_AUDIOBRIDGE_ERROR_MISSING_ELEMENT, JANUS_AUDIOBRIDGE_ERROR_INVALID_ELEMENT);
+ if(error_code != 0)
+ goto plugin_response;
+ /* We only allow for a limited set of properties to be edited */
+ json_t *room = json_object_get(root, "room");
+ json_t *desc = json_object_get(root, "new_description");
+ json_t *secret = json_object_get(root, "new_secret");
+ json_t *pin = json_object_get(root, "new_pin");
+ json_t *is_private = json_object_get(root, "new_is_private");
+ json_t *permanent = json_object_get(root, "permanent");
+ gboolean save = permanent ? json_is_true(permanent) : FALSE;
+ if(save && config == NULL) {
+ JANUS_LOG(LOG_ERR, "No configuration file, can't edit room permanently\n");
+ error_code = JANUS_AUDIOBRIDGE_ERROR_UNKNOWN_ERROR;
+ g_snprintf(error_cause, 512, "No configuration file, can't edit room permanently");
+ goto plugin_response;
+ }
+ guint64 room_id = json_integer_value(room);
+ janus_mutex_lock(&rooms_mutex);
+ janus_audiobridge_room *audiobridge = g_hash_table_lookup(rooms, &room_id);
+ if(audiobridge == NULL) {
+ janus_mutex_unlock(&rooms_mutex);
+ JANUS_LOG(LOG_ERR, "No such room (%"SCNu64")\n", room_id);
+ error_code = JANUS_AUDIOBRIDGE_ERROR_NO_SUCH_ROOM;
+ g_snprintf(error_cause, 512, "No such room (%"SCNu64")", room_id);
+ goto plugin_response;
+ }
+ janus_mutex_lock(&audiobridge->mutex);
+ /* A secret may be required for this action */
+ JANUS_CHECK_SECRET(audiobridge->room_secret, root, "secret", error_code, error_cause,
+ JANUS_AUDIOBRIDGE_ERROR_MISSING_ELEMENT, JANUS_AUDIOBRIDGE_ERROR_INVALID_ELEMENT, JANUS_AUDIOBRIDGE_ERROR_UNAUTHORIZED);
+ if(error_code != 0) {
+ janus_mutex_unlock(&audiobridge->mutex);
+ janus_mutex_unlock(&rooms_mutex);
+ goto plugin_response;
+ }
+ /* Edit the room properties that were provided */
+ if(desc != NULL && strlen(json_string_value(desc)) > 0) {
+ char *old_description = audiobridge->room_name;
+ char *new_description = g_strdup(json_string_value(desc));
+ audiobridge->room_name = new_description;
+ g_free(old_description);
+ }
+ if(is_private)
+ audiobridge->is_private = json_is_true(is_private);
+ if(secret && strlen(json_string_value(secret)) > 0) {
+ char *old_secret = audiobridge->room_secret;
+ char *new_secret = g_strdup(json_string_value(secret));
+ audiobridge->room_secret = new_secret;
+ g_free(old_secret);
+ }
+ if(pin && strlen(json_string_value(pin)) > 0) {
+ char *old_pin = audiobridge->room_pin;
+ char *new_pin = g_strdup(json_string_value(pin));
+ audiobridge->room_pin = new_pin;
+ g_free(old_pin);
+ }
+ if(save) {
+ /* This change is permanent: save to the configuration file too
+ * FIXME: We should check if anything fails... */
+ JANUS_LOG(LOG_VERB, "Modifying room %"SCNu64" permanently in config file\n", room_id);
+ janus_mutex_lock(&config_mutex);
+ char cat[BUFSIZ], value[BUFSIZ];
+ /* The room ID is the category */
+ g_snprintf(cat, BUFSIZ, "%"SCNu64, room_id);
+ /* Remove the old category first */
+ janus_config_remove_category(config, cat);
+ /* Now write the room details again */
+ janus_config_add_category(config, cat);
+ janus_config_add_item(config, cat, "description", audiobridge->room_name);
+ if(audiobridge->is_private)
+ janus_config_add_item(config, cat, "is_private", "yes");
+ g_snprintf(value, BUFSIZ, "%"SCNu32, audiobridge->sampling_rate);
+ janus_config_add_item(config, cat, "sampling_rate", value);
+ if(audiobridge->room_secret)
+ janus_config_add_item(config, cat, "secret", audiobridge->room_secret);
+ if(audiobridge->room_pin)
+ janus_config_add_item(config, cat, "pin", audiobridge->room_pin);
+ if(audiobridge->record_file) {
+ janus_config_add_item(config, cat, "record", "yes");
+ janus_config_add_item(config, cat, "record_file", audiobridge->record_file);
+ }
+ /* Save modified configuration */
+ if(janus_config_save(config, config_folder, JANUS_AUDIOBRIDGE_PACKAGE) < 0)
+ save = FALSE; /* This will notify the user the room changes are not permanent */
+ janus_mutex_unlock(&config_mutex);
+ }
+ /* Prepare response/notification */
+ response = json_object();
+ json_object_set_new(response, "audiobridge", json_string("edited"));
+ json_object_set_new(response, "room", json_integer(audiobridge->room_id));
+ json_object_set_new(response, "permanent", save ? json_true() : json_false());
+ /* Also notify event handlers */
+ if(notify_events && gateway->events_is_enabled()) {
+ json_t *info = json_object();
+ json_object_set_new(info, "event", json_string("edited"));
+ json_object_set_new(info, "room", json_integer(room_id));
+ gateway->notify_event(&janus_audiobridge_plugin, session->handle, info);
+ }
+ janus_mutex_unlock(&audiobridge->mutex);
+ janus_mutex_unlock(&rooms_mutex);
+ /* Done */
+ JANUS_LOG(LOG_VERB, "Audiobridge room edited\n");
+ goto plugin_response;
} else if(!strcasecmp(request_text, "destroy")) {
JANUS_LOG(LOG_VERB, "Attempt to destroy an existing audiobridge room\n");
JANUS_VALIDATE_JSON_OBJECT(root, destroy_parameters,
@@ -1682,13 +1830,14 @@ struct janus_plugin_result *janus_audiobridge_handle_message(janus_plugin_sessio
g_snprintf(cat, BUFSIZ, "%"SCNu64, room_id);
janus_config_remove_category(config, cat);
/* Save modified configuration */
- janus_config_save(config, config_folder, JANUS_AUDIOBRIDGE_PACKAGE);
+ if(janus_config_save(config, config_folder, JANUS_AUDIOBRIDGE_PACKAGE) < 0)
+ save = FALSE; /* This will notify the user the room destruction is not permanent */
janus_mutex_unlock(&config_mutex);
}
/* Prepare response/notification */
- response = json_object();
- json_object_set_new(response, "audiobridge", json_string("destroyed"));
- json_object_set_new(response, "room", json_integer(room_id));
+ json_t *destroyed = json_object();
+ json_object_set_new(destroyed, "audiobridge", json_string("destroyed"));
+ json_object_set_new(destroyed, "room", json_integer(room_id));
/* Notify all participants that the fun is over, and that they'll be kicked */
JANUS_LOG(LOG_VERB, "Notifying all participants\n");
GHashTableIter iter;
@@ -1698,7 +1847,7 @@ struct janus_plugin_result *janus_audiobridge_handle_message(janus_plugin_sessio
janus_audiobridge_participant *p = value;
if(p && p->session) {
p->room = NULL;
- int ret = gateway->push_event(p->session->handle, &janus_audiobridge_plugin, NULL, response, NULL);
+ int ret = gateway->push_event(p->session->handle, &janus_audiobridge_plugin, NULL, destroyed, NULL);
JANUS_LOG(LOG_VERB, " >> %d (%s)\n", ret, janus_get_api_error(ret));
/* Get rid of queued packets */
janus_mutex_lock(&p->qmutex);
@@ -1719,6 +1868,7 @@ struct janus_plugin_result *janus_audiobridge_handle_message(janus_plugin_sessio
janus_mutex_unlock(&p->qmutex);
}
}
+ json_decref(destroyed);
/* Also notify event handlers */
if(notify_events && gateway->events_is_enabled()) {
json_t *info = json_object();
@@ -1732,6 +1882,10 @@ struct janus_plugin_result *janus_audiobridge_handle_message(janus_plugin_sessio
janus_mutex_unlock(&rooms_mutex);
g_thread_join(audiobridge->thread);
/* Done */
+ response = json_object();
+ json_object_set_new(response, "audiobridge", json_string("destroyed"));
+ json_object_set_new(response, "room", json_integer(room_id));
+ json_object_set_new(response, "permanent", save ? json_true() : json_false());
JANUS_LOG(LOG_VERB, "Audiobridge room destroyed\n");
goto plugin_response;
} else if(!strcasecmp(request_text, "list")) {
diff --git a/plugins/janus_textroom.c b/plugins/janus_textroom.c
index 0bc79c8..704589f 100644
--- a/plugins/janus_textroom.c
+++ b/plugins/janus_textroom.c
@@ -15,7 +15,7 @@
* a "setup" message, by which the user initializes the PeerConnection
* itself. Apart from that, all other messages can be exchanged directly
* via Data Channels. For room management purposes, though, requests like
- * "create", "destroy", "list" and "exists" are available through the
+ * "create", "edit", "destroy", "list" and "exists" are available through the
* Janus API as well: notice that in this case you'll have to use "request"
* and not "textroom" as the name of the request.
*
@@ -142,6 +142,7 @@ static struct janus_json_parameter adminkey_parameters[] = {
{"admin_key", JSON_STRING, JANUS_JSON_PARAM_REQUIRED}
};
static struct janus_json_parameter create_parameters[] = {
+ {"room", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
{"description", JSON_STRING, 0},
{"secret", JSON_STRING, 0},
{"pin", JSON_STRING, 0},
@@ -149,6 +150,14 @@ static struct janus_json_parameter create_parameters[] = {
{"is_private", JANUS_JSON_BOOL, 0},
{"allowed", JSON_ARRAY, 0}
};
+static struct janus_json_parameter edit_parameters[] = {
+ {"room", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE},
+ {"description", JSON_STRING, 0},
+ {"secret", JSON_STRING, 0},
+ {"pin", JSON_STRING, 0},
+ {"post", JSON_STRING, 0},
+ {"is_private", JANUS_JSON_BOOL, 0}
+};
static struct janus_json_parameter allowed_parameters[] = {
{"room", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE},
{"secret", JSON_STRING, 0},
@@ -695,6 +704,7 @@ struct janus_plugin_result *janus_textroom_handle_message(janus_plugin_session *
if(!strcasecmp(request_text, "list")
|| !strcasecmp(request_text, "exists")
|| !strcasecmp(request_text, "create")
+ || !strcasecmp(request_text, "edit")
|| !strcasecmp(request_text, "destroy")) {
/* These requests typically only belong to the datachannel
* messaging, but for admin purposes we might use them on
@@ -1559,6 +1569,116 @@ janus_plugin_result *janus_textroom_handle_incoming_request(janus_plugin_session
json_object_set_new(reply, "room", json_integer(room_id));
json_object_set_new(reply, "exists", room_exists ? json_true() : json_false());
}
+ } else if(!strcasecmp(request_text, "edit")) {
+ JANUS_VALIDATE_JSON_OBJECT(root, edit_parameters,
+ error_code, error_cause, TRUE,
+ JANUS_TEXTROOM_ERROR_MISSING_ELEMENT, JANUS_TEXTROOM_ERROR_INVALID_ELEMENT);
+ if(error_code != 0)
+ goto msg_response;
+ /* We only allow for a limited set of properties to be edited */
+ json_t *room = json_object_get(root, "room");
+ json_t *desc = json_object_get(root, "new_description");
+ json_t *secret = json_object_get(root, "new_secret");
+ json_t *is_private = json_object_get(root, "new_is_private");
+ json_t *pin = json_object_get(root, "new_pin");
+ json_t *post = json_object_get(root, "new_post");
+ json_t *permanent = json_object_get(root, "permanent");
+ gboolean save = permanent ? json_is_true(permanent) : FALSE;
+ if(save && config == NULL) {
+ JANUS_LOG(LOG_ERR, "No configuration file, can't edit room permanently\n");
+ error_code = JANUS_TEXTROOM_ERROR_UNKNOWN_ERROR;
+ g_snprintf(error_cause, 512, "No configuration file, can't edit room permanently");
+ goto msg_response;
+ }
+ guint64 room_id = json_integer_value(room);
+ janus_mutex_lock(&rooms_mutex);
+ janus_textroom_room *textroom = g_hash_table_lookup(rooms, &room_id);
+ if(textroom == NULL) {
+ janus_mutex_unlock(&rooms_mutex);
+ JANUS_LOG(LOG_ERR, "No such room (%"SCNu64")\n", room_id);
+ error_code = JANUS_TEXTROOM_ERROR_NO_SUCH_ROOM;
+ g_snprintf(error_cause, 512, "No such room (%"SCNu64")", room_id);
+ goto msg_response;
+ }
+ janus_mutex_lock(&textroom->mutex);
+ /* A secret may be required for this action */
+ JANUS_CHECK_SECRET(textroom->room_secret, root, "secret", error_code, error_cause,
+ JANUS_TEXTROOM_ERROR_MISSING_ELEMENT, JANUS_TEXTROOM_ERROR_INVALID_ELEMENT, JANUS_TEXTROOM_ERROR_UNAUTHORIZED);
+ if(error_code != 0) {
+ janus_mutex_unlock(&textroom->mutex);
+ janus_mutex_unlock(&rooms_mutex);
+ goto msg_response;
+ }
+ /* Edit the room properties that were provided */
+ if(desc != NULL && strlen(json_string_value(desc)) > 0) {
+ char *old_description = textroom->room_name;
+ char *new_description = g_strdup(json_string_value(desc));
+ textroom->room_name = new_description;
+ g_free(old_description);
+ }
+ if(is_private)
+ textroom->is_private = json_is_true(is_private);
+ if(secret && strlen(json_string_value(secret)) > 0) {
+ char *old_secret = textroom->room_secret;
+ char *new_secret = g_strdup(json_string_value(secret));
+ textroom->room_secret = new_secret;
+ g_free(old_secret);
+ }
+ if(post && strlen(json_string_value(post)) > 0) {
+ char *old_post = textroom->http_backend;
+ char *new_post = g_strdup(json_string_value(post));
+ textroom->http_backend = new_post;
+ g_free(old_post);
+ }
+ if(pin && strlen(json_string_value(pin)) > 0) {
+ char *old_pin = textroom->room_pin;
+ char *new_pin = g_strdup(json_string_value(pin));
+ textroom->room_pin = new_pin;
+ g_free(old_pin);
+ }
+ if(save) {
+ /* This change is permanent: save to the configuration file too
+ * FIXME: We should check if anything fails... */
+ JANUS_LOG(LOG_VERB, "Modifying room %"SCNu64" permanently in config file\n", room_id);
+ janus_mutex_lock(&config_mutex);
+ char cat[BUFSIZ];
+ /* The room ID is the category */
+ g_snprintf(cat, BUFSIZ, "%"SCNu64, room_id);
+ /* Remove the old category first */
+ janus_config_remove_category(config, cat);
+ /* Now write the room details again */
+ janus_config_add_category(config, cat);
+ janus_config_add_item(config, cat, "description", textroom->room_name);
+ if(textroom->is_private)
+ janus_config_add_item(config, cat, "is_private", "yes");
+ if(textroom->room_secret)
+ janus_config_add_item(config, cat, "secret", textroom->room_secret);
+ if(textroom->room_pin)
+ janus_config_add_item(config, cat, "pin", textroom->room_pin);
+ if(textroom->http_backend)
+ janus_config_add_item(config, cat, "post", textroom->http_backend);
+ /* Save modified configuration */
+ if(janus_config_save(config, config_folder, JANUS_TEXTROOM_PACKAGE) < 0)
+ save = FALSE; /* This will notify the user the room changes are not permanent */
+ janus_mutex_unlock(&config_mutex);
+ }
+ janus_mutex_unlock(&textroom->mutex);
+ janus_mutex_unlock(&rooms_mutex);
+ if(!internal) {
+ /* Send response back */
+ reply = json_object();
+ /* Notice that we reply differently if the request came via Janus API */
+ json_object_set_new(reply, "textroom", json_string(json == NULL ? "success" : "edited"));
+ json_object_set_new(reply, "room", json_integer(room_id));
+ json_object_set_new(reply, "permanent", save ? json_true() : json_false());
+ }
+ /* Also notify event handlers */
+ if(notify_events && gateway->events_is_enabled()) {
+ json_t *info = json_object();
+ json_object_set_new(info, "event", json_string("edited"));
+ json_object_set_new(info, "room", json_integer(room_id));
+ gateway->notify_event(&janus_textroom_plugin, session->handle, info);
+ }
} else if(!strcasecmp(request_text, "destroy")) {
JANUS_VALIDATE_JSON_OBJECT(root, room_parameters,
error_code, error_cause, TRUE,
@@ -1605,7 +1725,8 @@ janus_plugin_result *janus_textroom_handle_incoming_request(janus_plugin_session
g_snprintf(cat, BUFSIZ, "%"SCNu64, room_id);
janus_config_remove_category(config, cat);
/* Save modified configuration */
- janus_config_save(config, config_folder, JANUS_TEXTROOM_PACKAGE);
+ if(janus_config_save(config, config_folder, JANUS_TEXTROOM_PACKAGE) < 0)
+ save = FALSE; /* This will notify the user the room destruction is not permanent */
janus_mutex_unlock(&config_mutex);
}
/* Notify all participants */
@@ -1642,6 +1763,8 @@ janus_plugin_result *janus_textroom_handle_incoming_request(janus_plugin_session
reply = json_object();
/* Notice that we reply differently if the request came via Janus API */
json_object_set_new(reply, "textroom", json_string(json == NULL ? "success" : "destroyed"));
+ json_object_set_new(reply, "room", json_integer(room_id));
+ json_object_set_new(reply, "permanent", save ? json_true() : json_false());
}
/* We'll let the watchdog worry about freeing resources */
old_rooms = g_list_append(old_rooms, textroom);
diff --git a/plugins/janus_videoroom.c b/plugins/janus_videoroom.c
index 80459c8..ac41c94 100644
--- a/plugins/janus_videoroom.c
+++ b/plugins/janus_videoroom.c
@@ -89,11 +89,12 @@ rec_dir = <folder where recordings should be stored, when enabled>
* (invalid JSON, invalid request) which will always result in a
* synchronous error response even for asynchronous requests.
*
- * \c create , \c destroy , \c exists, \c list, \c allowed, \c kick and
+ * \c create , \c destroy , \c edit , \c exists, \c list, \c allowed, \c kick and
* and \c listparticipants are synchronous requests, which means you'll
* get a response directly within the context of the transaction.
* \c create allows you to create a new video room dynamically, as an
- * alternative to using the configuration file; \c destroy removes a
+ * alternative to using the configuration file; \c edit allows you to
+ * dynamically edit some room properties (e.g., the PIN); \c destroy removes a
* video room and destroys it, kicking all the users out as part of the
* process; \c exists allows you to check whether a specific video room
* exists; finally, \c list lists all the available rooms, while \c
@@ -241,6 +242,19 @@ static struct janus_json_parameter create_parameters[] = {
{"rec_dir", JSON_STRING, 0},
{"permanent", JANUS_JSON_BOOL, 0}
};
+static struct janus_json_parameter edit_parameters[] = {
+ {"room", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE},
+ {"secret", JSON_STRING, 0},
+ {"new_description", JSON_STRING, 0},
+ {"new_is_private", JANUS_JSON_BOOL, 0},
+ {"new_secret", JSON_STRING, 0},
+ {"new_pin", JSON_STRING, 0},
+ {"new_require_pvtid", JANUS_JSON_BOOL, 0},
+ {"new_bitrate", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
+ {"new_fir_freq", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
+ {"new_publishers", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
+ {"permanent", JANUS_JSON_BOOL, 0}
+};
static struct janus_json_parameter room_parameters[] = {
{"room", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE}
};
@@ -1652,6 +1666,126 @@ struct janus_plugin_result *janus_videoroom_handle_message(janus_plugin_session
gateway->notify_event(&janus_videoroom_plugin, session->handle, info);
}
goto plugin_response;
+ } else if(!strcasecmp(request_text, "edit")) {
+ /* Edit the properties for an existing videoroom */
+ JANUS_LOG(LOG_VERB, "Attempt to edit the properties of an existing videoroom room\n");
+ JANUS_VALIDATE_JSON_OBJECT(root, edit_parameters,
+ error_code, error_cause, TRUE,
+ JANUS_VIDEOROOM_ERROR_MISSING_ELEMENT, JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT);
+ if(error_code != 0)
+ goto plugin_response;
+ /* We only allow for a limited set of properties to be edited */
+ json_t *desc = json_object_get(root, "new_description");
+ json_t *is_private = json_object_get(root, "new_is_private");
+ json_t *req_pvtid = json_object_get(root, "new_require_pvtid");
+ json_t *secret = json_object_get(root, "new_secret");
+ json_t *pin = json_object_get(root, "new_pin");
+ json_t *bitrate = json_object_get(root, "new_bitrate");
+ json_t *fir_freq = json_object_get(root, "new_fir_freq");
+ json_t *publishers = json_object_get(root, "new_publishers");
+ json_t *permanent = json_object_get(root, "permanent");
+ gboolean save = permanent ? json_is_true(permanent) : FALSE;
+ if(save && config == NULL) {
+ JANUS_LOG(LOG_ERR, "No configuration file, can't edit room permanently\n");
+ error_code = JANUS_VIDEOROOM_ERROR_UNKNOWN_ERROR;
+ g_snprintf(error_cause, 512, "No configuration file, can't edit room permanently");
+ goto plugin_response;
+ }
+ janus_mutex_lock(&rooms_mutex);
+ janus_videoroom *videoroom = NULL;
+ error_code = janus_videoroom_access_room(root, TRUE, FALSE, &videoroom, error_cause, sizeof(error_cause));
+ if(error_code != 0) {
+ janus_mutex_unlock(&rooms_mutex);
+ goto plugin_response;
+ }
+ /* Edit the room properties that were provided */
+ if(desc != NULL && strlen(json_string_value(desc)) > 0) {
+ char *old_description = videoroom->room_name;
+ char *new_description = g_strdup(json_string_value(desc));
+ videoroom->room_name = new_description;
+ g_free(old_description);
+ }
+ if(is_private)
+ videoroom->is_private = json_is_true(is_private);
+ if(req_pvtid)
+ videoroom->require_pvtid = json_is_true(req_pvtid);
+ if(publishers)
+ videoroom->max_publishers = json_integer_value(publishers);
+ if(bitrate) {
+ videoroom->bitrate = json_integer_value(bitrate);
+ if(videoroom->bitrate > 0 && videoroom->bitrate < 64000)
+ videoroom->bitrate = 64000; /* Don't go below 64k */
+ }
+ if(fir_freq)
+ videoroom->fir_freq = json_integer_value(fir_freq);
+ if(secret && strlen(json_string_value(secret)) > 0) {
+ char *old_secret = videoroom->room_secret;
+ char *new_secret = g_strdup(json_string_value(secret));
+ videoroom->room_secret = new_secret;
+ g_free(old_secret);
+ }
+ if(pin && strlen(json_string_value(pin)) > 0) {
+ char *old_pin = videoroom->room_pin;
+ char *new_pin = g_strdup(json_string_value(pin));
+ videoroom->room_pin = new_pin;
+ g_free(old_pin);
+ }
+ if(save) {
+ /* This room is permanent: save to the configuration file too
+ * FIXME: We should check if anything fails... */
+ JANUS_LOG(LOG_VERB, "Modifying room %"SCNu64" permanently in config file\n", videoroom->room_id);
+ janus_mutex_lock(&config_mutex);
+ char cat[BUFSIZ], value[BUFSIZ];
+ /* The room ID is the category */
+ g_snprintf(cat, BUFSIZ, "%"SCNu64, videoroom->room_id);
+ /* Remove the old category first */
+ janus_config_remove_category(config, cat);
+ /* Now write the room details again */
+ janus_config_add_category(config, cat);
+ janus_config_add_item(config, cat, "description", videoroom->room_name);
+ if(videoroom->is_private)
+ janus_config_add_item(config, cat, "is_private", "yes");
+ if(videoroom->require_pvtid)
+ janus_config_add_item(config, cat, "require_pvtid", "yes");
+ g_snprintf(value, BUFSIZ, "%"SCNu32, videoroom->bitrate);
+ janus_config_add_item(config, cat, "bitrate", value);
+ g_snprintf(value, BUFSIZ, "%d", videoroom->max_publishers);
+ janus_config_add_item(config, cat, "publishers", value);
+ if(videoroom->fir_freq) {
+ g_snprintf(value, BUFSIZ, "%"SCNu16, videoroom->fir_freq);
+ janus_config_add_item(config, cat, "fir_freq", value);
+ }
+ janus_config_add_item(config, cat, "audiocodec", janus_videoroom_audiocodec_name(videoroom->acodec));
+ janus_config_add_item(config, cat, "videocodec", janus_videoroom_videocodec_name(videoroom->vcodec));
+ if(videoroom->do_svc)
+ janus_config_add_item(config, cat, "video_svc", "yes");
+ if(videoroom->room_secret)
+ janus_config_add_item(config, cat, "secret", videoroom->room_secret);
+ if(videoroom->room_pin)
+ janus_config_add_item(config, cat, "pin", videoroom->room_pin);
+ if(videoroom->record)
+ janus_config_add_item(config, cat, "record", "yes");
+ if(videoroom->rec_dir)
+ janus_config_add_item(config, cat, "rec_dir", videoroom->rec_dir);
+ /* Save modified configuration */
+ if(janus_config_save(config, config_folder, JANUS_VIDEOROOM_PACKAGE) < 0)
+ save = FALSE; /* This will notify the user the room changes are not permanent */
+ janus_mutex_unlock(&config_mutex);
+ }
+ janus_mutex_unlock(&rooms_mutex);
+ /* Send info back */
+ response = json_object();
+ json_object_set_new(response, "videoroom", json_string("edited"));
+ json_object_set_new(response, "room", json_integer(videoroom->room_id));
+ json_object_set_new(response, "permanent", save ? json_true() : json_false());
+ /* Also notify event handlers */
+ if(notify_events && gateway->events_is_enabled()) {
+ json_t *info = json_object();
+ json_object_set_new(info, "event", json_string("edited"));
+ json_object_set_new(info, "room", json_integer(videoroom->room_id));
+ gateway->notify_event(&janus_videoroom_plugin, session->handle, info);
+ }
+ goto plugin_response;
} else if(!strcasecmp(request_text, "destroy")) {
JANUS_LOG(LOG_VERB, "Attempt to destroy an existing videoroom room\n");
JANUS_VALIDATE_JSON_OBJECT(root, destroy_parameters,
@@ -1718,13 +1852,15 @@ struct janus_plugin_result *janus_videoroom_handle_message(janus_plugin_session
g_snprintf(cat, BUFSIZ, "%"SCNu64, room_id);
janus_config_remove_category(config, cat);
/* Save modified configuration */
- janus_config_save(config, config_folder, JANUS_VIDEOROOM_PACKAGE);
+ if(janus_config_save(config, config_folder, JANUS_VIDEOROOM_PACKAGE) < 0)
+ save = FALSE; /* This will notify the user the room destruction is not permanent */
janus_mutex_unlock(&config_mutex);
}
/* Done */
response = json_object();
json_object_set_new(response, "videoroom", json_string("destroyed"));
json_object_set_new(response, "room", json_integer(room_id));
+ json_object_set_new(response, "permanent", save ? json_true() : json_false());
goto plugin_response;
} else if(!strcasecmp(request_text, "list")) {
/* List all rooms (but private ones) and their details (except for the secret, of course...) */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/janus.git
More information about the Pkg-voip-commits
mailing list