[svn-commits] tilghman: branch group/issue10217 r201098 - /team/group/issue10217/channels/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jun 16 14:48:47 CDT 2009


Author: tilghman
Date: Tue Jun 16 14:48:43 2009
New Revision: 201098

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=201098
Log:
Committing, because I'm in the middle of a thunderstorm, and I'm cautious like that.

Modified:
    team/group/issue10217/channels/chan_dahdi.c

Modified: team/group/issue10217/channels/chan_dahdi.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/issue10217/channels/chan_dahdi.c?view=diff&rev=201098&r1=201097&r2=201098
==============================================================================
--- team/group/issue10217/channels/chan_dahdi.c (original)
+++ team/group/issue10217/channels/chan_dahdi.c Tue Jun 16 14:48:43 2009
@@ -1493,6 +1493,18 @@
 	return conf;
 }
 
+#ifdef HAVE_PRI
+static void *lowlayercompat_free(void *data);
+static void lowlayercompat_duplicate(void *data);
+static void lowlayercompat_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
+
+static struct ast_datastore_info lowlayercompat_info = {
+	.type = "LOWLAYERCOMPAT",
+	.destroy = lowlayercompat_free,
+	.duplicate = lowlayercompat_duplicate,
+	.chan_fixup = lowlayercompat_fixup,
+};
+#endif
 
 static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);
 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
@@ -1532,6 +1544,139 @@
 	.func_channel_read = dahdi_func_read,
 	.func_channel_write = dahdi_func_write,
 };
+
+#ifdef HAVE_PRI
+struct lowlayercompat {
+	struct ast_channel *master;
+	struct pri_lowlayercompat llc[4];
+};
+
+static void lowlayercompat_free(void *data)
+{
+	struct lowlayercompat *llc = data;
+	if (llc->master) {
+		llc->master = ast_channel_unref(llc->master);
+	}
+	ast_free(llc);
+}
+
+static void *lowlayercompat_duplicate(void *data)
+{
+	struct lowlayercompat *old_llc = data, *new_llc = ast_calloc(1, sizeof(*new_llc));
+	if (!new_llc) {
+		return NULL;
+	}
+	/* Nothing really more than a copy, except that we add a reference to the channel. */
+	new_llc->master = ast_channel_ref(old_llc->master);
+	memcpy(new_llc->llc, old_llc->llc, sizeof(new_llc->llc));
+	return new_llc;
+}
+
+static void lowlayercompat_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
+{
+	struct lowlayercompat *llc = data;
+	if (llc->master == old_chan) {
+		/* If the master is the old channel, then we change the reference to the master, otherwise do nothing. */
+		llc->master = ast_channel_ref(new_chan);
+		ast_channel_unref(old_chan);
+	}
+}
+
+static void add_lowlayercompat(struct ast_channel *chan, struct pri_call *call)
+{
+	struct ast_datastore *ds = ast_datastore_alloc(&lowlayercompat_info, NULL);
+	struct lowlayercompat *llc = ast_calloc(1, sizeof(*llc));
+
+	if (!ds || !llc) {
+		ast_free(ds);
+		ast_free(llc);
+
+		/* TODO Signal negotiation failed */
+		return;
+	}
+
+	ds->data = llc;
+	ds->inheritance = 1;
+
+	/* TODO Populate LLC structure */
+
+	ast_channel_datastore_add(chan, ds);
+}
+
+static const char *transcap2txt(int tc)
+{
+	return cap[tc];
+}
+
+static int llc_read(struct ast_channel *chan, const char *cmd, char *data, struct ast_str  **buf, ssize_t len)
+{
+	/* LOWLEVELCOMPAT(rec,name) */
+	struct ast_datastore *ds = ast_channel_datastore_find(chan, &lowlevelcompat_info, NULL);
+	struct lowlevelcompat *llc = ds ? ds->data : NULL;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(record);
+		AST_APP_ARG(name);
+	);
+	int recnum;
+	const char *value = "";
+
+	if (!llc) {
+		return -1;
+	}
+
+	AST_STANDARD_APP_ARGS(args, s);
+	if (args.argc != 2) {
+		ast_log(LOG_ERROR, "LOWLEVELCOMPAT requires 2 arguments: (<record>,<name>)\n");
+		return -1;
+	}
+
+	if ((recnum = atoi(args.record)) < 1 || recnum > 4) {
+		ast_log(LOG_ERROR, "Record number must be between 1 and 4 ('%s')\n", args.record);
+		return -1;
+	}
+
+	if (!strcasecmp(args.name, "transcapability")) {
+		const char *cap[32] = { "SPEECH", "", "", "", "", "", "", "",
+			"DIGITAL", "RESTRICTED", "", "", "", "", "", "",
+			"3.1K", "DIGITAL_W_TONES", "", "", "", "", "", "",
+			"VIDEO" };
+		value = cap[llc->llc[recnum].transcapability];
+	} else if (!strcasecmp(args.name, "transmode")) {
+		value = llc->llc[recnum].transmode ? "PACKET" : "CIRCUIT";
+	} else if (!strcasecmp(args.name, "transrate")) {
+		if (llc->llc[recnum].transmode == 0) {
+			value = "PACKET";
+		} else if (llc->llc[recnum].transmode == 0x18) {
+			char rate[12];
+			snprintf(rate, sizeof(rate), "%dK", 64 * llc->llc[recnum].transmultiplier);
+			value = rate;
+		} else {
+			const char *rate[32] = { "", "", "", "", "", "", "", "",
+				"", "", "", "", "", "", "", "",
+				"64K", "128K", "", "384K", "", "1536K", "", "1920K" };
+			value = rate[llc->llc[recnum].transrate];
+		}
+	} else if (!strcasecmp(args.name, "transmultiplier")) {
+		char rate[12];
+		snprintf(rate, sizeof(rate), "%d", llc->llc[recnum].transmultiplier);
+		value = rate;
+	} /* TODO */
+	ast_str_set(buf, len, "%s", value);
+	return 0;
+}
+
+static int llc_write(struct ast_channel *chan, const char *cmd, char *s, const char *value)
+{
+	/* TODO */
+}
+
+static struct ast_custom_function llc_function = {
+	.name = "LOWLEVELCOMPAT",
+	.read2 = llc_read,
+	.write = llc_write,
+};
+
+#endif
 
 #ifdef HAVE_PRI
 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)




More information about the svn-commits mailing list