diff options
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r-- | channels/chan_iax2.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 2026f92e8..aa5c791b1 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -2884,6 +2884,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); struct parsed_dial_string pds; struct create_addr_info cai; + struct ast_var_t *var; if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); @@ -3007,6 +3008,19 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) /* send the command using the appropriate socket for this peer */ iaxs[callno]->sockfd = cai.sockfd; + /* Add remote vars */ + AST_LIST_TRAVERSE(&c->varshead, var, entries) { + if (!strncmp(ast_var_name(var), "~IAX2~", strlen("~IAX2~"))) { + char tmp[256]; + int i; + /* Automatically divide the value up into sized chunks */ + for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) - strlen("~IAX2~") + 1)) { + snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var) + strlen("~IAX2~"), ast_var_value(var) + i); + iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); + } + } + } + /* Transmit the string in a "NEW" request */ send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); @@ -6447,6 +6461,33 @@ static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, s return 1; } +static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + const char *value; + char tmp[256]; + snprintf(tmp, sizeof(tmp), "~IAX2~%s", data); + value = pbx_builtin_getvar_helper(chan, tmp); + ast_copy_string(buf, value ? value : "", len); + return 0; +} + +static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *varname, const char *value) +{ + char tmp[256]; + /* Inherit forever */ + snprintf(tmp, sizeof(tmp), "__~IAX2~%s", varname); + pbx_builtin_setvar_helper(chan, tmp, value); + return 0; +} + +static struct ast_custom_function iaxvar_function = { + .name = "IAXVAR", + .synopsis = "Sets or retrieves a remote variable", + .syntax = "IAXVAR(<varname>)", + .read = acf_iaxvar_read, + .write = acf_iaxvar_write, +}; + static int socket_process(struct iax2_thread *thread) { struct sockaddr_in sin; @@ -6753,6 +6794,9 @@ retryowner: } else { if (option_debug) ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); + /* Free remote variables (if any) */ + if (ies.vars) + ast_variables_destroy(ies.vars); ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } @@ -6996,6 +7040,18 @@ retryowner: if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) iax2_destroy(fr->callno); + else if (ies.vars) { + struct ast_variable *var, *prev = NULL; + char tmp[256]; + for (var = ies.vars; var; var = var->next) { + if (prev) + free(prev); + prev = var; + snprintf(tmp, sizeof(tmp), "__~IAX2~%s", var->name); + pbx_builtin_setvar_helper(c, tmp, var->value); + } + ies.vars = NULL; + } } else { ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); /* If this is a TBD call, we're ready but now what... */ @@ -7586,6 +7642,10 @@ retryowner2: iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); } + /* Free remote variables (if any) */ + if (ies.vars) + ast_variables_destroy(ies.vars); + /* Don't actually pass these frames along */ if ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_TXCNT) && @@ -10025,6 +10085,7 @@ static int __unload_module(void) static int unload_module(void) { ast_custom_function_unregister(&iaxpeer_function); + ast_custom_function_unregister(&iaxvar_function); return __unload_module(); } @@ -10038,6 +10099,7 @@ static int load_module(void) struct iax2_peer *peer = NULL; ast_custom_function_register(&iaxpeer_function); + ast_custom_function_register(&iaxvar_function); iax_set_output(iax_debug_output); iax_set_error(iax_error_output); |