[svn-commits] rmudgett: branch 1.4 r2077 - /branches/1.4/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Oct 21 12:30:44 CDT 2010


Author: rmudgett
Date: Thu Oct 21 12:30:41 2010
New Revision: 2077

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=2077
Log:
Extract the layer 2 link structure out of struct pri.

This completes the layer 2 link and Q.931 call control restructuring.
Some code is now simplified since there is only one D channel control
structure and the amount of allocated memory is reduced.

Modified:
    branches/1.4/pri.c
    branches/1.4/pri_aoc.c
    branches/1.4/pri_cc.c
    branches/1.4/pri_facility.c
    branches/1.4/pri_internal.h
    branches/1.4/pri_q921.h
    branches/1.4/pri_q931.h
    branches/1.4/prisched.c
    branches/1.4/q921.c
    branches/1.4/q931.c

Modified: branches/1.4/pri.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri.c?view=diff&rev=2077&r1=2076&r2=2077
==============================================================================
--- branches/1.4/pri.c (original)
+++ branches/1.4/pri.c Thu Oct 21 12:30:41 2010
@@ -225,7 +225,6 @@
 	if (!ctrl || timer < 0 || PRI_MAX_TIMERS <= timer || value < 0) {
 		return -1;
 	}
-	ctrl = PRI_MASTER(ctrl);
 	ctrl->timers[timer] = value;
 	return 0;
 }
@@ -235,7 +234,6 @@
 	if (!ctrl || timer < 0 || PRI_MAX_TIMERS <= timer) {
 		return -1;
 	}
-	ctrl = PRI_MASTER(ctrl);
 	return ctrl->timers[timer];
 }
 
@@ -285,34 +283,150 @@
 	return res;
 }
 
