[svn-commits] russell: trunk r61702 - in /trunk: channels/ funcs/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Fri Apr 20 14:12:53 MST 2007


Author: russell
Date: Fri Apr 20 16:12:53 2007
New Revision: 61702

URL: http://svn.digium.com/view/asterisk?view=rev&rev=61702
Log:
Merge changes from team/russell/iax2_osp

This set of changes adds OSP support to chan_iax2.  However, I have modified
the patch a bit from what was submitted.  You now use the CHANNEL() function
to get and set the OSP token for IAX2.

(issue #8531, reported by and original patch by homesick, patch updated by me)

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

Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=61702&r1=61701&r2=61702
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Fri Apr 20 16:12:53 2007
@@ -577,6 +577,8 @@
 		AST_STRING_FIELD(accountcode);
 		AST_STRING_FIELD(mohinterpret);
 		AST_STRING_FIELD(mohsuggest);
+		/*! received OSP token */
+		AST_STRING_FIELD(osptoken);
 	);
 	
 	/*! permitted authentication methods */
@@ -851,6 +853,9 @@
 static void destroy_user(struct iax2_user *user);
 static void prune_peers(void);
 
+static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
+static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
+
 static const struct ast_channel_tech iax2_tech = {
 	.type = "IAX2",
 	.description = tdesc,
@@ -874,6 +879,8 @@
 	.bridge = iax2_bridge,
 	.transfer = iax2_transfer,
 	.fixup = iax2_fixup,
+	.func_channel_read = acf_channel_read,
+	.func_channel_write = acf_channel_write,
 };
 
 static void insert_idle_thread(struct iax2_thread *thread)
@@ -2890,6 +2897,11 @@
 	struct parsed_dial_string pds;
 	struct create_addr_info cai;
 	struct ast_var_t *var;
+	const char* osp_token_ptr;
+	unsigned int osp_token_length;
+	unsigned char osp_block_index;
+	unsigned int osp_block_length;
+	unsigned char osp_buffer[256];
 
 	if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
 		ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
@@ -3009,6 +3021,25 @@
 		iaxs[callno]->pingtime = autokill / 2;
 		iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
 	}
+
+	/* Check if there is an OSP token set by IAXCHANINFO function */
+	osp_token_ptr = iaxs[callno]->osptoken;
+	if (!ast_strlen_zero(osp_token_ptr)) {
+		if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
+			osp_block_index = 0;
+			while (osp_token_length > 0) {
+				osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
+				osp_buffer[0] = osp_block_index;
+				memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
+				iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
+				osp_block_index++;
+				osp_token_ptr += osp_block_length;
+				osp_token_length -= osp_block_length;
+			} 
+		} else
+			ast_log(LOG_WARNING, "OSP token is too long\n");
+	} else if (option_debug && iaxdebug)
+		ast_log(LOG_DEBUG, "OSP token is undefined\n");
 
 	/* send the command using the appropriate socket for this peer */
 	iaxs[callno]->sockfd = cai.sockfd;
@@ -6316,6 +6347,36 @@
 	iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
 }
 
+static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies) 
+{
+	int i;
+	unsigned int length, offset = 0;
+	char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
+
+	for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
+		length = ies->ospblocklength[i];
+		if (length != 0) {
+			if (length > IAX_MAX_OSPBLOCK_SIZE) {
+				/* OSP token block length wrong, clear buffer */
+				offset = 0;
+				break;
+			} else {
+				memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
+				offset += length;
+			}
+		} else {
+			break;
+		}
+	}
+	*(full_osptoken + offset) = '\0';
+	if (strlen(full_osptoken) != offset) {
+		/* OSP token length wrong, clear buffer */
+		*full_osptoken = '\0';
+	}
+
+	ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
+}
+
 static int socket_read(int *id, int fd, short events, void *cbdata)
 {
 	struct iax2_thread *thread;
@@ -6940,6 +7001,8 @@
 					ast_mutex_lock(&iaxsl[fr->callno]);
 				} else
 					exists = 0;
+				/* Get OSP token if it does exist */
+				save_osptoken(fr, &ies);
 				if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
 					if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
 						memset(&ied0, 0, sizeof(ied0));
@@ -9824,6 +9887,61 @@
 	"\n"
 };
 
