[asterisk-commits] tilghman: trunk r51123 - /trunk/channels/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Jan 16 01:39:00 MST 2007


Author: tilghman
Date: Tue Jan 16 02:38:59 2007
New Revision: 51123

URL: http://svn.digium.com/view/asterisk?view=rev&rev=51123
Log:
IAX2 remote variables - Bug 7619

Modified:
    trunk/channels/chan_iax2.c
    trunk/channels/iax2-parser.c
    trunk/channels/iax2-parser.h
    trunk/channels/iax2.h

Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=51123&r1=51122&r2=51123
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Tue Jan 16 02:38:59 2007
@@ -2884,6 +2884,7 @@
 	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);
@@ -3006,6 +3007,19 @@
 
 	/* 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 @@
 	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 @@
 						} 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 @@
 								
 								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 @@
 				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)
 {
 	ast_custom_function_unregister(&iaxpeer_function);
+	ast_custom_function_unregister(&iaxvar_function);
 	return __unload_module();
 }
 
@@ -10038,6 +10099,7 @@
 	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);

Modified: trunk/channels/iax2-parser.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/iax2-parser.c?view=diff&rev=51123&r1=51122&r2=51123
==============================================================================
--- trunk/channels/iax2-parser.c (original)
+++ trunk/channels/iax2-parser.c Tue Jan 16 02:38:59 2007
@@ -39,6 +39,7 @@
 #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 @@
 	{ 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 @@
 	/* 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 @@
 				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);

Modified: trunk/channels/iax2-parser.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/iax2-parser.h?view=diff&rev=51123&r1=51122&r2=51123
==============================================================================
--- trunk/channels/iax2-parser.h (original)
+++ trunk/channels/iax2-parser.h Tue Jan 16 02:38:59 2007
@@ -73,6 +73,7 @@
 	unsigned short rr_delay;
 	unsigned int rr_dropped;
 	unsigned int rr_ooo;
+	struct ast_variable *vars;
 };
 
 #define DIRECTION_INGRESS 1

Modified: trunk/channels/iax2.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/iax2.h?view=diff&rev=51123&r1=51122&r2=51123
==============================================================================
--- trunk/channels/iax2.h (original)
+++ trunk/channels/iax2.h Tue Jan 16 02:38:59 2007
@@ -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)



More information about the asterisk-commits mailing list