-void __pri_free_tei(struct pri * p)
-{
-	if (p) {
+/*!
+ * \brief Destroy the given link.
+ *
+ * \param link Q.921 link to destroy.
+ *
+ * \return Nothing
+ */
+void pri_link_destroy(struct q921_link *link)
+{
+	if (link) {
 		struct q931_call *call;
 
-		call = p->dummy_call;
+		call = link->dummy_call;
 		if (call) {
 			pri_schedule_del(call->pri, call->retranstimer);
 			call->retranstimer = 0;
 			pri_call_apdu_queue_cleanup(call);
 		}
-		free(p->msg_line);
-		free(p->sched.timer);
-		free(p);
-	}
-}
-
-struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri)
+		free(link);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Initialize the layer 2 link structure.
+ *
+ * \param ctrl D channel controller.
+ * \param link Q.921 link to initialize.
+ * \param sapi SAPI new link is to use.
+ * \param tei TEI new link is to use.
+ *
+ * \note It is assumed that the link has already been memset to zero.
+ *
+ * \return Nothing
+ */
+static void pri_link_init(struct pri *ctrl, struct q921_link *link, int sapi, int tei)
+{
+	link->ctrl = ctrl;
+	link->sapi = sapi;
+	link->tei = tei;
+}
+
+/*!
+ * \brief Create a new layer 2 link.
+ *
+ * \param ctrl D channel controller.
+ * \param sapi SAPI new link is to use.
+ * \param tei TEI new link is to use.
+ *
+ * \retval link on success.
+ * \retval NULL on error.
+ */
+struct q921_link *pri_link_new(struct pri *ctrl, int sapi, int tei)
+{
+	struct link_dummy *dummy_link;
+	struct q921_link *link;
+
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_GR303_EOC:
+	case PRI_SWITCH_GR303_TMC:
+		link = calloc(1, sizeof(*link));
+		if (!link) {
+			return NULL;
+		}
+		dummy_link = NULL;
+		break;
+	default:
+		dummy_link = calloc(1, sizeof(*dummy_link));
+		if (!dummy_link) {
+			return NULL;
+		}
+		link = &dummy_link->link;
+		break;
+	}
+
+	pri_link_init(ctrl, link, sapi, tei);
+	if (dummy_link) {
+		/* Initialize the dummy call reference call record. */
+		link->dummy_call = &dummy_link->dummy_call;
+		q931_init_call_record(link, link->dummy_call, Q931_DUMMY_CALL_REFERENCE);
+	}
+
+	q921_start(link);
+
+	return link;
+}
+
+/*!
+ * \internal
+ * \brief Destroy the given D channel controller.
+ *
+ * \param ctrl D channel control to destroy.
+ *
+ * \return Nothing
+ */
+static void pri_ctrl_destroy(struct pri *ctrl)
+{
+	if (ctrl) {
+		struct q931_call *call;
+
+		if (ctrl->link.tei == Q921_TEI_GROUP
+			&& ctrl->link.sapi == Q921_SAPI_LAYER2_MANAGEMENT
+			&& ctrl->localtype == PRI_CPE) {
+			/* This dummy call was borrowed from the specific TEI link. */
+			call = NULL;
+		} else {
+			call = ctrl->link.dummy_call;
+		}
+		if (call) {
+			pri_schedule_del(call->pri, call->retranstimer);
+			call->retranstimer = 0;
+			pri_call_apdu_queue_cleanup(call);
+		}
+		free(ctrl->msg_line);
+		free(ctrl->sched.timer);
+		free(ctrl);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Create a new D channel control structure.
+ *
+ * \param fd D channel file descriptor if no callback functions supplied.
+ * \param node Switch NET/CPE type
+ * \param switchtype ISDN switch type
+ * \param rd D channel read callback function
+ * \param wr D channel write callback function
+ * \param userdata Callback function parameter
+ * \param tei TEI new link is to use.
+ * \param bri TRUE if interface is BRI
+ *
+ * \retval ctrl on success.
+ * \retval NULL on error.
+ */
+static struct pri *pri_ctrl_new(int fd, int node, int switchtype, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri)
 {
 	int create_dummy_call;
 	struct d_ctrl_dummy *dummy_ctrl;
-	struct pri *p;
+	struct pri *ctrl;
 
 	switch (switchtype) {
 	case PRI_SWITCH_GR303_EOC:
 	case PRI_SWITCH_GR303_TMC:
-	case PRI_SWITCH_GR303_TMC_SWITCHING:
-	case PRI_SWITCH_GR303_EOC_PATH:
 		create_dummy_call = 0;
 		break;
 	default:
@@ -332,96 +446,75 @@
 		if (!dummy_ctrl) {
 			return NULL;
 		}
-		p = &dummy_ctrl->ctrl;
+		ctrl = &dummy_ctrl->ctrl;
 	} else {
-		p = calloc(1, sizeof(*p));
-		if (!p) {
+		ctrl = calloc(1, sizeof(*ctrl));
+		if (!ctrl) {
 			return NULL;
 		}
 		dummy_ctrl = NULL;
 	}
-	if (!master) {
-		/* This is the master record. */
-		p->msg_line = calloc(1, sizeof(*p->msg_line));
-		if (!p->msg_line) {
-			free(p);
+	ctrl->msg_line = calloc(1, sizeof(*ctrl->msg_line));
+	if (!ctrl->msg_line) {
+		free(ctrl);
+		return NULL;
+	}
+
+	ctrl->bri = bri;
+	ctrl->fd = fd;
+	ctrl->read_func = rd;
+	ctrl->write_func = wr;
+	ctrl->userdata = userdata;
+	ctrl->localtype = node;
+	ctrl->switchtype = switchtype;
+	ctrl->cref = 1;
+	ctrl->nsf = PRI_NSF_NONE;
+	ctrl->callpool = &ctrl->localpool;
+	pri_default_timers(ctrl, switchtype);
+#ifdef LIBPRI_COUNTERS
+	ctrl->q921_rxcount = 0;
+	ctrl->q921_txcount = 0;
+	ctrl->q931_rxcount = 0;
+	ctrl->q931_txcount = 0;
+#endif
+	switch (switchtype) {
+	case PRI_SWITCH_GR303_EOC:
+		ctrl->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
+		pri_link_init(ctrl, &ctrl->link, Q921_SAPI_GR303_EOC, Q921_TEI_GR303_EOC_OPS);
+		ctrl->link.next = pri_link_new(ctrl, Q921_SAPI_GR303_EOC, Q921_TEI_GR303_EOC_PATH);
+		if (!ctrl->link.next) {
+			pri_ctrl_destroy(ctrl);
 			return NULL;
 		}
-	}
-
-	p->bri = bri;
-	p->fd = fd;
-	p->read_func = rd;
-	p->write_func = wr;
-	p->userdata = userdata;
-	p->localtype = node;
-	p->switchtype = switchtype;
-	p->cref = 1;
-	p->sapi = (tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL;
-	p->tei = tei;
-	p->nsf = PRI_NSF_NONE;
-	p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
-	p->master = master;
-	p->callpool = &p->localpool;
-	pri_default_timers(p, switchtype);
-	if (master) {
-		pri_set_debug(p, master->debug);
-		pri_set_inbanddisconnect(p, master->acceptinbanddisconnect);
-		if (master->sendfacility)
-			pri_facility_enable(p);
-	}
-#ifdef LIBPRI_COUNTERS
-	p->q921_rxcount = 0;
-	p->q921_txcount = 0;
-	p->q931_rxcount = 0;
-	p->q931_txcount = 0;
-#endif
+		break;
+	case PRI_SWITCH_GR303_TMC:
+		ctrl->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
+		pri_link_init(ctrl, &ctrl->link, Q921_SAPI_GR303_TMC_CALLPROC, Q921_TEI_GR303_TMC_CALLPROC);
+		ctrl->link.next = pri_link_new(ctrl, Q921_SAPI_GR303_TMC_SWITCHING, Q921_TEI_GR303_TMC_SWITCHING);
+		if (!ctrl->link.next) {
+			pri_ctrl_destroy(ctrl);
+			return NULL;
+		}
+		break;
+	default:
+		ctrl->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
+		pri_link_init(ctrl, &ctrl->link,
+			(tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL,
+			tei);
+		break;
+	}
 	if (dummy_ctrl) {
 		/* Initialize the dummy call reference call record. */
-		dummy_ctrl->ctrl.dummy_call = &dummy_ctrl->dummy_call;
-		q931_init_call_record(&dummy_ctrl->ctrl, dummy_ctrl->ctrl.dummy_call,
+		ctrl->link.dummy_call = &dummy_ctrl->dummy_call;
+		q931_init_call_record(&ctrl->link, ctrl->link.dummy_call,
 			Q931_DUMMY_CALL_REFERENCE);
 	}
-	switch (switchtype) {
-	case PRI_SWITCH_GR303_EOC:
-		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-		p->sapi = Q921_SAPI_GR303_EOC;
-		p->tei = Q921_TEI_GR303_EOC_OPS;
-		p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0);
-		if (!p->subchannel) {
-			free(p);
-			return NULL;
-		}
-		break;
-	case PRI_SWITCH_GR303_TMC:
-		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-		p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
-		p->tei = Q921_TEI_GR303_TMC_CALLPROC;
-		p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0);
-		if (!p->subchannel) {
-			free(p);
-			return NULL;
-		}
-		break;
-	case PRI_SWITCH_GR303_TMC_SWITCHING:
-		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-		p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
-		p->tei = Q921_TEI_GR303_TMC_SWITCHING;
-		break;
-	case PRI_SWITCH_GR303_EOC_PATH:
-		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-		p->sapi = Q921_SAPI_GR303_EOC;
-		p->tei = Q921_TEI_GR303_EOC_PATH;
-		break;
-	default:
-		break;
-	}
-
-	if (p->tei == Q921_TEI_GROUP && p->sapi == Q921_SAPI_LAYER2_MANAGEMENT
-		&& p->localtype == PRI_CPE) {
-		p->subchannel = __pri_new_tei(-1, p->localtype, p->switchtype, p, NULL, NULL, NULL, Q921_TEI_PRI, 1);
-		if (!p->subchannel) {
-			free(p);
+
+	if (ctrl->link.tei == Q921_TEI_GROUP && ctrl->link.sapi == Q921_SAPI_LAYER2_MANAGEMENT
+		&& ctrl->localtype == PRI_CPE) {
+		ctrl->link.next = pri_link_new(ctrl, Q921_SAPI_CALL_CTRL, Q921_TEI_PRI);
+		if (!ctrl->link.next) {
+			pri_ctrl_destroy(ctrl);
 			return NULL;
 		}
 		/*
@@ -430,11 +523,12 @@
 		 * to broadcast messages on the dummy call or to broadcast any
 		 * messages for that matter.
 		 */
-		p->dummy_call = p->subchannel->dummy_call;
-	} else
-		q921_start(p);
-	
-	return p;
+		ctrl->link.dummy_call = ctrl->link.next->dummy_call;
+	} else {
+		q921_start(&ctrl->link);
+	}
+
+	return ctrl;
 }
 
 void pri_call_set_useruser(q931_call *c, const char *userchars)
@@ -470,15 +564,15 @@
 
 struct pri *pri_new(int fd, int nodetype, int switchtype)
 {
-	return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0);
+	return pri_ctrl_new(fd, nodetype, switchtype, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0);
 }
 
 struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype)
 {
 	if (ptpmode)
-		return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1);
+		return pri_ctrl_new(fd, nodetype, switchtype, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1);
 	else
-		return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1);
+		return pri_ctrl_new(fd, nodetype, switchtype, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1);
 }
 
 struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
@@ -487,7 +581,7 @@
 		io_read = __pri_read;
 	if (!io_write)
 		io_write = __pri_write;
-	return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 0);
+	return pri_ctrl_new(fd, nodetype, switchtype, io_read, io_write, userdata, Q921_TEI_PRI, 0);
 }
 
 struct pri *pri_new_bri_cb(int fd, int ptpmode, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
@@ -499,9 +593,9 @@
 		io_write = __pri_write;
 	}
 	if (ptpmode) {
-		return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 1);
+		return pri_ctrl_new(fd, nodetype, switchtype, io_read, io_write, userdata, Q921_TEI_PRI, 1);
 	} else {
-		return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_GROUP, 1);
+		return pri_ctrl_new(fd, nodetype, switchtype, io_read, io_write, userdata, Q921_TEI_GROUP, 1);
 	}
 }
 
