[libpri-commits] rmudgett: branch 1.4 r2063 - in /branches/1.4: pri_q921.h q921.c

SVN commits to the libpri project libpri-commits at lists.digium.com
Thu Oct 21 11:14:57 CDT 2010


Author: rmudgett
Date: Thu Oct 21 11:14:54 2010
New Revision: 2063

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=2063
Log:
Logically separate Q.921 TEI link processing from D channel control.

This is in anticipation of extracting a layer 2 link structure out of
struct pri.

Also fixes Q.921 timer value access.  The timer access must always be on
the D channel control structure (Master).

Modified:
    branches/1.4/pri_q921.h
    branches/1.4/q921.c

Modified: branches/1.4/pri_q921.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_q921.h?view=diff&rev=2063&r1=2062&r2=2063
==============================================================================
--- branches/1.4/pri_q921.h (original)
+++ branches/1.4/pri_q921.h Thu Oct 21 11:14:54 2010
@@ -189,7 +189,7 @@
 extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx);
 
 /* Bring up the D-channel */
-extern void q921_start(struct pri *pri);
+void q921_start(struct pri *link);
 
 //extern void q921_reset(struct pri *pri, int reset_iqueue);
 
@@ -197,7 +197,7 @@
 
 extern int q921_transmit_iframe(struct pri *pri, int tei, void *buf, int len, int cr);
 
-extern int q921_transmit_uiframe(struct pri *pri, void *buf, int len);
+int q921_transmit_uiframe(struct pri *link, void *buf, int len);
 
 extern pri_event *q921_dchannel_up(struct pri *pri);
 

Modified: branches/1.4/q921.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/q921.c?view=diff&rev=2063&r1=2062&r2=2063
==============================================================================
--- branches/1.4/q921.c (original)
+++ branches/1.4/q921.c Thu Oct 21 11:14:54 2010
@@ -45,20 +45,19 @@
  */
 //#define RANDOM_DROPS	1
 
-#define Q921_INIT(ctrl, hf) do { \
+#define Q921_INIT(link, hf) do { \
 	memset(&(hf),0,sizeof(hf)); \
-	(hf).h.sapi = (ctrl)->sapi; \
+	(hf).h.sapi = (link)->sapi; \
 	(hf).h.ea1 = 0; \
 	(hf).h.ea2 = 1; \
-	(hf).h.tei = (ctrl)->tei; \
+	(hf).h.tei = (link)->tei; \
 } while(0)
 
-static void reschedule_t200(struct pri *ctrl);
-static void q921_dump_pri(struct pri *ctrl, char direction_tag);
-static void q921_establish_data_link(struct pri *ctrl);
-static void q921_mdl_error(struct pri *ctrl, char error);
-static void q921_mdl_remove(struct pri *ctrl);
-static void q921_restart_ptp_link_if_needed(struct pri *ctrl);
+static void q921_dump_pri(struct pri *link, char direction_tag);
+static void q921_establish_data_link(struct pri *link);
+static void q921_mdl_error(struct pri *link, char error);
+static void q921_mdl_remove(struct pri *link);
+static void q921_restart_ptp_link_if_needed(struct pri *link);
 
 /*!
  * \internal
@@ -92,8 +91,11 @@
 	return "Unknown state";
 }
 
-static void q921_setstate(struct pri *ctrl, int newstate)
-{
+static void q921_setstate(struct pri *link, int newstate)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
 		/*
 		 * Suppress displaying these state transitions:
@@ -102,14 +104,14 @@
 		 * Q921 keeps flipping back and forth between these two states
 		 * when it has nothing better to do.
 		 */
-		switch (ctrl->q921_state) {
+		switch (link->q921_state) {
 		case Q921_MULTI_FRAME_ESTABLISHED:
 		case Q921_TIMER_RECOVERY:
 			switch (newstate) {
 			case Q921_MULTI_FRAME_ESTABLISHED:
 			case Q921_TIMER_RECOVERY:
 				/* Suppress displaying this state transition. */
-				ctrl->q921_state = newstate;
+				link->q921_state = newstate;
 				return;
 			default:
 				break;
@@ -118,43 +120,41 @@
 		default:
 			break;
 		}
-		if (ctrl->q921_state != newstate) {
+		if (link->q921_state != newstate) {
 			pri_message(ctrl, "Changing from state %d(%s) to %d(%s)\n",
-				ctrl->q921_state, q921_state2str(ctrl->q921_state),
+				link->q921_state, q921_state2str(link->q921_state),
 				newstate, q921_state2str(newstate));
 		}
 	}
-	ctrl->q921_state = newstate;
-}
-
-static void q921_discard_iqueue(struct pri *ctrl)
+	link->q921_state = newstate;
+}
+
+static void q921_discard_iqueue(struct pri *link)
 {
 	struct q921_frame *f, *p;
 
-	f = ctrl->txqueue;
+	f = link->txqueue;
 	while (f) {
 		p = f;
 		f = f->next;
 		/* Free frame */
 		free(p);
 	}
-	ctrl->txqueue = NULL;
+	link->txqueue = NULL;
 }
 
 static int q921_transmit(struct pri *ctrl, q921_h *h, int len) 
 {
 	int res;
 
-	ctrl = PRI_MASTER(ctrl);
-
 #ifdef RANDOM_DROPS
-   if (!(random() % 3)) {
-         pri_message(ctrl, " === Dropping Packet ===\n");
-         return 0;
-   }
-#endif   
+	if (!(random() % 3)) {
+		pri_message(ctrl, " === Dropping Packet ===\n");
+		return 0;
+	}
+#endif
 #ifdef LIBPRI_COUNTERS
-	ctrl->q921_txcount++;      
+	ctrl->q921_txcount++;
 #endif
 	/* Just send it raw */
 	if (ctrl->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
@@ -168,14 +168,17 @@
 	return 0;
 }
 
-static void q921_send_tei(struct pri *ctrl, int message, int ri, int ai, int iscommand)
+static void q921_send_tei(struct pri *link, int message, int ri, int ai, int iscommand)
 {
 	q921_u *f;
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	if (!(f = calloc(1, sizeof(*f) + 5)))
 		return;
 
-	Q921_INIT(ctrl, *f);
+	Q921_INIT(link, *f);
 	f->h.c_r = (ctrl->localtype == PRI_NETWORK) ? iscommand : !iscommand;
 	f->ft = Q921_FRAMETYPE_U;
 	f->data[0] = 0x0f;	/* Management entity */
@@ -190,56 +193,62 @@
 	free(f);
 }
 
-static void t202_expire(void *vpri)
-{
-	struct pri *ctrl = (struct pri *)vpri;
+static void t202_expire(void *vlink)
+{
+	struct pri *link = vlink;
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	/* Start the TEI request timer. */
-	pri_schedule_del(ctrl, ctrl->t202_timer);
-	ctrl->t202_timer =
-		pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T202], t202_expire, ctrl);
-
-	++ctrl->n202_counter;
-	if (!ctrl->t202_timer || ctrl->n202_counter > ctrl->timers[PRI_TIMER_N202]) {
-		if (!ctrl->t202_timer) {
+	pri_schedule_del(ctrl, link->t202_timer);
+	link->t202_timer =
+		pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T202], t202_expire, link);
+
+	++link->n202_counter;
+	if (!link->t202_timer || link->n202_counter > ctrl->timers[PRI_TIMER_N202]) {
+		if (!link->t202_timer) {
 			pri_error(ctrl, "Could not start T202 timer.");
 		} else {
-			pri_schedule_del(ctrl, ctrl->t202_timer);
-			ctrl->t202_timer = 0;
+			pri_schedule_del(ctrl, link->t202_timer);
+			link->t202_timer = 0;
 		}
 		pri_error(ctrl, "Unable to receive TEI from network in state %d(%s)!\n",
-			ctrl->q921_state, q921_state2str(ctrl->q921_state));
-		switch (ctrl->q921_state) {
+			link->q921_state, q921_state2str(link->q921_state));
+		switch (link->q921_state) {
 		case Q921_ASSIGN_AWAITING_TEI:
 			break;
 		case Q921_ESTABLISH_AWAITING_TEI:
-			q921_discard_iqueue(ctrl);
+			q921_discard_iqueue(link);
 			/* DL-RELEASE indication */
-			q931_dl_event(ctrl, Q931_DL_EVENT_DL_RELEASE_IND);
+			q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND);
 			break;
 		default:
 			break;
 		}
-		q921_setstate(ctrl, Q921_TEI_UNASSIGNED);
+		q921_setstate(link, Q921_TEI_UNASSIGNED);
 		return;
 	}
 
 	/* Send TEI request */
