diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/channel.c | 41 | ||||
-rw-r--r-- | main/pbx.c | 55 |
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 { |