@@ -647,16 +741,12 @@
 	if (!pri)
 		return;
 	pri->debug = debug;
-	if (pri->subchannel)
-		pri_set_debug(pri->subchannel, debug);
 }
 
 int pri_get_debug(struct pri *pri)
 {
 	if (!pri)
 		return -1;
-	if (pri->subchannel)
-		return pri_get_debug(pri->subchannel);
 	return pri->debug;
 }
 
@@ -665,9 +755,6 @@
 	if (!pri)
 		return;
 	pri->sendfacility = 1;
-	if (pri->subchannel)
-		pri_facility_enable(pri->subchannel);
-	return;
 }
 
 int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
@@ -763,7 +850,6 @@
 void pri_connect_ack_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->manual_connect_ack = enable ? 1 : 0;
 	}
 }
@@ -1162,7 +1248,6 @@
 void pri_hangup_fix_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->hangup_fix_enabled = enable ? 1 : 0;
 	}
 }
@@ -1348,9 +1433,6 @@
 	int added_length;
 	va_list ap;
 
-	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
-	}
 	if (!ctrl || !ctrl->msg_line) {
 		/* Just have to do it the old way. */
 		va_start(ap, fmt);
@@ -1412,7 +1494,7 @@
 	vsnprintf(tmp, sizeof(tmp), fmt, ap);
 	va_end(ap);
 	if (__pri_error)
-		__pri_error(pri ? PRI_MASTER(pri) : NULL, tmp);
+		__pri_error(pri, tmp);
 	else
 		fputs(tmp, stderr);
 }
@@ -1478,7 +1560,7 @@
 	size_t used;
 #ifdef LIBPRI_COUNTERS
 	struct q921_frame *f;
-	struct pri *link;
+	struct q921_link *link;
 	unsigned q921outstanding;
 #endif
 	unsigned idx;
@@ -1493,8 +1575,6 @@
 	if (!buf) {
 		return NULL;
 	}
-
-	ctrl = PRI_MASTER(ctrl);
 
 	/* Might be nice to format these a little better */
 	used = 0;
@@ -1507,9 +1587,9 @@
 	used = pri_snprintf(buf, used, buf_size, "Q931 TX: %d\n", ctrl->q931_txcount);
 	used = pri_snprintf(buf, used, buf_size, "Q921 RX: %d\n", ctrl->q921_rxcount);
 	used = pri_snprintf(buf, used, buf_size, "Q921 TX: %d\n", ctrl->q921_txcount);
-	for (link = ctrl; link; link = link->subchannel) {
+	for (link = &ctrl->link; link; link = link->next) {
 		q921outstanding = 0;
-		for (f = link->txqueue; f; f = f->next) {
+		for (f = link->tx_queue; f; f = f->next) {
 			++q921outstanding;
 		}
 		used = pri_snprintf(buf, used, buf_size, "Q921 Outstanding: %u (TEI=%d)\n",
@@ -1702,7 +1782,6 @@
 void pri_transfer_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->transfer_support = enable ? 1 : 0;
 	}
 }
@@ -1710,7 +1789,6 @@
 void pri_hold_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->hold_support = enable ? 1 : 0;
 	}
 }