-	ctrl->ri = random() % 65535;
-	q921_send_tei(PRI_MASTER(ctrl), Q921_TEI_IDENTITY_REQUEST, ctrl->ri, Q921_TEI_GROUP, 1);
-}
-
-static void q921_tei_request(struct pri *ctrl)
-{
-	ctrl->n202_counter = 0;
-	t202_expire(ctrl);
-}
-
-static void q921_send_dm(struct pri *ctrl, int fbit)
+	link->ri = random() % 65535;
+	q921_send_tei(ctrl, Q921_TEI_IDENTITY_REQUEST, link->ri, Q921_TEI_GROUP, 1);
+}
+
+static void q921_tei_request(struct pri *link)
+{
+	link->n202_counter = 0;
+	t202_expire(link);
+}
+
+static void q921_send_dm(struct pri *link, int fbit)
 {
 	q921_h h;
-
-	Q921_INIT(ctrl, h);
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	Q921_INIT(link, h);
 	h.u.m3 = 0;	/* M3 = 0 */
 	h.u.m2 = 3;	/* M2 = 3 */
 	h.u.p_f = fbit;	/* Final set appropriately */
@@ -256,16 +265,19 @@
 		return;
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Sending DM\n", ctrl->tei);
+		pri_message(ctrl, "TEI=%d Sending DM\n", link->tei);
 	}
 	q921_transmit(ctrl, &h, 4);
 }
 
-static void q921_send_disc(struct pri *ctrl, int pbit)
+static void q921_send_disc(struct pri *link, int pbit)
 {
 	q921_h h;
-
-	Q921_INIT(ctrl, h);
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	Q921_INIT(link, h);
 	h.u.m3 = 2;	/* M3 = 2 */
 	h.u.m2 = 0;	/* M2 = 0 */
 	h.u.p_f = pbit;	/* Poll set appropriately */
@@ -282,15 +294,19 @@
 		return;
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Sending DISC\n", ctrl->tei);
+		pri_message(ctrl, "TEI=%d Sending DISC\n", link->tei);
 	}
 	q921_transmit(ctrl, &h, 4);
 }
 
-static void q921_send_ua(struct pri *ctrl, int fbit)
+static void q921_send_ua(struct pri *link, int fbit)
 {
 	q921_h h;
-	Q921_INIT(ctrl, h);
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	Q921_INIT(link, h);
 	h.u.m3 = 3;		/* M3 = 3 */
 	h.u.m2 = 0;		/* M2 = 0 */
 	h.u.p_f = fbit;	/* Final set appropriately */
@@ -307,16 +323,19 @@
 		return;
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Sending UA\n", ctrl->tei);
+		pri_message(ctrl, "TEI=%d Sending UA\n", link->tei);
 	}
 	q921_transmit(ctrl, &h, 3);
 }
 
-static void q921_send_sabme(struct pri *ctrl)
+static void q921_send_sabme(struct pri *link)
 {
 	q921_h h;
-
-	Q921_INIT(ctrl, h);
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	Q921_INIT(link, h);
 	h.u.m3 = 3;	/* M3 = 3 */
 	h.u.m2 = 3;	/* M2 = 3 */
 	h.u.p_f = 1;	/* Poll bit set */
@@ -333,24 +352,20 @@
 		return;
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Sending SABME\n", ctrl->tei);
+		pri_message(ctrl, "TEI=%d Sending SABME\n", link->tei);
 	}
 	q921_transmit(ctrl, &h, 3);
 }
 
-#if 0
-static void q921_send_sabme_now(void *vpri)
-{
-	q921_send_sabme(vpri, 1);
-}
-#endif
-
-static int q921_ack_packet(struct pri *ctrl, int num)
+static int q921_ack_packet(struct pri *link, int num)
 {
 	struct q921_frame *f;
 	struct q921_frame *prev;
-
-	for (prev = NULL, f = ctrl->txqueue; f; prev = f, f = f->next) {
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	for (prev = NULL, f = link->txqueue; f; prev = f, f = f->next) {
 		if (!f->transmitted) {
 			break;
 		}
@@ -360,14 +375,14 @@
 			if (prev)
 				prev->next = f->next;
 			else
-				ctrl->txqueue = f->next;
+				link->txqueue = f->next;
 			if (ctrl->debug & PRI_DEBUG_Q921_DUMP) {
 				pri_message(ctrl,
 					"-- ACKing N(S)=%d, txqueue head is N(S)=%d (-1 is empty, -2 is not transmitted)\n",
 					f->h.n_s,
-					ctrl->txqueue
-						? ctrl->txqueue->transmitted
-							? ctrl->txqueue->h.n_s
+					link->txqueue
+						? link->txqueue->transmitted
+							? link->txqueue->h.n_s
 							: -2
 						: -1);
 			}
@@ -379,33 +394,40 @@
 	return 0;
 }
 
-static void t203_expire(void *);
-static void t200_expire(void *);
-
-static void reschedule_t200(struct pri *ctrl)
-{
+static void t203_expire(void *vlink);
+static void t200_expire(void *vlink);
+
+#define restart_t200(link) reschedule_t200(link)
+static void reschedule_t200(struct pri *link)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
 	if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 		pri_message(ctrl, "-- Restarting T200 timer\n");
-	pri_schedule_del(ctrl, ctrl->t200_timer);
-	ctrl->t200_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], t200_expire, ctrl);
-}
-
-#define restart_t200(ctrl) reschedule_t200((ctrl))
+	pri_schedule_del(ctrl, link->t200_timer);
+	link->t200_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], t200_expire, link);
+}
 
 #if 0
