[asterisk-commits] tilghman: branch group/issue10217 r201098 - /team/group/issue10217/channels/
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list