ARI: bridges/{bridgeID}/addChannel: add roles parameter
authorJonathan Rose <jrose@digium.com>
Mon, 5 Aug 2013 16:59:13 +0000 (16:59 +0000)
committerJonathan Rose <jrose@digium.com>
Mon, 5 Aug 2013 16:59:13 +0000 (16:59 +0000)
Roles are now cleared with each entry into a bridge with addChannel.
If the roles parameter is present, the role specified will be applied
to all channels being added with the addChannel command.

(closes issue ASTERISK-21973)
Reported by: Matt Jordan
https://reviewboard.asterisk.org/r/2691/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@396182 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/bridge_roles.h
include/asterisk/stasis_app.h
main/bridge_roles.c
res/ari/resource_bridges.c
res/ari/resource_bridges.h
res/res_ari_bridges.c
res/stasis/control.c
rest-api/api-docs/bridges.json

index d90e564..f91a6b0 100644 (file)
@@ -52,6 +52,13 @@ int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
 void ast_channel_remove_bridge_role(struct ast_channel *chan, const char *role_name);
 
 /*!
+ * \brief Removes all bridge roles currently on a channel
+ *
+ * \param chan Channel the roles are being removed from
+ */
+void ast_channel_clear_bridge_roles(struct ast_channel *chan);
+
+/*!
  * \brief Set a role option on a channel
  * \param channel Channel receiving the role option
  * \param role_name Role the role option is applied to
index 898cb18..87b4bdb 100644 (file)
@@ -174,6 +174,24 @@ const char *stasis_app_control_get_channel_id(
 int stasis_app_control_dial(struct stasis_app_control *control, const char *endpoint, int timeout);
 
 /*!
+ * \brief Apply a bridge role to a channel controlled by a stasis app control
+ *
+ * \param control Control for \c res_stasis
+ * \param role Role to apply
+ *
+ * \return 0 for success
+ * \return -1 for error.
+ */
+int stasis_app_control_add_role(struct stasis_app_control *control, const char *role);
+
+/*!
+ * \brief Clear bridge roles currently applied to a channel controlled by a stasis app control
+ *
+ * \param control Control for \c res_stasis
+ */
+void stasis_app_control_clear_roles(struct stasis_app_control *control);
+
+/*!
  * \brief Exit \c res_stasis and continue execution in the dialplan.
  *
  * If the channel is no longer in \c res_stasis, this function does nothing.
index dd1012b..1d781ca 100644 (file)
@@ -355,6 +355,25 @@ void ast_channel_remove_bridge_role(struct ast_channel *chan, const char *role_n
        ast_debug(2, "Role %s did not exist on channel %s\n", role_name, ast_channel_name(chan));
 }
 
+void ast_channel_clear_bridge_roles(struct ast_channel *chan)
+{
+       struct bridge_roles_datastore *roles_datastore = fetch_bridge_roles_datastore(chan);
+       struct bridge_role *role;
+
+       if (!roles_datastore) {
+               /* The roles datastore didn't already exist, so there is no need to remove any roles */
+               ast_debug(2, "Roles did not exist on channel %s\n", ast_channel_name(chan));
+               return;
+       }
+
+       AST_LIST_TRAVERSE_SAFE_BEGIN(&roles_datastore->role_list, role, list) {
+               ast_debug(2, "Removing bridge role %s from channel %s\n", role->role, ast_channel_name(chan));
+               AST_LIST_REMOVE_CURRENT(list);
+               bridge_role_destroy(role);
+       }
+       AST_LIST_TRAVERSE_SAFE_END;
+}
+
 int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value)
 {
        struct bridge_role *role = get_role_from_channel(channel, role_name);
index e4c7194..65fe8d7 100644 (file)
@@ -176,6 +176,16 @@ void ast_ari_add_channel_to_bridge(struct ast_variable *headers, struct ast_add_
        }
 
        for (i = 0; i < list->count; ++i) {
+               stasis_app_control_clear_roles(list->controls[i]);
+               if (!ast_strlen_zero(args->role)) {
+                       if (stasis_app_control_add_role(list->controls[i], args->role)) {
+                               ast_ari_response_alloc_failed(response);
+                               return;
+                       }
+               }
+       }
+
+       for (i = 0; i < list->count; ++i) {
                stasis_app_control_add_channel_to_bridge(list->controls[i], bridge);
        }
 
index d124324..d82cb6f 100644 (file)
@@ -103,6 +103,8 @@ struct ast_add_channel_to_bridge_args {
        size_t channel_count;
        /*! \brief Parsing context for channel. */
        char *channel_parse;
+       /*! \brief Channel's role in the bridge */
+       const char *role;
 };
 /*!
  * \brief Add a channel to a bridge.
index 57dc6a4..05ea12e 100644 (file)
@@ -324,6 +324,9 @@ static void ast_ari_add_channel_to_bridge_cb(
                                args.channel[j] = (vals[j]);
                        }
                } else
+               if (strcmp(i->name, "role") == 0) {
+                       args.role = (i->value);
+               } else
                {}
        }
        for (i = path_vars; i; i = i->next) {
index 211566e..dcc0297 100644 (file)
@@ -168,6 +168,16 @@ int stasis_app_control_dial(struct stasis_app_control *control, const char *endp
        return 0;
 }
 
+int stasis_app_control_add_role(struct stasis_app_control *control, const char *role)
+{
+       return ast_channel_add_bridge_role(control->channel, role);
+}
+
+void stasis_app_control_clear_roles(struct stasis_app_control *control)
+{
+       ast_channel_clear_bridge_roles(control->channel);
+}
+
 int control_is_done(struct stasis_app_control *control)
 {
        /* Called from stasis_app_exec thread; no lock needed */
index 57954dd..940ed0a 100644 (file)
                                                        "required": true,
                                                        "allowMultiple": true,
                                                        "dataType": "string"
+                                               },
+                                               {
+                                                       "name": "role",
+                                                       "description": "Channel's role in the bridge",
+                                                       "paramType": "query",
+                                                       "required": false,
+                                                       "allowMultiple": false,
+                                                       "dataType": "string"
                                                }
                                        ],
                                        "errorResponses": [