-static void reschedule_t203(struct pri *ctrl)
-{
+static void reschedule_t203(struct pri *link)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
 	if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 		pri_message(ctrl, "-- Restarting T203 timer\n");
-	pri_schedule_del(ctrl, ctrl->t203_timer);
-	ctrl->t203_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T203], t203_expire, ctrl);
+	pri_schedule_del(ctrl, link->t203_timer);
+	link->t203_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T203], t203_expire, link);
 }
 #endif
 
 #if 0
-static int q921_unacked_iframes(struct pri *ctrl)
-{
-	struct q921_frame *f = ctrl->txqueue;
+static int q921_unacked_iframes(struct pri *link)
+{
+	struct q921_frame *f = link->txqueue;
 	int cnt = 0;
 
 	while(f) {
@@ -418,50 +440,66 @@
 }
 #endif
 
-static void start_t203(struct pri *ctrl)
-{
-	if (ctrl->t203_timer) {
+static void start_t203(struct pri *link)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	if (link->t203_timer) {
 		if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 			pri_message(ctrl, "T203 requested to start without stopping first\n");
-		pri_schedule_del(ctrl, ctrl->t203_timer);
+		pri_schedule_del(ctrl, link->t203_timer);
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 		pri_message(ctrl, "-- Starting T203 timer\n");
-	ctrl->t203_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T203], t203_expire, ctrl);
-}
-
-static void stop_t203(struct pri *ctrl)
-{
-	if (ctrl->t203_timer) {
+	link->t203_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T203], t203_expire, link);
+}
+
+static void stop_t203(struct pri *link)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	if (link->t203_timer) {
 		if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 			pri_message(ctrl, "-- Stopping T203 timer\n");
-		pri_schedule_del(ctrl, ctrl->t203_timer);
-		ctrl->t203_timer = 0;
+		pri_schedule_del(ctrl, link->t203_timer);
+		link->t203_timer = 0;
 	} else {
 		if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 			pri_message(ctrl, "-- T203 requested to stop when not started\n");
 	}
 }
 
-static void start_t200(struct pri *ctrl)
-{
-	if (ctrl->t200_timer) {
+static void start_t200(struct pri *link)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	if (link->t200_timer) {
 		if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 			pri_message(ctrl, "T200 requested to start without stopping first\n");
-		pri_schedule_del(ctrl, ctrl->t200_timer);
+		pri_schedule_del(ctrl, link->t200_timer);
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 		pri_message(ctrl, "-- Starting T200 timer\n");
-	ctrl->t200_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], t200_expire, ctrl);
-}
-
-static void stop_t200(struct pri *ctrl)
-{
-	if (ctrl->t200_timer) {
+	link->t200_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], t200_expire, link);
+}
+
+static void stop_t200(struct pri *link)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	if (link->t200_timer) {
 		if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 			pri_message(ctrl, "-- Stopping T200 timer\n");
-		pri_schedule_del(ctrl, ctrl->t200_timer);
-		ctrl->t200_timer = 0;
+		pri_schedule_del(ctrl, link->t200_timer);
+		link->t200_timer = 0;
 	} else {
 		if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 			pri_message(ctrl, "-- T200 requested to stop when not started\n");
@@ -469,12 +507,15 @@
 }
 
 /* This is the equivalent of the I-Frame queued up path in Figure B.7 in MULTI_FRAME_ESTABLISHED */
