mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-22 21:36:28 +00:00
IAX2 remote variables - Bug 7619
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51123 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -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);
|
||||
|
@@ -39,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/frame.h"
|
||||
#include "asterisk/utils.h"
|
||||
#include "asterisk/unaligned.h"
|
||||
#include "asterisk/config.h"
|
||||
#include "asterisk/lock.h"
|
||||
#include "asterisk/threadstorage.h"
|
||||
|
||||
@@ -262,6 +263,7 @@ static struct iax2_ie {
|
||||
{ IAX_IE_RR_DELAY, "RR_DELAY", dump_short },
|
||||
{ IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int },
|
||||
{ IAX_IE_RR_OOO, "RR_OUTOFORDER", dump_int },
|
||||
{ IAX_IE_VARIABLE, "VARIABLE", dump_string },
|
||||
};
|
||||
|
||||
static struct iax2_ie prov_ies[] = {
|
||||
@@ -613,7 +615,8 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
|
||||
/* Parse data into information elements */
|
||||
int len;
|
||||
int ie;
|
||||
char tmp[256];
|
||||
char tmp[256], *tmp2;
|
||||
struct ast_variable *var, *var2, *prev;
|
||||
memset(ies, 0, (int)sizeof(struct iax_ies));
|
||||
ies->msgcount = -1;
|
||||
ies->firmwarever = -1;
|
||||
@@ -898,6 +901,35 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
|
||||
ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_VARIABLE:
|
||||
ast_copy_string(tmp, (char *)data + 2, len + 1);
|
||||
tmp2 = strchr(tmp, '=');
|
||||
if (tmp2)
|
||||
*tmp2++ = '\0';
|
||||
else
|
||||
tmp2 = "";
|
||||
/* Existing variable or new variable? */
|
||||
for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) {
|
||||
if (strcmp(tmp, var2->name) == 0) {
|
||||
int len = strlen(var2->value) + strlen(tmp2) + 1;
|
||||
char *tmp3 = alloca(len);
|
||||
snprintf(tmp3, len, "%s%s", var2->value, tmp2);
|
||||
var = ast_variable_new(tmp, tmp3);
|
||||
var->next = var2->next;
|
||||
if (prev)
|
||||
prev->next = var;
|
||||
else
|
||||
ies->vars = var;
|
||||
free(var2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!var2) {
|
||||
var = ast_variable_new(tmp, tmp2);
|
||||
var->next = ies->vars;
|
||||
ies->vars = var;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
|
||||
outputf(tmp);
|
||||
|
@@ -73,6 +73,7 @@ struct iax_ies {
|
||||
unsigned short rr_delay;
|
||||
unsigned int rr_dropped;
|
||||
unsigned int rr_ooo;
|
||||
struct ast_variable *vars;
|
||||
};
|
||||
|
||||
#define DIRECTION_INGRESS 1
|
||||
|
@@ -128,6 +128,7 @@
|
||||
#define IAX_IE_RR_DELAY 49 /* Max playout delay for received frames (in ms) u16 */
|
||||
#define IAX_IE_RR_DROPPED 50 /* Dropped frames (presumably by jitterbuf) u32 */
|
||||
#define IAX_IE_RR_OOO 51 /* Frames received Out of Order u32 */
|
||||
#define IAX_IE_VARIABLE 52 /* Remote variables */
|
||||
|
||||
|
||||
#define IAX_AUTH_PLAINTEXT (1 << 0)
|
||||
|
Reference in New Issue
Block a user