+static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
+{
+	struct chan_iax2_pvt *pvt;
+	unsigned int callno;
+	int res = 0;
+
+	if (!chan || chan->tech != &iax2_tech) {
+		ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
+		return -1;
+	}
+
+	callno = PTR_TO_CALLNO(chan->tech_pvt);
+	ast_mutex_lock(&iaxsl[callno]);
+	if (!(pvt = iaxs[callno])) {
+		ast_mutex_unlock(&iaxsl[callno]);
+		return -1;
+	}
+
+	if (!strcasecmp(args, "osptoken"))
+		ast_string_field_set(pvt, osptoken, value);
+	else
+		res = -1;
+
+	ast_mutex_unlock(&iaxsl[callno]);
+
+	return res;
+}
+
+static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
+{
+	struct chan_iax2_pvt *pvt;
+	unsigned int callno;
+	int res = 0;
+
+	if (!chan || chan->tech != &iax2_tech) {
+		ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
+		return -1;
+	}
+
+	callno = PTR_TO_CALLNO(chan->tech_pvt);
+	ast_mutex_lock(&iaxsl[callno]);
+	if (!(pvt = iaxs[callno])) {
+		ast_mutex_unlock(&iaxsl[callno]);
+		return -1;
+	}
+
+	if (!strcasecmp(args, "osptoken"))
+		ast_copy_string(buf, pvt->osptoken, buflen);
+	else
+		res = -1;
+
+	ast_mutex_unlock(&iaxsl[callno]);
+
+	return res;
+}
 
 /*! \brief Part of the device state notification system ---*/
 static int iax2_devicestate(void *data) 

Modified: trunk/channels/iax2-parser.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/iax2-parser.c?view=diff&rev=61702&r1=61701&r2=61702
==============================================================================
--- trunk/channels/iax2-parser.c (original)
+++ trunk/channels/iax2-parser.c Fri Apr 20 16:12:53 2007
@@ -264,6 +264,7 @@
 	{ IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int },
 	{ IAX_IE_RR_OOO, "RR_OUTOFORDER", dump_int },
 	{ IAX_IE_VARIABLE, "VARIABLE", dump_string },
+	{ IAX_IE_OSPTOKEN, "OSPTOKEN" },
 };
 
 static struct iax2_ie prov_ies[] = {
@@ -617,6 +618,7 @@
 	int ie;
 	char tmp[256], *tmp2;
 	struct ast_variable *var, *var2, *prev;
+	unsigned int count;
 	memset(ies, 0, (int)sizeof(struct iax_ies));
 	ies->msgcount = -1;
 	ies->firmwarever = -1;
@@ -930,6 +932,15 @@
 				ies->vars = var;
 			}
 			break;
+		case IAX_IE_OSPTOKEN:
+			if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) {
+				ies->osptokenblock[count] = (char *)data + 2 + 1;
+				ies->ospblocklength[count] = len - 1;
+			} else {
+				snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
+				errorf(tmp);
+			}
+			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=61702&r1=61701&r2=61702
==============================================================================
--- trunk/channels/iax2-parser.h (original)
+++ trunk/channels/iax2-parser.h Fri Apr 20 16:12:53 2007
@@ -74,6 +74,8 @@
 	unsigned int rr_dropped;
 	unsigned int rr_ooo;
 	struct ast_variable *vars;
+	char *osptokenblock[IAX_MAX_OSPBLOCK_NUM];
+	unsigned int ospblocklength[IAX_MAX_OSPBLOCK_NUM];
 };
 
 #define DIRECTION_INGRESS 1

Modified: trunk/channels/iax2.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/iax2.h?view=diff&rev=61702&r1=61701&r2=61702
==============================================================================
--- trunk/channels/iax2.h (original)
+++ trunk/channels/iax2.h Fri Apr 20 16:12:53 2007
@@ -129,7 +129,12 @@
 #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_IE_OSPTOKEN				53		/* OSP token */
+
+#define IAX_MAX_OSPBLOCK_SIZE		254		/* Max OSP token block size, 255 bytes - 1 byte OSP token block index */
+#define IAX_MAX_OSPBLOCK_NUM		4
+#define IAX_MAX_OSPTOKEN_SIZE		(IAX_MAX_OSPBLOCK_SIZE * IAX_MAX_OSPBLOCK_NUM)
+#define IAX_MAX_OSPBUFF_SIZE		(IAX_MAX_OSPTOKEN_SIZE + 16)
 
 #define IAX_AUTH_PLAINTEXT			(1 << 0)
 #define IAX_AUTH_MD5				(1 << 1)

Modified: trunk/funcs/func_channel.c
URL: http://svn.digium.com/view/asterisk/trunk/funcs/func_channel.c?view=diff&rev=61702&r1=61701&r2=61702
==============================================================================
--- trunk/funcs/func_channel.c (original)
+++ trunk/funcs/func_channel.c Fri Apr 20 16:12:53 2007
@@ -182,6 +182,9 @@
 		"    rtt                   Round trip time\n"
 		"    all                   All statistics (in a form suited to logging, but not for parsing)\n"
 		"\n"
+		"chan_iax2 provides the following additional options:\n"
+		"R/W    osptoken           Get or set the OSP token information for a call\n"
+		"\n"
 		"Additional items may be available from the channel driver providing\n"
 		"the channel; see its documentation for details.\n"
 		"\n"



More information about the svn-commits mailing list