-static int q921_send_queued_iframes(struct pri *ctrl)
-{
+static int q921_send_queued_iframes(struct pri *link)
+{
+	struct pri *ctrl;
 	struct q921_frame *f;
 	int frames_txd = 0;
 
-	for (f = ctrl->txqueue; f; f = f->next) {
+	ctrl = PRI_MASTER(link);
+
+	for (f = link->txqueue; f; f = f->next) {
 		if (!f->transmitted) {
 			/* This frame has not been sent yet. */
 			break;
@@ -485,20 +526,20 @@
 		return 0;
 	}
 
-	if (ctrl->peer_rx_busy
-		|| (ctrl->v_s == Q921_ADD(ctrl->v_a, ctrl->timers[PRI_TIMER_K]))) {
+	if (link->peer_rx_busy
+		|| (link->v_s == Q921_ADD(link->v_a, ctrl->timers[PRI_TIMER_K]))) {
 		/* Don't flood debug trace if not really looking at Q.921 layer. */
 		if (ctrl->debug & (/* PRI_DEBUG_Q921_STATE | */ PRI_DEBUG_Q921_DUMP)) {
 			pri_message(ctrl,
 				"TEI=%d Couldn't transmit I-frame at this time due to peer busy condition or window shut\n",
-				ctrl->tei);
+				link->tei);
 		}
 		return 0;
 	}
 
 	/* Send all pending frames that fit in the window. */
 	for (; f; f = f->next) {
-		if (ctrl->v_s == Q921_ADD(ctrl->v_a, ctrl->timers[PRI_TIMER_K])) {
+		if (link->v_s == Q921_ADD(link->v_a, ctrl->timers[PRI_TIMER_K])) {
 			/* The window is no longer open. */
 			break;
 		}
@@ -511,19 +552,19 @@
 		 * Done now because the frame may have been queued before we
 		 * had an assigned TEI.
 		 */
-		f->h.h.tei = ctrl->tei;
-
-		f->h.n_s = ctrl->v_s;
-		f->h.n_r = ctrl->v_r;
+		f->h.h.tei = link->tei;
+
+		f->h.n_s = link->v_s;
+		f->h.n_r = link->v_r;
 		f->h.ft = 0;
 		f->h.p_f = 0;
 		if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
 			pri_message(ctrl,
 				"TEI=%d Transmitting N(S)=%d, window is open V(A)=%d K=%d\n",
-				ctrl->tei, f->h.n_s, ctrl->v_a, ctrl->timers[PRI_TIMER_K]);
-		}
-		q921_transmit(ctrl, (q921_h *)(&f->h), f->len);
-		Q921_INC(ctrl->v_s);
+				link->tei, f->h.n_s, link->v_a, ctrl->timers[PRI_TIMER_K]);
+		}
+		q921_transmit(ctrl, (q921_h *) (&f->h), f->len);
+		Q921_INC(link->v_s);
 		++frames_txd;
 
 		if (ctrl->debug & PRI_DEBUG_Q931_DUMP) {
@@ -535,30 +576,33 @@
 			 * Also the dump is done here so the Q.931 part is decoded only
 			 * once instead of for every retransmission.
 			 */
-			q931_dump(ctrl, ctrl->tei, (q931_h *) f->h.data, f->len - 4, 1);
+			q931_dump(ctrl, link->tei, (q931_h *) f->h.data, f->len - 4, 1);
 		}
 	}
 
 	if (frames_txd) {
-		ctrl->acknowledge_pending = 0;
-		if (!ctrl->t200_timer) {
-			stop_t203(ctrl);
-			start_t200(ctrl);
+		link->acknowledge_pending = 0;
+		if (!link->t200_timer) {
+			stop_t203(link);
+			start_t200(link);
 		}
 	}
 
 	return frames_txd;
 }
 
-static void q921_reject(struct pri *ctrl, int pf)
+static void q921_reject(struct pri *link, int pf)
 {
 	q921_h h;
-
-	Q921_INIT(ctrl, h);
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	Q921_INIT(link, h);
 	h.s.x0 = 0;	/* Always 0 */
 	h.s.ss = 2;	/* Reject */
 	h.s.ft = 1;	/* Frametype (01) */
-	h.s.n_r = ctrl->v_r;	/* Where to start retransmission */
+	h.s.n_r = link->v_r;	/* Where to start retransmission N(R) */
 	h.s.p_f = pf;	
 	switch(ctrl->localtype) {
 	case PRI_NETWORK:
@@ -572,20 +616,23 @@
 		return;
 	}
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Sending REJ N(R)=%d\n", ctrl->tei, ctrl->v_r);
+		pri_message(ctrl, "TEI=%d Sending REJ N(R)=%d\n", link->tei, link->v_r);
 	}
 	q921_transmit(ctrl, &h, 4);
 }
 
-static void q921_rr(struct pri *ctrl, int pbit, int cmd)
+static void q921_rr(struct pri *link, int pbit, int cmd)
 {
 	q921_h h;
-
-	Q921_INIT(ctrl, h);
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
+	Q921_INIT(link, h);
 	h.s.x0 = 0;	/* Always 0 */
 	h.s.ss = 0; /* Receive Ready */
 	h.s.ft = 1;	/* Frametype (01) */
-	h.s.n_r = ctrl->v_r;	/* N/R */
+	h.s.n_r = link->v_r;	/* N(R) */
 	h.s.p_f = pbit;		/* Poll/Final set appropriately */
 	switch(ctrl->localtype) {
 	case PRI_NETWORK:
@@ -606,100 +653,105 @@
 	}
 #if 0	/* Don't flood debug trace with RR if not really looking at Q.921 layer. */
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Sending RR N(R)=%d\n", ctrl->tei, ctrl->v_r);
+		pri_message(ctrl, "TEI=%d Sending RR N(R)=%d\n", link->tei, link->v_r);
 	}
 #endif
 	q921_transmit(ctrl, &h, 4);
 }
 