@@ -1775,7 +1853,6 @@
 void pri_reroute_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->deflection_support = enable ? 1 : 0;
 	}
 }
@@ -1827,7 +1904,6 @@
 void pri_cc_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->cc_support = enable ? 1 : 0;
 	}
 }
@@ -1835,7 +1911,6 @@
 void pri_cc_recall_mode(struct pri *ctrl, int mode)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->cc.option.recall_mode = mode ? 1 : 0;
 	}
 }
@@ -1843,7 +1918,6 @@
 void pri_cc_retain_signaling_req(struct pri *ctrl, int signaling_retention)
 {
 	if (ctrl && 0 <= signaling_retention && signaling_retention < 3) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->cc.option.signaling_retention_req = signaling_retention;
 	}
 }
@@ -1851,7 +1925,6 @@
 void pri_cc_retain_signaling_rsp(struct pri *ctrl, int signaling_retention)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->cc.option.signaling_retention_rsp = signaling_retention ? 1 : 0;
 	}
 }

Modified: branches/1.4/pri_aoc.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_aoc.c?view=diff&rev=2077&r1=2076&r2=2077
==============================================================================
--- branches/1.4/pri_aoc.c (original)
+++ branches/1.4/pri_aoc.c Thu Oct 21 12:30:41 2010
@@ -212,7 +212,7 @@
 	struct pri_subcommand *subcmd;
 	int request;
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		send_facility_error(ctrl, call, invoke->invoke_id, ROSE_ERROR_Gen_NotSubscribed);
 		return;
 	}
@@ -439,7 +439,7 @@
 {
 	struct pri_subcommand *subcmd;
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		return;
 	}
 	subcmd = q931_alloc_subcommand(ctrl);
@@ -470,7 +470,7 @@
 {
 	struct pri_subcommand *subcmd;
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		return;
 	}
 	subcmd = q931_alloc_subcommand(ctrl);
@@ -535,7 +535,7 @@
 {
 	struct pri_subcommand *subcmd;
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		return;
 	}
 	subcmd = q931_alloc_subcommand(ctrl);
@@ -577,7 +577,7 @@
 {
 	struct pri_subcommand *subcmd;
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		return;
 	}
 	subcmd = q931_alloc_subcommand(ctrl);
@@ -760,7 +760,7 @@
 {
 	struct pri_subcommand *subcmd;
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		return;
 	}
 	subcmd = q931_alloc_subcommand(ctrl);
@@ -828,7 +828,7 @@
 		}
 	}
 
-	if (!PRI_MASTER(ctrl)->aoc_support) {
+	if (!ctrl->aoc_support) {
 		return;
 	}
 	subcmd = q931_alloc_subcommand(ctrl);
@@ -869,7 +869,6 @@
 void pri_aoc_events_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->aoc_support = enable ? 1 : 0;
 	}
 }

