summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/channel.c41
-rw-r--r--main/pbx.c55
2 files changed, 78 insertions, 18 deletions
diff --git a/main/channel.c b/main/channel.c
index 12a30e048..15c7fa406 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -4068,6 +4068,19 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
}
ast_frfree(f);
f = &ast_null_frame;
+ } else if (f->subclass.integer == AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE && dropnondefault) {
+ /* The caller of this function is incapable of handling streams so we don't accept the change request
+ * and stick to the streams currently on the channel.
+ */
+ ast_channel_stream_topology_changed(chan, ast_channel_get_stream_topology(chan));
+ ast_frfree(f);
+ f = &ast_null_frame;
+ } else if (f->subclass.integer == AST_CONTROL_STREAM_TOPOLOGY_CHANGED && dropnondefault) {
+ /* The caller of this function is incapable of handling streams so we absord the notification that the
+ * stream topology has changed.
+ */
+ ast_frfree(f);
+ f = &ast_null_frame;
}
break;
case AST_FRAME_DTMF_END:
@@ -4494,6 +4507,8 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
case AST_CONTROL_UPDATE_RTP_PEER:
case AST_CONTROL_PVT_CAUSE_CODE:
case AST_CONTROL_MASQUERADE_NOTIFY:
+ case AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE:
+ case AST_CONTROL_STREAM_TOPOLOGY_CHANGED:
case AST_CONTROL_STREAM_STOP:
case AST_CONTROL_STREAM_SUSPEND:
case AST_CONTROL_STREAM_REVERSE:
@@ -4792,6 +4807,8 @@ static int indicate_data_internal(struct ast_channel *chan, int _condition, cons
case AST_CONTROL_MCID:
case AST_CONTROL_MASQUERADE_NOTIFY:
case AST_CONTROL_UPDATE_RTP_PEER:
+ case AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE:
+ case AST_CONTROL_STREAM_TOPOLOGY_CHANGED:
case AST_CONTROL_STREAM_STOP:
case AST_CONTROL_STREAM_SUSPEND:
case AST_CONTROL_STREAM_REVERSE:
@@ -11147,3 +11164,27 @@ enum ast_channel_error ast_channel_errno(void)
{
return ast_channel_internal_errno();
}
+
+int ast_channel_request_stream_topology_change(struct ast_channel *chan, struct ast_stream_topology *topology)
+{
+ ast_assert(chan != NULL);
+ ast_assert(topology != NULL);
+
+ if (!ast_channel_is_multistream(chan) || !ast_channel_tech(chan)->indicate) {
+ return -1;
+ }
+
+ return ast_channel_tech(chan)->indicate(chan, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, topology, sizeof(topology));
+}
+
+int ast_channel_stream_topology_changed(struct ast_channel *chan, struct ast_stream_topology *topology)
+{
+ ast_assert(chan != NULL);
+ ast_assert(topology != NULL);
+
+ if (!ast_channel_is_multistream(chan) || !ast_channel_tech(chan)->indicate) {
+ return -1;
+ }
+
+ return ast_channel_tech(chan)->indicate(chan, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, topology, sizeof(topology));
+}
diff --git a/main/pbx.c b/main/pbx.c
index fe87d67a5..dc4b91f08 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -657,7 +657,7 @@ static int ast_add_extension2_lockopt(struct ast_context *con,
static struct ast_context *find_context_locked(const char *context);
static struct ast_context *find_context(const char *context);
static void get_device_state_causing_channels(struct ao2_container *c);
-static int ext_strncpy(char *dst, const char *src, int len, int nofluff);
+static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff);
/*!
* \internal
@@ -6980,32 +6980,51 @@ int ast_async_goto_by_name(const char *channame, const char *context, const char
return res;
}
-/*! \brief copy a string skipping whitespace and dashes */
-static int ext_strncpy(char *dst, const char *src, int len, int nofluff)
+/*!
+ * \internal
+ * \brief Copy a string skipping whitespace and optionally dashes.
+ *
+ * \param dst Destination buffer to copy src string.
+ * \param src Null terminated string to copy.
+ * \param dst_size Number of bytes in the dst buffer.
+ * \param nofluf Nonzero if '-' chars are not copied.
+ *
+ * \return Number of bytes written to dst including null terminator.
+ */
+static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff)
{
- int count = 0;
- int insquares = 0;
+ unsigned int count;
+ unsigned int insquares;
+ unsigned int is_pattern;
- while (*src && (count < len - 1)) {
+ if (!dst_size--) {
+ /* There really is no dst buffer */
+ return 0;
+ }
+
+ count = 0;
+ insquares = 0;
+ is_pattern = *src == '_';
+ while (*src && count < dst_size) {
if (*src == '[') {
- insquares = 1;
+ if (is_pattern) {
+ insquares = 1;
+ }
} else if (*src == ']') {
insquares = 0;
} else if (*src == ' ' && !insquares) {
- src++;
+ ++src;
continue;
} else if (*src == '-' && !insquares && nofluff) {
- src++;
+ ++src;
continue;
}
- *dst = *src;
- dst++;
- src++;
- count++;
+ *dst++ = *src++;
+ ++count;
}
*dst = '\0';
- return count;
+ return count + 1;
}
/*!
@@ -7322,10 +7341,10 @@ static int ast_add_extension2_lockopt(struct ast_context *con,
p += strlen(label) + 1;
}
tmp->name = p;
- p += ext_strncpy(p, extension, strlen(extension) + 1, 0) + 1;
+ p += ext_strncpy(p, extension, strlen(extension) + 1, 0);
if (exten_fluff) {
tmp->exten = p;
- p += ext_strncpy(p, extension, strlen(extension) + 1, 1) + 1;
+ p += ext_strncpy(p, extension, strlen(extension) + 1 - exten_fluff, 1);
} else {
/* no fluff, we don't need a copy. */
tmp->exten = tmp->name;
@@ -7335,10 +7354,10 @@ static int ast_add_extension2_lockopt(struct ast_context *con,
/* Blank callerid and NULL callerid are two SEPARATE things. Do NOT confuse the two!!! */
if (callerid) {
- p += ext_strncpy(p, callerid, strlen(callerid) + 1, 0) + 1;
+ p += ext_strncpy(p, callerid, strlen(callerid) + 1, 0);
if (callerid_fluff) {
tmp->cidmatch = p;
- p += ext_strncpy(p, callerid, strlen(callerid) + 1, 1) + 1;
+ p += ext_strncpy(p, callerid, strlen(callerid) + 1 - callerid_fluff, 1);
}
tmp->matchcid = AST_EXT_MATCHCID_ON;
} else {