-static void transmit_enquiry(struct pri *ctrl)
-{
-	if (!ctrl->own_rx_busy) {
-		q921_rr(ctrl, 1, 1);
-		ctrl->acknowledge_pending = 0;
-		start_t200(ctrl);
+static void transmit_enquiry(struct pri *link)
+{
+	if (!link->own_rx_busy) {
+		q921_rr(link, 1, 1);
+		link->acknowledge_pending = 0;
+		start_t200(link);
 	} else {
 		/* XXX: Implement me... */
 	}
 }
 
-static void t200_expire(void *vpri)
-{
-	struct pri *ctrl = vpri;
+static void t200_expire(void *vlink)
+{
+	struct pri *link = vlink;
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	if (ctrl->debug & PRI_DEBUG_Q921_DUMP) {
 		pri_message(ctrl, "%s\n", __FUNCTION__);
-		q921_dump_pri(ctrl, ' ');
-	}
-
-	ctrl->t200_timer = 0;
-
-	switch (ctrl->q921_state) {
+		q921_dump_pri(link, ' ');
+	}
+
+	link->t200_timer = 0;
+
+	switch (link->q921_state) {
 	case Q921_MULTI_FRAME_ESTABLISHED:
-		ctrl->RC = 0;
-		transmit_enquiry(ctrl);
-		ctrl->RC++;
-		q921_setstate(ctrl, Q921_TIMER_RECOVERY);
+		link->RC = 0;
+		transmit_enquiry(link);
+		link->RC++;
+		q921_setstate(link, Q921_TIMER_RECOVERY);
 		break;
 	case Q921_TIMER_RECOVERY:
 		/* SDL Flow Figure B.8/Q.921 Page 81 */
-		if (ctrl->RC != ctrl->timers[PRI_TIMER_N200]) {
+		if (link->RC != ctrl->timers[PRI_TIMER_N200]) {
 #if 0
-			if (ctrl->v_s == ctrl->v_a) {
-				transmit_enquiry(ctrl);
+			if (link->v_s == link->v_a) {
+				transmit_enquiry(link);
 			}
 #else
 			/* We are chosing to enquiry by default (to reduce risk of T200 timer errors at the other
 			 * side, instead of retransmission of the last I-frame we sent */
-			transmit_enquiry(ctrl);
+			transmit_enquiry(link);
 #endif
-			ctrl->RC++;
+			link->RC++;
 		} else {
-			q921_mdl_error(ctrl, 'I');
-			q921_establish_data_link(ctrl);
-			ctrl->l3initiated = 0;
-			q921_setstate(ctrl, Q921_AWAITING_ESTABLISHMENT);
+			q921_mdl_error(link, 'I');
+			q921_establish_data_link(link);
+			link->l3initiated = 0;
+			q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
 		}
 		break;
 	case Q921_AWAITING_ESTABLISHMENT:
-		if (ctrl->RC != ctrl->timers[PRI_TIMER_N200]) {
-			ctrl->RC++;
-			q921_send_sabme(ctrl);
-			start_t200(ctrl);
+		if (link->RC != ctrl->timers[PRI_TIMER_N200]) {
+			link->RC++;
+			q921_send_sabme(link);
+			start_t200(link);
 		} else {
-			q921_discard_iqueue(ctrl);
-			q921_mdl_error(ctrl, 'G');
-			q921_setstate(ctrl, Q921_TEI_ASSIGNED);
+			q921_discard_iqueue(link);
+			q921_mdl_error(link, 'G');
+			q921_setstate(link, Q921_TEI_ASSIGNED);
 			/* DL-RELEASE indication */
-			q931_dl_event(ctrl, Q931_DL_EVENT_DL_RELEASE_IND);
+			q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND);
 		}
 		break;
 	case Q921_AWAITING_RELEASE:
-		if (ctrl->RC != ctrl->timers[PRI_TIMER_N200]) {
-			++ctrl->RC;
-			q921_send_disc(ctrl, 1);
-			start_t200(ctrl);
+		if (link->RC != ctrl->timers[PRI_TIMER_N200]) {
+			++link->RC;
+			q921_send_disc(link, 1);
+			start_t200(link);
 		} else {
-			q921_mdl_error(ctrl, 'H');
+			q921_mdl_error(link, 'H');
 			/* DL-RELEASE confirm */
-			q931_dl_event(ctrl, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
-			q921_setstate(ctrl, Q921_TEI_ASSIGNED);
+			q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
+			q921_setstate(link, Q921_TEI_ASSIGNED);
 		}
 		break;
 	default:
 		/* Looks like someone forgot to stop the T200 timer. */
 		pri_error(ctrl, "T200 expired in state %d(%s)\n",
-			ctrl->q921_state, q921_state2str(ctrl->q921_state));
-		break;
-	}
-
+			link->q921_state, q921_state2str(link->q921_state));
+		break;
+	}
 }
 
 /* This is sending a DL-UNIT-DATA request */
-int q921_transmit_uiframe(struct pri *ctrl, void *buf, int len)
+int q921_transmit_uiframe(struct pri *link, void *buf, int len)
 {
 	uint8_t ubuf[512];
 	q921_h *h = (void *)&ubuf[0];
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	if (len >= 512) {
 		pri_error(ctrl, "Requested to send UI-frame larger than 512 bytes!\n");
@@ -710,7 +762,7 @@
 	h->h.sapi = 0;
 	h->h.ea1 = 0;
 	h->h.ea2 = 1;
-	h->h.tei = ctrl->tei;
+	h->h.tei = link->tei;
 	h->u.m3 = 0;
 	h->u.m2 = 0;
 	h->u.p_f = 0;	/* Poll bit set */
@@ -735,10 +787,9 @@
 	return 0;
 }
 
-static struct pri * pri_find_tei(struct pri *vpri, int sapi, int tei)
-{
-	struct pri *ctrl;
-	for (ctrl = PRI_MASTER(vpri); ctrl; ctrl = ctrl->subchannel) {
+static struct pri *pri_find_tei(struct pri *ctrl, int sapi, int tei)
+{
+	for (; ctrl; ctrl = ctrl->subchannel) {
 		if (ctrl->tei == tei && ctrl->sapi == sapi)
 			return ctrl;
 	}
@@ -747,63 +798,64 @@
 }
 
 /* This is the equivalent of a DL-DATA request, as well as the I-frame queued up outcome */
-int q921_transmit_iframe(struct pri *vpri, int tei, void *buf, int len, int cr)
+int q921_transmit_iframe(struct pri *link, int tei, void *buf, int len, int cr)
 {
 	q921_frame *f, *prev=NULL;
 	struct pri *ctrl;
 
-	if (BRI_NT_PTMP(vpri)) {
+	ctrl = PRI_MASTER(link);
+
+	if (BRI_NT_PTMP(ctrl)) {
 		if (tei == Q921_TEI_GROUP) {
-			pri_error(vpri, "Huh?! For NT-PTMP, we shouldn't be sending I-frames out the group TEI\n");
+			pri_error(ctrl, "Huh?! For NT-PTMP, we shouldn't be sending I-frames out the group TEI\n");
 			return 0;
 		}
 
-		ctrl = pri_find_tei(vpri, Q921_SAPI_CALL_CTRL, tei);
-		if (!ctrl) {
-			pri_error(vpri, "Huh?! Unable to locate PRI associated with TEI %d.  Did we have to ditch it due to error conditions?\n", tei);
+		link = pri_find_tei(ctrl, Q921_SAPI_CALL_CTRL, tei);
+		if (!link) {
+			pri_error(ctrl, "Huh?! Unable to locate PRI associated with TEI %d.  Did we have to ditch it due to error conditions?\n", tei);
 			return 0;
 		}
-	} else if (BRI_TE_PTMP(vpri)) {
+	} else if (BRI_TE_PTMP(ctrl)) {
 		/* We don't care what the tei is, since we only support one sub and one TEI */
-		ctrl = PRI_MASTER(vpri)->subchannel;
-
-		switch (ctrl->q921_state) {
+		link = ctrl->subchannel;
+
+		switch (link->q921_state) {
 		case Q921_TEI_UNASSIGNED:
-			q921_setstate(ctrl, Q921_ESTABLISH_AWAITING_TEI);
-			q921_tei_request(ctrl);
+			q921_setstate(link, Q921_ESTABLISH_AWAITING_TEI);
+			q921_tei_request(link);
 			break;
 		case Q921_ASSIGN_AWAITING_TEI:
-			q921_setstate(ctrl, Q921_ESTABLISH_AWAITING_TEI);
+			q921_setstate(link, Q921_ESTABLISH_AWAITING_TEI);
 			break;
 		default:
 			break;
 		}
 	} else {
 		/* Should just be PTP modes, which shouldn't have subs */
-		ctrl = vpri;
 	}
 
 	/* Figure B.7/Q.921 Page 70 */
-	switch (ctrl->q921_state) {
+	switch (link->q921_state) {
 	case Q921_TEI_ASSIGNED:
 		/* If we aren't in a state compatiable with DL-DATA requests, start getting us there here */
-		q921_establish_data_link(ctrl);
-		ctrl->l3initiated = 1;
-		q921_setstate(ctrl, Q921_AWAITING_ESTABLISHMENT);
+		q921_establish_data_link(link);
+		link->l3initiated = 1;
+		q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
 		/* For all rest, we've done the work to get us up prior to this and fall through */
 	case Q921_ESTABLISH_AWAITING_TEI:
 	case Q921_TIMER_RECOVERY:
 	case Q921_AWAITING_ESTABLISHMENT:
 	case Q921_MULTI_FRAME_ESTABLISHED:
 		/* Find queue tail. */
-		for (f = ctrl->txqueue; f; f = f->next) {
+		for (f = link->txqueue; f; f = f->next) {
 			prev = f;
 		}
 
 		f = calloc(1, sizeof(q921_frame) + len + 2);
 		if (f) {
-			Q921_INIT(ctrl, f->h);
-			switch(ctrl->localtype) {
+			Q921_INIT(link, f->h);
+			switch (ctrl->localtype) {
 			case PRI_NETWORK:
 				if (cr)
 					f->h.h.c_r = 1;
@@ -826,76 +878,81 @@
 			if (prev)
 				prev->next = f;
 			else
-				ctrl->txqueue = f;
-
-			if (ctrl->q921_state != Q921_MULTI_FRAME_ESTABLISHED) {
+				link->txqueue = f;
+
+			if (link->q921_state != Q921_MULTI_FRAME_ESTABLISHED) {
 				if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
 					pri_message(ctrl,
 						"TEI=%d Just queued I-frame since in state %d(%s)\n",
-						ctrl->tei,
-						ctrl->q921_state, q921_state2str(ctrl->q921_state));
+						link->tei,
+						link->q921_state, q921_state2str(link->q921_state));
 				}
-				return 0;
-			}
-
-			if (ctrl->peer_rx_busy || (ctrl->v_s == Q921_ADD(ctrl->v_a, ctrl->timers[PRI_TIMER_K]))) {
+				break;
+			}
+
+			if (link->peer_rx_busy || (link->v_s == Q921_ADD(link->v_a, ctrl->timers[PRI_TIMER_K]))) {
 				if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
 					pri_message(ctrl,
 						"TEI=%d Just queued I-frame due to peer busy condition or window shut\n",
-						ctrl->tei);
+						link->tei);
 				}
-				return 0;
-			}
-
-			q921_send_queued_iframes(ctrl);
-
-			return 0;
+				break;
+			}
+
+			q921_send_queued_iframes(link);
 		} else {
 			pri_error(ctrl, "!! Out of memory for Q.921 transmit\n");
 			return -1;
 		}
+		break;
 	case Q921_TEI_UNASSIGNED:
 	case Q921_ASSIGN_AWAITING_TEI:
 	case Q921_AWAITING_RELEASE:
 	default:
 		pri_error(ctrl, "Cannot transmit frames in state %d(%s)\n",
-			ctrl->q921_state, q921_state2str(ctrl->q921_state));
+			link->q921_state, q921_state2str(link->q921_state));
 		break;
 	}
 	return 0;
 }
 
-static void t203_expire(void *vpri)
-{
-	struct pri *ctrl = vpri;
+static void t203_expire(void *vlink)
+{
+	struct pri *link = vlink;
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	if (ctrl->debug & PRI_DEBUG_Q921_DUMP)
 		pri_message(ctrl, "%s\n", __FUNCTION__);
 
-	ctrl->t203_timer = 0;
-
-	switch (ctrl->q921_state) {
+	link->t203_timer = 0;
+
+	switch (link->q921_state) {
 	case Q921_MULTI_FRAME_ESTABLISHED:
-		transmit_enquiry(ctrl);
-		ctrl->RC = 0;
-		q921_setstate(ctrl, Q921_TIMER_RECOVERY);
+		transmit_enquiry(link);
+		link->RC = 0;
+		q921_setstate(link, Q921_TIMER_RECOVERY);
 		break;
 	default:
 		/* Looks like someone forgot to stop the T203 timer. */
 		pri_error(ctrl, "T203 expired in state %d(%s)\n",
-			ctrl->q921_state, q921_state2str(ctrl->q921_state));
-		break;
-	}
-}
-
-static void q921_dump_iqueue_info(struct pri *ctrl)
-{
+			link->q921_state, q921_state2str(link->q921_state));
+		break;
+	}
+}
+
+static void q921_dump_iqueue_info(struct pri *link)
+{
+	struct pri *ctrl;
 	struct q921_frame *f;
 	int pending = 0, unacked = 0;
 
+	ctrl = PRI_MASTER(link);
+
 	unacked = pending = 0;
 
-	for (f = ctrl->txqueue; f; f = f->next) {
+	for (f = link->txqueue; f; f = f->next) {
 		if (f->transmitted) {
 			unacked++;
 		} else {
@@ -1026,6 +1083,8 @@
 				if (h->u.m2 == 3)
 					type = "XID (exchange identification note)";
 				break;
+			default:
+				break;
 			}
 		}
 		pri_message(ctrl, "%c   M3: %d   P/F: %d M2: %d 11: %d  [ %s ]\n",
@@ -1080,36 +1139,43 @@
 	}
 }
 
-static void q921_dump_pri(struct pri *ctrl, char direction_tag)
-{
+static void q921_dump_pri(struct pri *link, char direction_tag)
+{
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
+
 	pri_message(ctrl, "%c TEI: %d State %d(%s)\n",
-		direction_tag, ctrl->tei, ctrl->q921_state, q921_state2str(ctrl->q921_state));
+		direction_tag, link->tei, link->q921_state, q921_state2str(link->q921_state));
 	pri_message(ctrl, "%c V(A)=%d, V(S)=%d, V(R)=%d\n",
-		direction_tag, ctrl->v_a, ctrl->v_s, ctrl->v_r);
+		direction_tag, link->v_a, link->v_s, link->v_r);
 	pri_message(ctrl, "%c K=%d, RC=%d, l3initiated=%d, reject_except=%d, ack_pend=%d\n",
-		direction_tag, ctrl->timers[PRI_TIMER_K], ctrl->RC, ctrl->l3initiated,
-		ctrl->reject_exception, ctrl->acknowledge_pending);
+		direction_tag, ctrl->timers[PRI_TIMER_K], link->RC, link->l3initiated,
+		link->reject_exception, link->acknowledge_pending);
 	pri_message(ctrl, "%c T200_id=%d, N200=%d, T203_id=%d\n",
-		direction_tag, ctrl->t200_timer, ctrl->timers[PRI_TIMER_N200], ctrl->t203_timer);
-}
-
-static void q921_dump_pri_by_h(struct pri *vpri, char direction_tag, q921_h *h)
-{
-	struct pri *ctrl = NULL;
-
-	if (!vpri) {
+		direction_tag, link->t200_timer, ctrl->timers[PRI_TIMER_N200], link->t203_timer);
+}
+
+static void q921_dump_pri_by_h(struct pri *ctrl, char direction_tag, q921_h *h)
+{
+	struct pri *link;
+
+	if (!ctrl) {
 		return;
 	}
-	if (BRI_NT_PTMP(vpri)) {
-		ctrl = pri_find_tei(vpri, h->h.sapi, h->h.tei);
-	} else if (BRI_TE_PTMP(vpri)) {
-		ctrl = PRI_MASTER(vpri)->subchannel;
-	} else 
-		ctrl = vpri;
-	if (ctrl) {
-		q921_dump_pri(ctrl, direction_tag);
-	} else if (!PTMP_MODE(vpri)) {
-		pri_error(vpri, "Huh.... no pri found to dump\n");
+
+	if (BRI_NT_PTMP(ctrl)) {
+		link = pri_find_tei(ctrl, h->h.sapi, h->h.tei);
+	} else if (BRI_TE_PTMP(ctrl)) {
+		link = ctrl->subchannel;
+	} else {
+		link = ctrl;
+	}
+
+	if (link) {
+		q921_dump_pri(link, direction_tag);
+	} else {
+		pri_message(ctrl, "%c Link not found for this frame.\n", direction_tag);
 	}
 }
 
@@ -1117,6 +1183,7 @@
 {
 	int ri;
 	struct pri *sub;
+	struct pri *link;
 	pri_event *res = NULL;
 	int tei;
 
@@ -1184,9 +1251,9 @@
 			return NULL;
 
 		/* Assuming we're operating on the sub here */
-		ctrl = ctrl->subchannel;
+		link = ctrl->subchannel;
 		
-		switch (ctrl->q921_state) {
+		switch (link->q921_state) {
 		case Q921_ASSIGN_AWAITING_TEI:
 		case Q921_ESTABLISH_AWAITING_TEI:
 			break;
@@ -1195,29 +1262,31 @@
 			return NULL;
 		}
 
-		if (ri != ctrl->ri) {
-			pri_message(ctrl, "TEI assignment received for invalid Ri %02x (our is %02x)\n", ri, ctrl->ri);
+		if (ri != link->ri) {
+			pri_message(ctrl,
+				"TEI assignment received for another Ri %02x (ours is %02x)\n",
+				ri, link->ri);
 			return NULL;
 		}
 
-		pri_schedule_del(ctrl, ctrl->t202_timer);
-		ctrl->t202_timer = 0;
-
-		ctrl->tei = tei;
+		pri_schedule_del(ctrl, link->t202_timer);
+		link->t202_timer = 0;
+
+		link->tei = tei;
 		if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
 			pri_message(ctrl, "Got assigned TEI %d\n", tei);
 		}
 
-		switch (ctrl->q921_state) {
+		switch (link->q921_state) {
 		case Q921_ASSIGN_AWAITING_TEI:
-			q921_setstate(ctrl, Q921_TEI_ASSIGNED);
+			q921_setstate(link, Q921_TEI_ASSIGNED);
 			ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP;
 			res = &ctrl->ev;
 			break;
 		case Q921_ESTABLISH_AWAITING_TEI:
-			q921_establish_data_link(ctrl);
-			ctrl->l3initiated = 1;
-			q921_setstate(ctrl, Q921_AWAITING_ESTABLISHMENT);
+			q921_establish_data_link(link);
+			link->l3initiated = 1;
+			q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
 			ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP;
 			res = &ctrl->ev;
 			break;
@@ -1229,29 +1298,35 @@
 		if (!BRI_TE_PTMP(ctrl))
 			return NULL;
 
-		if (ctrl->subchannel->q921_state < Q921_TEI_ASSIGNED) {
+		/* Assuming we're operating on the sub here */
+		link = ctrl->subchannel;
+
+		if (link->q921_state < Q921_TEI_ASSIGNED) {
 			/* We do not have a TEI. */
 			return NULL;
 		}
 
 		/* If it's addressed to the group TEI or to our TEI specifically, we respond */
-		if ((tei == Q921_TEI_GROUP) || (tei == ctrl->subchannel->tei)) {
-			q921_send_tei(ctrl, Q921_TEI_IDENTITY_CHECK_RESPONSE, random() % 65535, ctrl->subchannel->tei, 1);
+		if (tei == Q921_TEI_GROUP || tei == link->tei) {
+			q921_send_tei(ctrl, Q921_TEI_IDENTITY_CHECK_RESPONSE, random() % 65535, link->tei, 1);
 		}
 		break;
 	case Q921_TEI_IDENTITY_REMOVE:
 		if (!BRI_TE_PTMP(ctrl))
 			return NULL;
 
-		if (ctrl->subchannel->q921_state < Q921_TEI_ASSIGNED) {
+		/* Assuming we're operating on the sub here */
+		link = ctrl->subchannel;
+
+		if (link->q921_state < Q921_TEI_ASSIGNED) {
 			/* We do not have a TEI. */
 			return NULL;
 		}
 
 		/* If it's addressed to the group TEI or to our TEI specifically, we respond */
-		if ((tei == Q921_TEI_GROUP) || (tei == ctrl->subchannel->tei)) {
-			q921_mdl_remove(ctrl->subchannel);
-			q921_start(ctrl->subchannel);
+		if (tei == Q921_TEI_GROUP || tei == link->tei) {
+			q921_mdl_remove(link);
+			q921_start(link);
 		}
 		break;
 	}
@@ -1270,121 +1345,130 @@
 	return command;
 }
 
-static void q921_clear_exception_conditions(struct pri *ctrl)
-{
-	ctrl->own_rx_busy = 0;
-	ctrl->peer_rx_busy = 0;
-	ctrl->reject_exception = 0;
-	ctrl->acknowledge_pending = 0;
-}
-
-static pri_event * q921_sabme_rx(struct pri *ctrl, q921_h *h)
+static void q921_clear_exception_conditions(struct pri *link)
+{
+	link->own_rx_busy = 0;
+	link->peer_rx_busy = 0;
+	link->reject_exception = 0;
+	link->acknowledge_pending = 0;
+}
+
+static pri_event *q921_sabme_rx(struct pri *link, q921_h *h)
 {
 	pri_event *res = NULL;
+	struct pri *ctrl;
 	enum Q931_DL_EVENT delay_q931_dl_event;
 
-	switch (ctrl->q921_state) {
+	ctrl = PRI_MASTER(link);
+
+	switch (link->q921_state) {
 	case Q921_TIMER_RECOVERY:
 		/* Timer recovery state handling is same as multiframe established */
 	case Q921_MULTI_FRAME_ESTABLISHED:
 		/* Send Unnumbered Acknowledgement */
-		q921_send_ua(ctrl, h->u.p_f);
-		q921_clear_exception_conditions(ctrl);
-		q921_mdl_error(ctrl, 'F');
-		if (ctrl->v_s != ctrl->v_a) {
-			q921_discard_iqueue(ctrl);
+		q921_send_ua(link, h->u.p_f);
+		q921_clear_exception_conditions(link);
+		q921_mdl_error(link, 'F');
+		if (link->v_s != link->v_a) {
+			q921_discard_iqueue(link);
 			/* DL-ESTABLISH indication */
 			delay_q931_dl_event = Q931_DL_EVENT_DL_ESTABLISH_IND;
 		} else {
 			delay_q931_dl_event = Q931_DL_EVENT_NONE;
 		}
-		stop_t200(ctrl);
-		start_t203(ctrl);
-		ctrl->v_s = ctrl->v_a = ctrl->v_r = 0;
-		q921_setstate(ctrl, Q921_MULTI_FRAME_ESTABLISHED);
+		stop_t200(link);
+		start_t203(link);
+		link->v_s = link->v_a = link->v_r = 0;
+		q921_setstate(link, Q921_MULTI_FRAME_ESTABLISHED);
 		if (delay_q931_dl_event != Q931_DL_EVENT_NONE) {
 			/* Delayed because Q.931 could send STATUS messages. */
-			q931_dl_event(ctrl, delay_q931_dl_event);
+			q931_dl_event(link, delay_q931_dl_event);
 		}
 		break;
 	case Q921_TEI_ASSIGNED:
-		q921_send_ua(ctrl, h->u.p_f);
-		q921_clear_exception_conditions(ctrl);
-		ctrl->v_s = ctrl->v_a = ctrl->v_r = 0;
+		q921_send_ua(link, h->u.p_f);
+		q921_clear_exception_conditions(link);
+		link->v_s = link->v_a = link->v_r = 0;
 		/* DL-ESTABLISH indication */
 		delay_q931_dl_event = Q931_DL_EVENT_DL_ESTABLISH_IND;
 		if (PTP_MODE(ctrl)) {
 			ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP;
 			res = &ctrl->ev;
 		}
-		start_t203(ctrl);
-		q921_setstate(ctrl, Q921_MULTI_FRAME_ESTABLISHED);
+		start_t203(link);
+		q921_setstate(link, Q921_MULTI_FRAME_ESTABLISHED);
 		if (delay_q931_dl_event != Q931_DL_EVENT_NONE) {
 			/* Delayed because Q.931 could send STATUS messages. */
-			q931_dl_event(ctrl, delay_q931_dl_event);
+			q931_dl_event(link, delay_q931_dl_event);
 		}
 		break;
 	case Q921_AWAITING_ESTABLISHMENT:
-		q921_send_ua(ctrl, h->u.p_f);
+		q921_send_ua(link, h->u.p_f);
 		break;
 	case Q921_AWAITING_RELEASE:
-		q921_send_dm(ctrl, h->u.p_f);
+		q921_send_dm(link, h->u.p_f);
 		break;
 	default:
 		pri_error(ctrl, "Cannot handle SABME in state %d(%s)\n",
-			ctrl->q921_state, q921_state2str(ctrl->q921_state));
+			link->q921_state, q921_state2str(link->q921_state));
 		break;
 	}
 
 	return res;
 }
 
-static pri_event *q921_disc_rx(struct pri *ctrl, q921_h *h)
-{
-	pri_event * res = NULL;
+static pri_event *q921_disc_rx(struct pri *link, q921_h *h)
+{
+	pri_event *res = NULL;
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "TEI=%d Got DISC\n", ctrl->tei);
-	}
-
-	switch (ctrl->q921_state) {
+		pri_message(ctrl, "TEI=%d Got DISC\n", link->tei);
+	}
+
+	switch (link->q921_state) {
 	case Q921_TEI_ASSIGNED:
 	case Q921_AWAITING_ESTABLISHMENT:
-		q921_send_dm(ctrl, h->u.p_f);
+		q921_send_dm(link, h->u.p_f);
 		break;
 	case Q921_AWAITING_RELEASE:
-		q921_send_ua(ctrl, h->u.p_f);
+		q921_send_ua(link, h->u.p_f);
 		break;
 	case Q921_MULTI_FRAME_ESTABLISHED:
 	case Q921_TIMER_RECOVERY:
-		q921_discard_iqueue(ctrl);
-		q921_send_ua(ctrl, h->u.p_f);
+		q921_discard_iqueue(link);
+		q921_send_ua(link, h->u.p_f);
 		/* DL-RELEASE indication */
-		q931_dl_event(ctrl, Q931_DL_EVENT_DL_RELEASE_IND);
-		stop_t200(ctrl);
-		if (ctrl->q921_state == Q921_MULTI_FRAME_ESTABLISHED)
-			stop_t203(ctrl);
-		q921_setstate(ctrl, Q921_TEI_ASSIGNED);
-		q921_restart_ptp_link_if_needed(ctrl);
+		q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND);
+		stop_t200(link);
+		if (link->q921_state == Q921_MULTI_FRAME_ESTABLISHED)
+			stop_t203(link);
+		q921_setstate(link, Q921_TEI_ASSIGNED);
+		q921_restart_ptp_link_if_needed(link);
 		break;
 	default:
 		pri_error(ctrl, "Don't know what to do with DISC in state %d(%s)\n",
-			ctrl->q921_state, q921_state2str(ctrl->q921_state));
+			link->q921_state, q921_state2str(link->q921_state));
 		break;
 	}
 
 	return res;
 }
 
-static void q921_mdl_remove(struct pri *ctrl)
+static void q921_mdl_remove(struct pri *link)
 {
 	int mdl_free_me;
+	struct pri *ctrl;
+
+	ctrl = PRI_MASTER(link);
 
 	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
-		pri_message(ctrl, "MDL-REMOVE: Removing TEI %d\n", ctrl->tei);
+		pri_message(ctrl, "MDL-REMOVE: Removing TEI %d\n", link->tei);
 	}
 	if (BRI_NT_PTMP(ctrl)) {
-		if (ctrl == PRI_MASTER(ctrl)) {
+		if (link == ctrl) {
 			pri_error(ctrl, "Bad bad bad!  Cannot MDL-REMOVE master\n");
 			return;
 		}
@@ -1393,67 +1477,69 @@
 		mdl_free_me = 0;
 	}
 
-	switch (ctrl->q921_state) {
+	switch (link->q921_state) {
 	case Q921_TEI_ASSIGNED:

[... 1455 lines stripped ...]



More information about the libpri-commits mailing list