mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 04:11:08 +00:00
bridging: Give bridges a name and a known creator
Bridges have two new optional properties, a creator and a name. Certain consumers of bridges will automatically provide bridges that they create with these properties. Examples include app_bridgewait, res_parking, app_confbridge, and app_agent_pool. In addition, a name may now be provided as an argument to the POST function for creating new bridges via ARI. (closes issue AFS-47) Review: https://reviewboard.asterisk.org/r/3070/ ........ Merged revisions 404042 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@404043 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1366,7 +1366,8 @@ static struct ast_bridge *bridge_agent_hold_new(void)
|
|||||||
bridge = bridge_alloc(sizeof(struct ast_bridge), &bridge_agent_hold_v_table);
|
bridge = bridge_alloc(sizeof(struct ast_bridge), &bridge_agent_hold_v_table);
|
||||||
bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
|
bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
|
||||||
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
|
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
|
||||||
| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
|
| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED,
|
||||||
|
"AgentPool", NULL);
|
||||||
bridge = bridge_register(bridge);
|
bridge = bridge_register(bridge);
|
||||||
return bridge;
|
return bridge;
|
||||||
}
|
}
|
||||||
|
@@ -360,7 +360,8 @@ static struct wait_bridge_wrapper *get_wait_bridge_wrapper(const char *bridge_na
|
|||||||
bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
|
bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
|
||||||
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
|
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
|
||||||
| AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
|
| AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
|
||||||
| AST_BRIDGE_FLAG_TRANSFER_PROHIBITED | AST_BRIDGE_FLAG_DISSOLVE_EMPTY);
|
| AST_BRIDGE_FLAG_TRANSFER_PROHIBITED | AST_BRIDGE_FLAG_DISSOLVE_EMPTY,
|
||||||
|
APP_NAME, bridge_name);
|
||||||
|
|
||||||
if (!bridge) {
|
if (!bridge) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -1218,7 +1218,8 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
|
|||||||
|
|
||||||
/* Create an actual bridge that will do the audio mixing */
|
/* Create an actual bridge that will do the audio mixing */
|
||||||
conference->bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
|
conference->bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
|
||||||
AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY);
|
AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY,
|
||||||
|
app, conference_name);
|
||||||
if (!conference->bridge) {
|
if (!conference->bridge) {
|
||||||
ao2_ref(conference, -1);
|
ao2_ref(conference, -1);
|
||||||
conference = NULL;
|
conference = NULL;
|
||||||
|
@@ -118,6 +118,18 @@
|
|||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
<para>Technology in use by the bridge</para>
|
<para>Technology in use by the bridge</para>
|
||||||
</xsl:element>
|
</xsl:element>
|
||||||
|
<xsl:element name="parameter">
|
||||||
|
<xsl:attribute name="name">
|
||||||
|
<xsl:value-of select="concat(@prefix, 'BridgeCreator')"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<para>Entity that created the bridge if applicable</para>
|
||||||
|
</xsl:element>
|
||||||
|
<xsl:element name="parameter">
|
||||||
|
<xsl:attribute name="name">
|
||||||
|
<xsl:value-of select="concat(@prefix, 'BridgeName')"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<para>Name used to refer to the bridge by its BridgeCreator if applicable</para>
|
||||||
|
</xsl:element>
|
||||||
<xsl:element name="parameter">
|
<xsl:element name="parameter">
|
||||||
<xsl:attribute name="name">
|
<xsl:attribute name="name">
|
||||||
<xsl:value-of select="concat(@prefix,'BridgeNumChannels')"/>
|
<xsl:value-of select="concat(@prefix,'BridgeNumChannels')"/>
|
||||||
|
@@ -312,8 +312,15 @@ struct ast_bridge {
|
|||||||
unsigned int dissolved:1;
|
unsigned int dissolved:1;
|
||||||
/*! TRUE if the bridge construction was completed. */
|
/*! TRUE if the bridge construction was completed. */
|
||||||
unsigned int construction_completed:1;
|
unsigned int construction_completed:1;
|
||||||
/*! Immutable bridge UUID. */
|
|
||||||
char uniqueid[AST_UUID_STR_LEN];
|
AST_DECLARE_STRING_FIELDS(
|
||||||
|
/*! Immutable name of the creator for the bridge */
|
||||||
|
AST_STRING_FIELD(creator);
|
||||||
|
/*! Immutable name given to the bridge by its creator */
|
||||||
|
AST_STRING_FIELD(name);
|
||||||
|
/*! Immutable bridge UUID. */
|
||||||
|
AST_STRING_FIELD(uniqueid);
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Bridge base class virtual method table. */
|
/*! \brief Bridge base class virtual method table. */
|
||||||
@@ -324,6 +331,8 @@ extern struct ast_bridge_methods ast_bridge_base_v_table;
|
|||||||
*
|
*
|
||||||
* \param capabilities The capabilities that we require to be used on the bridge
|
* \param capabilities The capabilities that we require to be used on the bridge
|
||||||
* \param flags Flags that will alter the behavior of the bridge
|
* \param flags Flags that will alter the behavior of the bridge
|
||||||
|
* \param creator Entity that created the bridge (optional)
|
||||||
|
* \param name Name given to the bridge by its creator (optional, requires named creator)
|
||||||
*
|
*
|
||||||
* \retval a pointer to a new bridge on success
|
* \retval a pointer to a new bridge on success
|
||||||
* \retval NULL on failure
|
* \retval NULL on failure
|
||||||
@@ -338,7 +347,7 @@ extern struct ast_bridge_methods ast_bridge_base_v_table;
|
|||||||
* This creates a no frills two party bridge that will be
|
* This creates a no frills two party bridge that will be
|
||||||
* destroyed once one of the channels hangs up.
|
* destroyed once one of the channels hangs up.
|
||||||
*/
|
*/
|
||||||
struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags);
|
struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Try locking the bridge.
|
* \brief Try locking the bridge.
|
||||||
|
@@ -87,6 +87,8 @@ struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_
|
|||||||
* \param self Bridge to operate upon. (Tolerates a NULL pointer)
|
* \param self Bridge to operate upon. (Tolerates a NULL pointer)
|
||||||
* \param capabilities The capabilities that we require to be used on the bridge
|
* \param capabilities The capabilities that we require to be used on the bridge
|
||||||
* \param flags Flags that will alter the behavior of the bridge
|
* \param flags Flags that will alter the behavior of the bridge
|
||||||
|
* \param creator Entity that created the bridge (optional)
|
||||||
|
* \param name Name given to the bridge by its creator (optional, requires named creator)
|
||||||
*
|
*
|
||||||
* \retval self on success
|
* \retval self on success
|
||||||
* \retval NULL on failure, self is already destroyed
|
* \retval NULL on failure, self is already destroyed
|
||||||
@@ -96,13 +98,13 @@ struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_
|
|||||||
* \code
|
* \code
|
||||||
* struct ast_bridge *bridge;
|
* struct ast_bridge *bridge;
|
||||||
* bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
|
* bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
|
||||||
* bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
|
* bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP, NULL, NULL);
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* This creates a no frills two party bridge that will be
|
* This creates a no frills two party bridge that will be
|
||||||
* destroyed once one of the channels hangs up.
|
* destroyed once one of the channels hangs up.
|
||||||
*/
|
*/
|
||||||
struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags);
|
struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \internal
|
* \internal
|
||||||
|
@@ -597,11 +597,12 @@ int stasis_app_control_queue_control(struct stasis_app_control *control,
|
|||||||
* \brief Create a bridge of the specified type.
|
* \brief Create a bridge of the specified type.
|
||||||
*
|
*
|
||||||
* \param type The type of bridge to be created
|
* \param type The type of bridge to be created
|
||||||
|
* \param name Optional name to give to the bridge
|
||||||
*
|
*
|
||||||
* \return New bridge.
|
* \return New bridge.
|
||||||
* \return \c NULL on error.
|
* \return \c NULL on error.
|
||||||
*/
|
*/
|
||||||
struct ast_bridge *stasis_app_bridge_create(const char *type);
|
struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the bridge with the given id.
|
* \brief Returns the bridge with the given id.
|
||||||
|
@@ -42,6 +42,10 @@ struct ast_bridge_snapshot {
|
|||||||
AST_STRING_FIELD(technology);
|
AST_STRING_FIELD(technology);
|
||||||
/*! Bridge subclass that is handling the bridge */
|
/*! Bridge subclass that is handling the bridge */
|
||||||
AST_STRING_FIELD(subclass);
|
AST_STRING_FIELD(subclass);
|
||||||
|
/*! Creator of the bridge */
|
||||||
|
AST_STRING_FIELD(creator);
|
||||||
|
/*! Name given to the bridge by its creator */
|
||||||
|
AST_STRING_FIELD(name);
|
||||||
);
|
);
|
||||||
/*! AO2 container of bare channel uniqueid strings participating in the bridge.
|
/*! AO2 container of bare channel uniqueid strings participating in the bridge.
|
||||||
* Allocated from ast_str_container_alloc() */
|
* Allocated from ast_str_container_alloc() */
|
||||||
|
@@ -533,9 +533,11 @@ static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_f
|
|||||||
struct ast_bridge dummy_bridge = {
|
struct ast_bridge dummy_bridge = {
|
||||||
.technology = deferred->tech,
|
.technology = deferred->tech,
|
||||||
.tech_pvt = deferred->tech_pvt,
|
.tech_pvt = deferred->tech_pvt,
|
||||||
|
.creator = bridge->creator,
|
||||||
|
.name = bridge->name,
|
||||||
|
.uniqueid = bridge->uniqueid,
|
||||||
};
|
};
|
||||||
|
|
||||||
ast_copy_string(dummy_bridge.uniqueid, bridge->uniqueid, sizeof(dummy_bridge.uniqueid));
|
|
||||||
ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
|
ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
|
||||||
dummy_bridge.uniqueid, dummy_bridge.technology->name);
|
dummy_bridge.uniqueid, dummy_bridge.technology->name);
|
||||||
dummy_bridge.technology->destroy(&dummy_bridge);
|
dummy_bridge.technology->destroy(&dummy_bridge);
|
||||||
@@ -679,6 +681,8 @@ static void destroy_bridge(void *obj)
|
|||||||
cleanup_video_mode(bridge);
|
cleanup_video_mode(bridge);
|
||||||
|
|
||||||
stasis_cp_single_unsubscribe(bridge->topics);
|
stasis_cp_single_unsubscribe(bridge->topics);
|
||||||
|
|
||||||
|
ast_string_field_free_memory(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast_bridge *bridge_register(struct ast_bridge *bridge)
|
struct ast_bridge *bridge_register(struct ast_bridge *bridge)
|
||||||
@@ -714,19 +718,35 @@ struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_
|
|||||||
}
|
}
|
||||||
|
|
||||||
bridge = ao2_alloc(size, destroy_bridge);
|
bridge = ao2_alloc(size, destroy_bridge);
|
||||||
if (bridge) {
|
if (!bridge) {
|
||||||
bridge->v_table = v_table;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ast_string_field_init(bridge, 80)) {
|
||||||
|
ao2_cleanup(bridge);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge->v_table = v_table;
|
||||||
|
|
||||||
return bridge;
|
return bridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags)
|
struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name)
|
||||||
{
|
{
|
||||||
|
char uuid_hold[AST_UUID_STR_LEN];
|
||||||
|
|
||||||
if (!self) {
|
if (!self) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_uuid_generate_str(self->uniqueid, sizeof(self->uniqueid));
|
ast_uuid_generate_str(uuid_hold, AST_UUID_STR_LEN);
|
||||||
|
ast_string_field_set(self, uniqueid, uuid_hold);
|
||||||
|
ast_string_field_set(self, creator, creator);
|
||||||
|
if (!ast_strlen_zero(creator)) {
|
||||||
|
ast_string_field_set(self, name, name);
|
||||||
|
}
|
||||||
|
|
||||||
ast_set_flag(&self->feature_flags, flags);
|
ast_set_flag(&self->feature_flags, flags);
|
||||||
self->allowed_capabilities = capabilities;
|
self->allowed_capabilities = capabilities;
|
||||||
|
|
||||||
@@ -881,12 +901,12 @@ struct ast_bridge_methods ast_bridge_base_v_table = {
|
|||||||
.get_merge_priority = bridge_base_get_merge_priority,
|
.get_merge_priority = bridge_base_get_merge_priority,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags)
|
struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name)
|
||||||
{
|
{
|
||||||
void *bridge;
|
void *bridge;
|
||||||
|
|
||||||
bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
|
bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
|
||||||
bridge = bridge_base_init(bridge, capabilities, flags);
|
bridge = bridge_base_init(bridge, capabilities, flags, creator, name);
|
||||||
bridge = bridge_register(bridge);
|
bridge = bridge_register(bridge);
|
||||||
return bridge;
|
return bridge;
|
||||||
}
|
}
|
||||||
@@ -991,6 +1011,9 @@ static int smart_bridge_operation(struct ast_bridge *bridge)
|
|||||||
struct ast_bridge dummy_bridge = {
|
struct ast_bridge dummy_bridge = {
|
||||||
.technology = bridge->technology,
|
.technology = bridge->technology,
|
||||||
.tech_pvt = bridge->tech_pvt,
|
.tech_pvt = bridge->tech_pvt,
|
||||||
|
.creator = bridge->creator,
|
||||||
|
.name = bridge->name,
|
||||||
|
.uniqueid = bridge->uniqueid,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (bridge->dissolved) {
|
if (bridge->dissolved) {
|
||||||
@@ -1043,8 +1066,6 @@ static int smart_bridge_operation(struct ast_bridge *bridge)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_copy_string(dummy_bridge.uniqueid, bridge->uniqueid, sizeof(dummy_bridge.uniqueid));
|
|
||||||
|
|
||||||
if (old_technology->destroy) {
|
if (old_technology->destroy) {
|
||||||
struct tech_deferred_destroy deferred_tech_destroy = {
|
struct tech_deferred_destroy deferred_tech_destroy = {
|
||||||
.tech = dummy_bridge.technology,
|
.tech = dummy_bridge.technology,
|
||||||
|
@@ -3239,7 +3239,7 @@ struct ast_bridge *ast_bridge_basic_new(void)
|
|||||||
bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_basic_v_table);
|
bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_basic_v_table);
|
||||||
bridge = bridge_base_init(bridge,
|
bridge = bridge_base_init(bridge,
|
||||||
AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX
|
AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX
|
||||||
| AST_BRIDGE_CAPABILITY_MULTIMIX, NORMAL_FLAGS);
|
| AST_BRIDGE_CAPABILITY_MULTIMIX, NORMAL_FLAGS, NULL, NULL);
|
||||||
bridge = bridge_basic_personality_alloc(bridge);
|
bridge = bridge_basic_personality_alloc(bridge);
|
||||||
bridge = bridge_register(bridge);
|
bridge = bridge_register(bridge);
|
||||||
return bridge;
|
return bridge;
|
||||||
|
@@ -156,10 +156,14 @@ struct ast_str *ast_manager_build_bridge_state_string_prefix(
|
|||||||
"%sBridgeUniqueid: %s\r\n"
|
"%sBridgeUniqueid: %s\r\n"
|
||||||
"%sBridgeType: %s\r\n"
|
"%sBridgeType: %s\r\n"
|
||||||
"%sBridgeTechnology: %s\r\n"
|
"%sBridgeTechnology: %s\r\n"
|
||||||
|
"%sBridgeCreator: %s\r\n"
|
||||||
|
"%sBridgeName: %s\r\n"
|
||||||
"%sBridgeNumChannels: %d\r\n",
|
"%sBridgeNumChannels: %d\r\n",
|
||||||
prefix, snapshot->uniqueid,
|
prefix, snapshot->uniqueid,
|
||||||
prefix, snapshot->subclass,
|
prefix, snapshot->subclass,
|
||||||
prefix, snapshot->technology,
|
prefix, snapshot->technology,
|
||||||
|
prefix, ast_strlen_zero(snapshot->creator) ? "<unknown>": snapshot->creator,
|
||||||
|
prefix, ast_strlen_zero(snapshot->name) ? "<unknown>": snapshot->name,
|
||||||
prefix, snapshot->num_channels);
|
prefix, snapshot->num_channels);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
ast_free(out);
|
ast_free(out);
|
||||||
|
@@ -242,6 +242,8 @@ struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge
|
|||||||
ast_string_field_set(snapshot, uniqueid, bridge->uniqueid);
|
ast_string_field_set(snapshot, uniqueid, bridge->uniqueid);
|
||||||
ast_string_field_set(snapshot, technology, bridge->technology->name);
|
ast_string_field_set(snapshot, technology, bridge->technology->name);
|
||||||
ast_string_field_set(snapshot, subclass, bridge->v_table->name);
|
ast_string_field_set(snapshot, subclass, bridge->v_table->name);
|
||||||
|
ast_string_field_set(snapshot, creator, bridge->creator);
|
||||||
|
ast_string_field_set(snapshot, name, bridge->name);
|
||||||
|
|
||||||
snapshot->feature_flags = bridge->feature_flags;
|
snapshot->feature_flags = bridge->feature_flags;
|
||||||
snapshot->capabilities = bridge->technology->capabilities;
|
snapshot->capabilities = bridge->technology->capabilities;
|
||||||
@@ -548,11 +550,13 @@ struct ast_json *ast_bridge_snapshot_to_json(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: o}",
|
json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o}",
|
||||||
"id", snapshot->uniqueid,
|
"id", snapshot->uniqueid,
|
||||||
"technology", snapshot->technology,
|
"technology", snapshot->technology,
|
||||||
"bridge_type", capability2str(snapshot->capabilities),
|
"bridge_type", capability2str(snapshot->capabilities),
|
||||||
"bridge_class", snapshot->subclass,
|
"bridge_class", snapshot->subclass,
|
||||||
|
"creator", snapshot->creator,
|
||||||
|
"name", snapshot->name,
|
||||||
"channels", json_channels);
|
"channels", json_channels);
|
||||||
if (!json_bridge) {
|
if (!json_bridge) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -891,7 +891,9 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||||||
int has_bridge_class = 0;
|
int has_bridge_class = 0;
|
||||||
int has_bridge_type = 0;
|
int has_bridge_type = 0;
|
||||||
int has_channels = 0;
|
int has_channels = 0;
|
||||||
|
int has_creator = 0;
|
||||||
int has_id = 0;
|
int has_id = 0;
|
||||||
|
int has_name = 0;
|
||||||
int has_technology = 0;
|
int has_technology = 0;
|
||||||
|
|
||||||
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
||||||
@@ -926,6 +928,16 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
if (strcmp("creator", ast_json_object_iter_key(iter)) == 0) {
|
||||||
|
int prop_is_valid;
|
||||||
|
has_creator = 1;
|
||||||
|
prop_is_valid = ast_ari_validate_string(
|
||||||
|
ast_json_object_iter_value(iter));
|
||||||
|
if (!prop_is_valid) {
|
||||||
|
ast_log(LOG_ERROR, "ARI Bridge field creator failed validation\n");
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
} else
|
||||||
if (strcmp("id", ast_json_object_iter_key(iter)) == 0) {
|
if (strcmp("id", ast_json_object_iter_key(iter)) == 0) {
|
||||||
int prop_is_valid;
|
int prop_is_valid;
|
||||||
has_id = 1;
|
has_id = 1;
|
||||||
@@ -936,6 +948,16 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
if (strcmp("name", ast_json_object_iter_key(iter)) == 0) {
|
||||||
|
int prop_is_valid;
|
||||||
|
has_name = 1;
|
||||||
|
prop_is_valid = ast_ari_validate_string(
|
||||||
|
ast_json_object_iter_value(iter));
|
||||||
|
if (!prop_is_valid) {
|
||||||
|
ast_log(LOG_ERROR, "ARI Bridge field name failed validation\n");
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
} else
|
||||||
if (strcmp("technology", ast_json_object_iter_key(iter)) == 0) {
|
if (strcmp("technology", ast_json_object_iter_key(iter)) == 0) {
|
||||||
int prop_is_valid;
|
int prop_is_valid;
|
||||||
has_technology = 1;
|
has_technology = 1;
|
||||||
@@ -969,11 +991,21 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!has_creator) {
|
||||||
|
ast_log(LOG_ERROR, "ARI Bridge missing required field creator\n");
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!has_id) {
|
if (!has_id) {
|
||||||
ast_log(LOG_ERROR, "ARI Bridge missing required field id\n");
|
ast_log(LOG_ERROR, "ARI Bridge missing required field id\n");
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!has_name) {
|
||||||
|
ast_log(LOG_ERROR, "ARI Bridge missing required field name\n");
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!has_technology) {
|
if (!has_technology) {
|
||||||
ast_log(LOG_ERROR, "ARI Bridge missing required field technology\n");
|
ast_log(LOG_ERROR, "ARI Bridge missing required field technology\n");
|
||||||
res = 0;
|
res = 0;
|
||||||
|
@@ -1083,7 +1083,9 @@ ari_validator ast_ari_validate_application_fn(void);
|
|||||||
* - bridge_class: string (required)
|
* - bridge_class: string (required)
|
||||||
* - bridge_type: string (required)
|
* - bridge_type: string (required)
|
||||||
* - channels: List[string] (required)
|
* - channels: List[string] (required)
|
||||||
|
* - creator: string (required)
|
||||||
* - id: string (required)
|
* - id: string (required)
|
||||||
|
* - name: string (required)
|
||||||
* - technology: string (required)
|
* - technology: string (required)
|
||||||
* LiveRecording
|
* LiveRecording
|
||||||
* - cause: string
|
* - cause: string
|
||||||
|
@@ -695,7 +695,7 @@ void ast_ari_bridges_create(struct ast_variable *headers,
|
|||||||
struct ast_ari_bridges_create_args *args,
|
struct ast_ari_bridges_create_args *args,
|
||||||
struct ast_ari_response *response)
|
struct ast_ari_response *response)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_bridge *, bridge, stasis_app_bridge_create(args->type), ao2_cleanup);
|
RAII_VAR(struct ast_bridge *, bridge, stasis_app_bridge_create(args->type, args->name), ao2_cleanup);
|
||||||
RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
|
||||||
|
|
||||||
if (!bridge) {
|
if (!bridge) {
|
||||||
|
@@ -54,6 +54,8 @@ void ast_ari_bridges_list(struct ast_variable *headers, struct ast_ari_bridges_l
|
|||||||
struct ast_ari_bridges_create_args {
|
struct ast_ari_bridges_create_args {
|
||||||
/*! \brief Type of bridge to create. */
|
/*! \brief Type of bridge to create. */
|
||||||
const char *type;
|
const char *type;
|
||||||
|
/*! \brief Name to give to the bridge being created. */
|
||||||
|
const char *name;
|
||||||
};
|
};
|
||||||
/*!
|
/*!
|
||||||
* \brief Create a new bridge.
|
* \brief Create a new bridge.
|
||||||
|
@@ -456,7 +456,7 @@ struct ast_bridge *bridge_parking_new(struct parking_lot *bridge_lot)
|
|||||||
bridge = bridge_alloc(sizeof(struct ast_bridge_parking), &ast_bridge_parking_v_table);
|
bridge = bridge_alloc(sizeof(struct ast_bridge_parking), &ast_bridge_parking_v_table);
|
||||||
bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
|
bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
|
||||||
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
|
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
|
||||||
| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM);
|
| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, "Parking", bridge_lot->name);
|
||||||
bridge = ast_bridge_parking_init(bridge, bridge_lot);
|
bridge = ast_bridge_parking_init(bridge, bridge_lot);
|
||||||
bridge = bridge_register(bridge);
|
bridge = bridge_register(bridge);
|
||||||
return bridge;
|
return bridge;
|
||||||
|
@@ -127,6 +127,9 @@ static void ast_ari_bridges_create_cb(
|
|||||||
if (strcmp(i->name, "type") == 0) {
|
if (strcmp(i->name, "type") == 0) {
|
||||||
args.type = (i->value);
|
args.type = (i->value);
|
||||||
} else
|
} else
|
||||||
|
if (strcmp(i->name, "name") == 0) {
|
||||||
|
args.name = (i->value);
|
||||||
|
} else
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
/* Look for a JSON request entity */
|
/* Look for a JSON request entity */
|
||||||
@@ -149,6 +152,10 @@ static void ast_ari_bridges_create_cb(
|
|||||||
if (field) {
|
if (field) {
|
||||||
args.type = ast_json_string_get(field);
|
args.type = ast_json_string_get(field);
|
||||||
}
|
}
|
||||||
|
field = ast_json_object_get(body, "name");
|
||||||
|
if (field) {
|
||||||
|
args.name = ast_json_string_get(field);
|
||||||
|
}
|
||||||
ast_ari_bridges_create(headers, &args, response);
|
ast_ari_bridges_create(headers, &args, response);
|
||||||
#if defined(AST_DEVMODE)
|
#if defined(AST_DEVMODE)
|
||||||
code = response->response_code;
|
code = response->response_code;
|
||||||
|
@@ -585,7 +585,7 @@ static void control_unlink(struct stasis_app_control *control)
|
|||||||
ao2_cleanup(control);
|
ao2_cleanup(control);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast_bridge *stasis_app_bridge_create(const char *type)
|
struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name)
|
||||||
{
|
{
|
||||||
struct ast_bridge *bridge;
|
struct ast_bridge *bridge;
|
||||||
int capabilities;
|
int capabilities;
|
||||||
@@ -604,7 +604,7 @@ struct ast_bridge *stasis_app_bridge_create(const char *type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge = ast_bridge_base_new(capabilities, flags);
|
bridge = ast_bridge_base_new(capabilities, flags, "Stasis", name);
|
||||||
if (bridge) {
|
if (bridge) {
|
||||||
if (!ao2_link(app_bridges, bridge)) {
|
if (!ao2_link(app_bridges, bridge)) {
|
||||||
ast_bridge_destroy(bridge, 0);
|
ast_bridge_destroy(bridge, 0);
|
||||||
|
@@ -38,6 +38,14 @@
|
|||||||
"holding"
|
"holding"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"description": "Name to give to the bridge being created.",
|
||||||
|
"paramType": "query",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false,
|
||||||
|
"dataType": "string"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -502,6 +510,16 @@
|
|||||||
"description": "Bridging class",
|
"description": "Bridging class",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
"creator": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Entity that created the bridge",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name the creator gave the bridge",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
"channels": {
|
"channels": {
|
||||||
"type": "List[string]",
|
"type": "List[string]",
|
||||||
"description": "Ids of channels participating in this bridge",
|
"description": "Ids of channels participating in this bridge",
|
||||||
|
Reference in New Issue
Block a user