Modified: branches/1.4/pri_cc.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_cc.c?view=diff&rev=2077&r1=2076&r2=2077
==============================================================================
--- branches/1.4/pri_cc.c (original)
+++ branches/1.4/pri_cc.c Thu Oct 21 12:30:41 2010
@@ -61,7 +61,6 @@
 {
 	struct pri_cc_record *cc_record;
 
-	ctrl = PRI_MASTER(ctrl);
 	for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
 		if (cc_record->ccbs_reference_id == reference_id) {
 			/* Found the record */
@@ -85,7 +84,6 @@
 {
 	struct pri_cc_record *cc_record;
 
-	ctrl = PRI_MASTER(ctrl);
 	for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
 		if (cc_record->call_linkage_id == linkage_id) {
 			/* Found the record */
@@ -110,7 +108,6 @@
 {
 	struct pri_cc_record *cc_record;
 
-	ctrl = PRI_MASTER(ctrl);
 	for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
 		if (cc_record->record_id == cc_id) {
 			/* Found the record */
@@ -234,7 +231,6 @@
 	struct q931_party_address addr_a;
 	struct q931_party_address addr_b;
 
-	ctrl = PRI_MASTER(ctrl);
 	addr_a = *party_a;
 	addr_b = *party_b;
 	for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
@@ -266,7 +262,6 @@
 	long reference_id;
 	long first_id;
 
-	ctrl = PRI_MASTER(ctrl);
 	ctrl->cc.last_reference_id = (ctrl->cc.last_reference_id + 1) & 0x7F;
 	reference_id = ctrl->cc.last_reference_id;
 	first_id = reference_id;
@@ -298,7 +293,6 @@
 	long linkage_id;
 	long first_id;
 
-	ctrl = PRI_MASTER(ctrl);
 	ctrl->cc.last_linkage_id = (ctrl->cc.last_linkage_id + 1) & 0x7F;
 	linkage_id = ctrl->cc.last_linkage_id;
 	first_id = linkage_id;
@@ -330,7 +324,6 @@
 	long record_id;
 	long first_id;
 
-	ctrl = PRI_MASTER(ctrl);
 	record_id = ++ctrl->cc.last_record_id;
 	first_id = record_id;
 	while (pri_cc_find_by_id(ctrl, record_id)) {
@@ -386,7 +379,6 @@
 	}
 	pri_cc_disassociate_signaling_link(doomed);
 
-	ctrl = PRI_MASTER(ctrl);
 	for (prev = &ctrl->cc.pool, current = ctrl->cc.pool; current;
 		prev = &current->next, current = current->next) {
 		if (current == doomed) {
@@ -413,7 +405,6 @@
 	struct pri_cc_record *cc_record;
 	long record_id;
 
-	ctrl = PRI_MASTER(ctrl);
 	record_id = pri_cc_new_id(ctrl);
 	if (record_id < 0) {
 		return NULL;
@@ -424,7 +415,7 @@
 	}
 
 	/* Initialize the new record */
-	cc_record->master = ctrl;
+	cc_record->ctrl = ctrl;
 	cc_record->record_id = record_id;
 	cc_record->call_linkage_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
 	cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
@@ -975,7 +966,7 @@
 
 	//msg.args.qsig.CcbsRequest.can_retain_service = 0;
 
-	switch (PRI_MASTER(ctrl)->cc.option.signaling_retention_req) {
+	switch (ctrl->cc.option.signaling_retention_req) {
 	case 0:/* Want release signaling link. */
 		cc_record->option.retain_signaling_link = 0;
 
@@ -1954,7 +1945,6 @@
 	struct q931_party_number party_a_number;
 	const struct pri_cc_record *cc_record;
 	unsigned char *new_pos;
-	struct pri *master;
 	unsigned idx;
 
 	pos = facility_encode_header(ctrl, pos, end, NULL);
@@ -1966,8 +1956,7 @@
 	msg.invoke_id = invoke->invoke_id;
 	msg.operation = invoke->operation;
 
-	master = PRI_MASTER(ctrl);
-	msg.args.etsi.CCBSInterrogate.recall_mode = master->cc.option.recall_mode;
+	msg.args.etsi.CCBSInterrogate.recall_mode = ctrl->cc.option.recall_mode;
 
 	/* Convert the given party A number. */
 	q931_party_number_init(&party_a_number);
@@ -1979,7 +1968,7 @@
 
 	/* Build the CallDetails list. */
 	idx = 0;
-	for (cc_record = master->cc.pool; cc_record; cc_record = cc_record->next) {
+	for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
 		if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID
 			|| (!cc_record->is_ccnr) != (invoke->operation == ROSE_ETSI_CCBSInterrogate)) {
 			/*
@@ -2087,7 +2076,7 @@
 {
 	int encode_result;
 
-	if (!PRI_MASTER(ctrl)->cc_support) {
+	if (!ctrl->cc_support) {
 		/* Call completion is disabled. */
 		return send_facility_error(ctrl, call, invoke->invoke_id,
 			ROSE_ERROR_Gen_NotSubscribed);
@@ -2134,7 +2123,7 @@
 {
 	struct pri_cc_record *cc_record;
 
-	if (!PRI_MASTER(ctrl)->cc_support) {
+	if (!ctrl->cc_support) {
 		/* Call completion is disabled. */
 		send_facility_error(ctrl, call, invoke->invoke_id,
 			ROSE_ERROR_Gen_NotSubscribed);
@@ -2191,7 +2180,7 @@
 		/* Ignore CC request message since it did not come in on the correct message. */
 		return;
 	}
-	if (!PRI_MASTER(ctrl)->cc_support) {
+	if (!ctrl->cc_support) {
 		/* Call completion is disabled. */
 		rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
 			ROSE_ERROR_Gen_NotSubscribed);
@@ -2270,7 +2259,6 @@
  */
 void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
 {
-	struct pri *master;
 	struct pri_cc_record *cc_record;
 	struct q931_party_address party_a;
 	struct q931_party_address party_b;
@@ -2279,8 +2267,7 @@
 		/* Ignore CC request message since it did not come in on the correct message. */
 		return;
 	}
-	master = PRI_MASTER(ctrl);
-	if (!master->cc_support) {
+	if (!ctrl->cc_support) {
 		/* Call completion is disabled. */
 		rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
 			ROSE_ERROR_QSIG_LongTermRejection);
@@ -2302,7 +2289,7 @@
 	rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
 		&invoke->args.qsig.CcbsRequest.subaddr_b);
 
-	cc_record = pri_cc_find_by_addressing(master, &party_a, &party_b,
+	cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
 		invoke->args.qsig.CcbsRequest.q931ie.length,
 		invoke->args.qsig.CcbsRequest.q931ie.contents);
 	if (!cc_record || cc_record->state != CC_STATE_AVAILABLE) {
@@ -2321,7 +2308,7 @@
 	} else {
 		/* The originator does not care.  Do how we are configured. */
 		cc_record->option.retain_signaling_link =
-			master->cc.option.signaling_retention_rsp;
+			ctrl->cc.option.signaling_retention_rsp;
 	}
 	if (!cc_record->party_a.number.valid || cc_record->party_a.number.str[0] == '\0') {
 		/*
@@ -2805,7 +2792,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->t_retention = 0;
-	q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
+	q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
 }
 
 /*!
@@ -2857,7 +2844,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
-	q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
+	q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
 }
 
 /*!
@@ -2911,7 +2898,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->t_supervision = 0;
-	q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
+	q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
 }
 
 /*!
@@ -2991,7 +2978,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->t_recall = 0;
-	q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
+	q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
 }
 
 /*!
@@ -3755,7 +3742,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->t_indirect = 0;
-	q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_rsp_a);
+	q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_rsp_a);
 }
 
 /*!
@@ -3904,7 +3891,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->t_indirect = 0;
-	q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_a);
+	q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_a);
 }
 
 /*!
@@ -4261,7 +4248,7 @@
 	struct pri_cc_record *cc_record = data;
 
 	cc_record->t_indirect = 0;
-	q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_HANGUP_SIGNALING);
+	q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_HANGUP_SIGNALING);
 }
 
 /*!
@@ -6850,7 +6837,7 @@
 				break;
 			}
 			cc_record->call_linkage_id = linkage_id;
-			cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
+			cc_record->signaling = ctrl->link.dummy_call;
 		} else {
 			cc_record = pri_cc_new_record(ctrl, call);
 			if (!cc_record) {
@@ -6894,7 +6881,7 @@
 		return;
 	}
 
-	if (!PRI_MASTER(ctrl)->cc_support) {
+	if (!ctrl->cc_support) {
 		/*
 		 * Blocking the cc-available event effectively
 		 * disables call completion for outgoing calls.

Modified: branches/1.4/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_facility.c?view=diff&rev=2077&r1=2076&r2=2077
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Thu Oct 21 12:30:41 2010
@@ -1859,7 +1859,7 @@
 		if (!BRI_NT_PTMP(ctrl)) {
 			return -1;
 		}
-		call = PRI_MASTER(ctrl)->dummy_call;
+		call = ctrl->link.dummy_call;
 		if (!call) {
 			return -1;
 		}
@@ -3825,7 +3825,6 @@
 void pri_mcid_enable(struct pri *ctrl, int enable)
 {
 	if (ctrl) {
-		ctrl = PRI_MASTER(ctrl);
 		ctrl->mcid_support = enable ? 1 : 0;
 	}
 }
@@ -3882,7 +3881,7 @@
 		 * Look for the original invocation message on the
 		 * broadcast dummy call reference call first.
 		 */
-		orig_call = PRI_MASTER(ctrl)->dummy_call;
+		orig_call = ctrl->link.dummy_call;
 		if (orig_call) {
 			apdu = pri_call_apdu_find(orig_call, reject->invoke_id);
 		}
@@ -3966,7 +3965,7 @@
 		 * Look for the original invocation message on the
 		 * broadcast dummy call reference call first.
 		 */
-		orig_call = PRI_MASTER(ctrl)->dummy_call;
+		orig_call = ctrl->link.dummy_call;
 		if (orig_call) {
 			apdu = pri_call_apdu_find(orig_call, error->invoke_id);
 		}
@@ -4042,7 +4041,7 @@
 		 * Look for the original invocation message on the
 		 * broadcast dummy call reference call first.
 		 */
-		orig_call = PRI_MASTER(ctrl)->dummy_call;
+		orig_call = ctrl->link.dummy_call;
 		if (orig_call) {
 			apdu = pri_call_apdu_find(orig_call, result->invoke_id);
 		}
@@ -4099,7 +4098,7 @@
 		break;
 #endif	/* Not handled yet */
 	case ROSE_ETSI_CallDeflection:
-		if (!PRI_MASTER(ctrl)->deflection_support) {
+		if (!ctrl->deflection_support) {
 			send_facility_error(ctrl, call, invoke->invoke_id,
 				ROSE_ERROR_Gen_NotSubscribed);
 			break;
@@ -4167,7 +4166,7 @@
 			&deflection);
 		break;
 	case ROSE_ETSI_CallRerouting:
-		if (!PRI_MASTER(ctrl)->deflection_support) {
+		if (!ctrl->deflection_support) {
 			send_facility_error(ctrl, call, invoke->invoke_id,
 				ROSE_ERROR_Gen_NotSubscribed);
 			break;
@@ -4365,7 +4364,7 @@
 		break;
 #endif	/* Not handled yet */
 	case ROSE_ETSI_EctExecute:
-		if (!PRI_MASTER(ctrl)->transfer_support) {
+		if (!ctrl->transfer_support) {
 			send_facility_error(ctrl, call, invoke->invoke_id,
 				ROSE_ERROR_Gen_NotSubscribed);
 			break;
@@ -4390,7 +4389,7 @@
 		break;
 #endif	/* Not handled yet */
 	case ROSE_ETSI_EctLinkIdRequest:
-		if (!PRI_MASTER(ctrl)->transfer_support) {
+		if (!ctrl->transfer_support) {
 			send_facility_error(ctrl, call, invoke->invoke_id,
 				ROSE_ERROR_Gen_ResourceUnavailable);
 			break;
@@ -4430,7 +4429,7 @@
 		break;
 #endif	/* defined(STATUS_REQUEST_PLACE_HOLDER) */
 	case ROSE_ETSI_CallInfoRetain:
-		if (!PRI_MASTER(ctrl)->cc_support) {
+		if (!ctrl->cc_support) {
 			/*
 			 * Blocking the cc-available event effectively
 			 * disables call completion for outgoing calls.
@@ -4445,7 +4444,7 @@
 		if (!cc_record) {
 			break;
 		}
-		cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
+		cc_record->signaling = ctrl->link.dummy_call;
 		/*
 		 * Since we received this facility, we will not be allocating any
 		 * reference and linkage id's.
@@ -4645,7 +4644,7 @@
 		pri_cc_event(ctrl, call, cc_record, CC_EVENT_REMOTE_USER_FREE);
 		break;
 	case ROSE_ETSI_CCBS_T_Available:
-		if (!PRI_MASTER(ctrl)->cc_support) {
+		if (!ctrl->cc_support) {
 			/*
 			 * Blocking the cc-available event effectively
 			 * disables call completion for outgoing calls.
@@ -4669,7 +4668,7 @@
 			/* Don't even dignify this with a response. */
 			break;
 		}
-		if (!PRI_MASTER(ctrl)->mcid_support) {
+		if (!ctrl->mcid_support) {
 			send_facility_error(ctrl, call, invoke->invoke_id,
 				ROSE_ERROR_Gen_NotSubscribed);
 			break;
@@ -4877,7 +4876,7 @@
 		break;
 #endif	/* Not handled yet */
 	case ROSE_QSIG_CallRerouting:
-		if (!PRI_MASTER(ctrl)->deflection_support) {
+		if (!ctrl->deflection_support) {
 			send_facility_error(ctrl, call, invoke->invoke_id,
 				ROSE_ERROR_Gen_NotSubscribed);
 			break;

Modified: branches/1.4/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_internal.h?view=diff&rev=2077&r1=2076&r2=2077
==============================================================================
--- branches/1.4/pri_internal.h (original)
+++ branches/1.4/pri_internal.h Thu Oct 21 12:30:41 2010
@@ -76,8 +76,6 @@
 	void *userdata;
 	/*! Accumulated pri_message() line. (Valid in master record only) */
 	struct pri_msg_line *msg_line;
-	struct pri *subchannel;	/* Sub-channel if appropriate */
-	struct pri *master;		/* Master channel if appropriate */
 	struct {
 		/*! Dynamically allocated array of timers that can grow as needed. */
 		struct pri_sched *timer;
@@ -93,9 +91,8 @@
 	int localtype;		/* Local network type (unknown, network, cpe) */
 	int remotetype;		/* Remote network type (unknown, network, cpe) */
 
-	int sapi;
-	int tei;
-	int protodisc;
+	int protodisc;	/* Layer 3 protocol discriminator */
+
 	unsigned int nfas:1;/* TRUE if this D channel is involved with an NFAS group */
 	unsigned int bri:1;
 	unsigned int acceptinbanddisconnect:1;	/* Should we allow inband progress after DISCONNECT? */
@@ -112,57 +109,23 @@
 	unsigned int manual_connect_ack:1;/* TRUE if the CONNECT_ACKNOWLEDGE is sent with API call */
 	unsigned int mcid_support:1;/* TRUE if the upper layer supports MCID */
 
-	/* MDL variables */
-	int mdl_error;
-	int mdl_error_state;
-	int mdl_timer;
-	int mdl_free_me;
-
-	/* Q.921 State */
-	int q921_state;	
-	int RC;
-	int peer_rx_busy:1;
-	int own_rx_busy:1;
-	int acknowledge_pending:1;
-	int reject_exception:1;
-
-	int v_s;			/* Next N(S) for transmission */
-	int v_a;			/* Last acknowledged frame */
-	int v_r;			/* Next frame expected to be received */
+	/*! Layer 2 link control for D channel. */
+	struct q921_link link;
 	
 	int cref;			/* Next call reference value */
-	
-	int l3initiated;
-
-	/* Various timers */
-	int t203_timer;		/* Max idle time */
-	int t202_timer;
-	int n202_counter;
-	int ri;
-	int t200_timer;		/* T-200 retransmission timer */
+
 	/* All ISDN Timer values */
 	int timers[PRI_MAX_TIMERS];
 
 	/* Used by scheduler */
-	struct timeval tv;
 	int schedev;
 	pri_event ev;		/* Static event thingy */
 	/*! Subcommands for static event thingy. */
 	struct pri_subcommands subcmds;
 	
-	/* Q.921 Re-transmission queue */
-	struct q921_frame *txqueue;
-	
 	/* Q.931 calls */
-	q931_call **callpool;
-	q931_call *localpool;
-
-	/*!
-	 * \brief Q.931 Dummy call reference call associated with this TEI.
-	 * \note If present then this call is allocated as part of the
-	 * D channel control structure.
-	 */
-	q931_call *dummy_call;
+	struct q931_call **callpool;
+	struct q931_call *localpool;
 
 #ifdef LIBPRI_COUNTERS
 	/* q921/q931 packet counters */
@@ -370,10 +333,6 @@
 	int aoc_charging_request;
 };
 
-/* Internal switch types */
-#define PRI_SWITCH_GR303_EOC_PATH	19
-#define PRI_SWITCH_GR303_TMC_SWITCHING	20
-
 #define Q931_MAX_TEI	8
 
 /*! \brief Incoming call transfer states. */
@@ -449,7 +408,7 @@
 /* q931_call datastructure */
 struct q931_call {
 	struct pri *pri;	/* D channel controller (master) */
-	struct pri *link;	/* Q.921 link associated with this call. */
+	struct q921_link *link;	/* Q.921 link associated with this call. */
 	struct q931_call *next;
 	int cr;				/* Call Reference */
 	/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
@@ -592,7 +551,7 @@
 	int is_link_id_valid;
 
 	/* Bridged call info */
-	q931_call *bridged_call;        /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
+	struct q931_call *bridged_call;        /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
 
 	int changestatus;		/* SERVICE message changestatus */
 	int reversecharge;		/* Reverse charging indication:
@@ -746,8 +705,8 @@
 struct pri_cc_record {
 	/*! Next call-completion record in the list */
 	struct pri_cc_record *next;
-	/*! Master D channel control structure. */
-	struct pri *master;
+	/*! D channel control structure. */
+	struct pri *ctrl;
 	/*! Original call that is offered CC availability. (NULL if no longer exists.) */
 	struct q931_call *original_call;
 	/*!
@@ -883,6 +842,14 @@
 	struct q931_call dummy_call;
 };
 
+/*! Layer 2 link control structure with associated dummy call reference record. */
+struct link_dummy {
+	/*! Layer 2 control structure. Must be first in the structure. */
+	struct q921_link link;
+	/*! Dummy call reference call record. */
+	struct q931_call dummy_call;
+};
+
 /*!
  * \brief Check if the given call ptr is valid and gripe if not.
  *
@@ -912,10 +879,10 @@
 
 void libpri_copy_string(char *dst, const char *src, size_t size);
 
-struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri);
-void __pri_free_tei(struct pri *p);
-
-void q931_init_call_record(struct pri *link, struct q931_call *call, int cr);
+void pri_link_destroy(struct q921_link *link);
+struct q921_link *pri_link_new(struct pri *ctrl, int sapi, int tei);
+
+void q931_init_call_record(struct q921_link *link, struct q931_call *call, int cr);
 
 void pri_sr_init(struct pri_sr *req);
 
@@ -985,21 +952,6 @@
 void q931_cc_indirect(struct pri *ctrl, struct pri_cc_record *cc_record, void (*func)(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record));
 
 /*!
- * \brief Get the master PRI control structure.
- *
- * \param ctrl D channel controller.
- *
- * \return Master PRI control structure.
- */
-static inline struct pri *PRI_MASTER(struct pri *ctrl)
-{
-	while (ctrl->master) {
-		ctrl = ctrl->master;
-	}
-	return ctrl;
-}
-
-/*!
  * \brief Determine if layer 2 is in BRI NT PTMP mode.
  *
  * \param ctrl D channel controller.
@@ -1011,10 +963,8 @@
 {
 	struct pri *my_ctrl = (struct pri *) ctrl;
 
-	/* Check master control structure */
-	my_ctrl = PRI_MASTER(my_ctrl);
 	return my_ctrl->bri && my_ctrl->localtype == PRI_NETWORK
-		&& my_ctrl->tei == Q921_TEI_GROUP;
+		&& my_ctrl->link.tei == Q921_TEI_GROUP;
 }
 
 /*!
@@ -1029,10 +979,8 @@
 {
 	struct pri *my_ctrl = (struct pri *) ctrl;
 
-	/* Check master control structure */
-	my_ctrl = PRI_MASTER(my_ctrl);
 	return my_ctrl->bri && my_ctrl->localtype == PRI_CPE
-		&& my_ctrl->tei == Q921_TEI_GROUP;
+		&& my_ctrl->link.tei == Q921_TEI_GROUP;
 }
 
 /*!
@@ -1047,8 +995,6 @@
 {
 	struct pri *my_ctrl = (struct pri *) ctrl;
 
-	/* Check master control structure */
-	my_ctrl = PRI_MASTER(my_ctrl);
 	return my_ctrl->localtype == PRI_NETWORK;
 }
 
@@ -1064,8 +1010,6 @@
 {
 	struct pri *my_ctrl = (struct pri *) ctrl;
 
-	/* Check master control structure */
-	my_ctrl = PRI_MASTER(my_ctrl);
 	return my_ctrl->localtype == PRI_CPE;
 }
 
@@ -1081,9 +1025,7 @@
 {
 	struct pri *my_ctrl = (struct pri *) ctrl;
 
-	/* Check master control structure */
-	my_ctrl = PRI_MASTER(my_ctrl);
-	return my_ctrl->tei == Q921_TEI_PRI;
+	return my_ctrl->link.tei == Q921_TEI_PRI;
 }
 
 /*!
@@ -1098,9 +1040,7 @@
 {
 	struct pri *my_ctrl = (struct pri *) ctrl;
 
-	/* Check master control structure */
-	my_ctrl = PRI_MASTER(my_ctrl);
-	return my_ctrl->tei == Q921_TEI_GROUP;
+	return my_ctrl->link.tei == Q921_TEI_GROUP;
 }
 
 #define Q931_DUMMY_CALL_REFERENCE	-1
@@ -1112,14 +1052,13 @@
  * \retval TRUE if given call is a dummy call.
  * \retval FALSE otherwise.
  */
-static inline int q931_is_dummy_call(const q931_call *call)
+static inline int q931_is_dummy_call(const struct q931_call *call)
 {
 	return (call->cr == Q931_DUMMY_CALL_REFERENCE) ? 1 : 0;
 }
 
 static inline short get_invokeid(struct pri *ctrl)
 {
-	ctrl = PRI_MASTER(ctrl);
 	return ++ctrl->last_invoke;
 }
 

Modified: branches/1.4/pri_q921.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_q921.h?view=diff&rev=2077&r1=2076&r2=2077
==============================================================================
--- branches/1.4/pri_q921.h (original)
+++ branches/1.4/pri_q921.h Thu Oct 21 12:30:41 2010
@@ -180,6 +180,66 @@
 	Q921_TIMER_RECOVERY = 8,
 } q921_state;
 
+/*! \brief Q.921 link controller structure */
+struct q921_link {
+	/*! Next Q.921 link in the chain. */
+	struct q921_link *next;
+	/*! D channel controller associated with this link. */
+	struct pri *ctrl;
+
+	/*!
+	 * \brief Q.931 Dummy call reference call associated with this TEI.
+	 *
+	 * \note If present then this call is allocated with the D
+	 * channel control structure or the link control structure
+	 * unless this is the TE PTMP broadcast TEI or a GR303 link.
+	 */
+	struct q931_call *dummy_call;
+
+	/*! Q.921 Re-transmission queue */
+	struct q921_frame *tx_queue;
+
+	/*! Q.921 State */
+	enum q921_state state;
+
+	/*! Service Access Profile Identifier (SAPI) of this link */
+	int sapi;
+	/*! Terminal Endpoint Identifier (TEI) of this link */
+	int tei;
+	/*! TEI assignment random indicator. */
+	int ri;
+
+	/*! V(A) - Next I-frame sequence number needing ack */
+	int v_a;
+	/*! V(S) - Next I-frame sequence number to send */
+	int v_s;
+	/*! V(R) - Next I-frame sequence number expected to receive */
+	int v_r;
+
+	/* Various timers */
+
+	/*! T-200 retransmission timer */
+	int t200_timer;
+	/*! Retry Count (T200) */
+	int RC;
+	int t202_timer;
+	int n202_counter;
+	/*! Max idle time */
+	int t203_timer;
+
+	/* MDL variables */
+	int mdl_timer;
+	int mdl_error;
+	enum q921_state mdl_error_state;
+	unsigned int mdl_free_me:1;
+
+	unsigned int peer_rx_busy:1;
+	unsigned int own_rx_busy:1;
+	unsigned int acknowledge_pending:1;
+	unsigned int reject_exception:1;
+	unsigned int l3_initiated:1;
+};
+
 static inline int Q921_ADD(int a, int b)
 {
 	return (a + b) % 128;
@@ -189,15 +249,15 @@
 extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx);
 
 /* Bring up the D-channel */
-void q921_start(struct pri *link);
+void q921_start(struct q921_link *link);
 
 //extern void q921_reset(struct pri *pri, int reset_iqueue);
 
 extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
 

[... 2160 lines stripped ...]



More information about the svn-commits mailing list