[libpri-commits] mattf: branch mattf/libpri-1.4-q921-rewrite r1361 - /team/mattf/libpri-1.4-q9...
SVN commits to the libpri project
libpri-commits at lists.digium.com
Wed Dec 2 15:01:05 CST 2009
Author: mattf
Date: Wed Dec 2 15:01:01 2009
New Revision: 1361
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1361
Log:
Commit MDL framework code into libpri.
Modified:
team/mattf/libpri-1.4-q921-rewrite/pri_internal.h
team/mattf/libpri-1.4-q921-rewrite/q921.c
Modified: team/mattf/libpri-1.4-q921-rewrite/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/team/mattf/libpri-1.4-q921-rewrite/pri_internal.h?view=diff&rev=1361&r1=1360&r2=1361
==============================================================================
--- team/mattf/libpri-1.4-q921-rewrite/pri_internal.h (original)
+++ team/mattf/libpri-1.4-q921-rewrite/pri_internal.h Wed Dec 2 15:01:01 2009
@@ -73,6 +73,11 @@
unsigned int hold_support:1;/* TRUE if upper layer supports call hold. */
unsigned int deflection_support:1;/* TRUE if upper layer supports call deflection/rerouting. */
+ /* MDL variables */
+ int mdl_error;
+ int mdl_error_state;
+ int mdl_timer;
+
/* Q.921 State */
int q921_state;
int k;
Modified: team/mattf/libpri-1.4-q921-rewrite/q921.c
URL: http://svnview.digium.com/svn/libpri/team/mattf/libpri-1.4-q921-rewrite/q921.c?view=diff&rev=1361&r1=1360&r2=1361
==============================================================================
--- team/mattf/libpri-1.4-q921-rewrite/q921.c (original)
+++ team/mattf/libpri-1.4-q921-rewrite/q921.c Wed Dec 2 15:01:01 2009
@@ -61,6 +61,8 @@
//static void q921_restart(struct pri *pri, int now);
//static void q921_tei_release_and_reacquire(struct pri *master);
static void q921_establish_data_link(struct pri *pri);
+static void q921_mdl_error(struct pri *pri, char error);
+static void q921_mdl_remove(struct pri *pri);
static void q921_setstate(struct pri *pri, int newstate)
{
@@ -450,7 +452,8 @@
}
pri->RC++;
} else {
- pri_error(pri, "MDL-ERROR (I): T200 = N200 in timer recovery state\n");
+ //pri_error(pri, "MDL-ERROR (I): T200 = N200 in timer recovery state\n");
+ q921_mdl_error(pri, 'I');
q921_establish_data_link(pri);
pri->l3initiated = 0;
q921_setstate(pri, Q921_AWAITING_ESTABLISHMENT);
@@ -463,21 +466,11 @@
start_t200(pri);
} else {
q921_discard_iqueue(pri);
- pri_error(pri, "MDL-ERROR (G) : T200 expired N200 times in state %d\n", pri->q921_state);
- if (PTP_MODE(pri)) {
- /* This branch is a deviation from SDL - We're still going to try to go back to multiframe established */
- pri->RC = 0;
- start_t200(pri);
- } else {
- /* This branch is according to SDL, Figure B.5/Q.921 on page 67 */
- q921_setstate(pri, Q921_TEI_ASSIGNED);
- }
+ //pri_error(pri, "MDL-ERROR (G) : T200 expired N200 times in state %d\n", pri->q921_state);
+ q921_mdl_error(pri, 'G');
+ q921_setstate(pri, Q921_TEI_ASSIGNED);
+ /* DL-RELEASE indication */
q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
-#if 0
- pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
- pri->schedev = 1;
-#endif
- /* XXX: We need to add some MDL functions to cover deviations from the SDL, but for now, this is how we'll do it */
}
break;
default:
@@ -1015,11 +1008,12 @@
/* Send Unnumbered Acknowledgement */
q921_send_ua(pri, h->u.p_f);
q921_clear_exception_conditions(pri);
- pri_error(pri, "MDL-ERROR (F), SABME in state %d\n", pri->q921_state);
+ //pri_error(pri, "MDL-ERROR (F), SABME in state %d\n", pri->q921_state);
+ q921_mdl_error(pri, 'F');
if (pri->v_s != pri->v_a) {
q921_discard_iqueue(pri);
- pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
- res = &pri->ev;
+ /* DL-ESTABLISH indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
}
stop_t200(pri);
start_t203(pri);
@@ -1030,7 +1024,12 @@
q921_send_ua(pri, h->u.p_f);
q921_clear_exception_conditions(pri);
pri->v_s = pri->v_a = pri->v_r = 0;
- pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
+ /* DL-ESTABLISH indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
+ if (PTP_MODE(pri)) {
+ pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
+ res = &pri->ev;
+ }
res = &pri->ev;
start_t203(pri);
q921_setstate(pri, Q921_MULTI_FRAME_ESTABLISHED);
@@ -1059,6 +1058,8 @@
q921_discard_iqueue(pri);
q921_send_ua(pri, h->u.p_f);
/* DL-RELEASE Indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
+
stop_t200(pri);
if (pri->q921_state == Q921_MULTI_FRAME_ESTABLISHED)
stop_t203(pri);
@@ -1073,13 +1074,190 @@
return res;
}
-static pri_event *q921_ua_rx(struct pri *pri, q921_h *h)
-{
- pri_event * res = NULL;
-
+static void q921_mdl_remove(struct pri *pri)
+{
switch (pri->q921_state) {
case Q921_TEI_ASSIGNED:
- pri_error(pri, "MDL-ERROR (C, D): UA received in state %d\n", pri->q921_state);
+ /* XXX: deviation! Since we don't have a UI queue, we just discard our I-queue */
+ q921_discard_iqueue(pri);
+ q921_setstate(pri, Q921_TEI_UNASSIGNED);
+ break;
+ case Q921_AWAITING_ESTABLISHMENT:
+ q921_discard_iqueue(pri);
+ /* DL-RELEASE indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
+
+ stop_t200(pri);
+ q921_setstate(pri, Q921_TEI_UNASSIGNED);
+ break;
+ case Q921_AWAITING_RELEASE:
+ q921_discard_iqueue(pri);
+ /* DL-RELEASE confirm */
+ stop_t200(pri);
+ break;
+ case Q921_MULTI_FRAME_ESTABLISHED:
+ q921_discard_iqueue(pri);
+ /* DL-RELEASE indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
+ stop_t200(pri);
+ stop_t203(pri);
+ q921_setstate(pri, Q921_TEI_UNASSIGNED);
+ break;
+ case Q921_TIMER_RECOVERY:
+ q921_discard_iqueue(pri);
+ /* DL-RELEASE indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
+ stop_t200(pri);
+ q921_setstate(pri, Q921_TEI_UNASSIGNED);
+ default:
+ pri_error(pri, "Cannot handle MDL remove when PRI is in state %d\n", pri->q921_state);
+ break;
+ }
+}
+
+static int q921_mdl_handle_network_error(struct pri *pri, char error)
+{
+ int handled = 0;
+ switch (error) {
+ case 'C':
+ case 'D':
+ case 'G':
+ case 'H':
+ case 'A':
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'I':
+ default:
+ pri_error(pri, "Network MDL can't handle error of type %c\n", error);
+ break;
+ }
+
+ return handled;
+}
+
+static int q921_mdl_handle_cpe_error(struct pri *pri, char error)
+{
+ int handled = 0;
+
+ switch (error) {
+ case 'C':
+ case 'D':
+ case 'G':
+ case 'H':
+ q921_mdl_remove(pri);
+ handled = 1;
+ break;
+ case 'A':
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'I':
+ break;
+ default:
+ pri_error(pri, "CPE MDL can't handle error of type %c\n", error);
+ break;
+ }
+
+ return handled;
+}
+
+static int q921_mdl_handle_ptp_error(struct pri *pri, char error)
+{
+ int handled = 0;
+ /* This is where we act a bit like L3 instead of L2, since we've got an L3 that depends on us
+ * keeping L2 automatically alive and happy for point to point links */
+ switch (error) {
+ case 'G':
+ /* We pick it back up and put it back together for this case */
+ q921_discard_iqueue(pri);
+ q921_establish_data_link(pri);
+ handled = 1;
+ break;
+ default:
+ pri_error(pri, "PTP MDL can't handle error of type %c\n", error);
+ }
+
+ return handled;
+}
+
+static void q921_mdl_handle_error(struct pri *pri, char error, int errored_state)
+{
+ int handled = 0;
+ if (PTP_MODE(pri)) {
+ handled = q921_mdl_handle_ptp_error(pri, error);
+ } else {
+ if (pri->localtype == PRI_NETWORK) {
+ handled = q921_mdl_handle_network_error(pri, error);
+ } else {
+ handled = q921_mdl_handle_cpe_error(pri, error);
+ }
+ }
+
+ if (handled)
+ return;
+
+ switch (error) {
+ case 'C':
+ pri_error(pri, "MDL-ERROR (C): UA in state %d\n", errored_state);
+ break;
+ case 'D':
+ pri_error(pri, "MDL-ERROR (D): UA in state %d\n", errored_state);
+ break;
+ case 'A':
+ pri_error(pri, "MDL-ERROR (A): Got supervisory frame with p_f bit set to 1 in state %d\n", errored_state);
+ break;
+ case 'I':
+ pri_error(pri, "MDL-ERROR (I): T200 = N200 in timer recovery state %d\n", errored_state);
+ break;
+ case 'G':
+ pri_error(pri, "MDL-ERROR (G) : T200 expired N200 times in state %d\n", errored_state);
+ break;
+ case 'F':
+ pri_error(pri, "MDL-ERROR (F), SABME in state %d\n", errored_state);
+ break;
+ case 'H':
+ case 'B':
+ case 'E':
+ case 'J':
+ default:
+ pri_error(pri, "MDL-ERROR (%c) in state %d\n", error, errored_state);
+
+ }
+}
+
+static void q921_mdl_handle_error_callback(void *vpri)
+{
+ struct pri *pri = vpri;
+
+ q921_mdl_handle_error(pri, pri->mdl_error, pri->mdl_error_state);
+
+ pri->mdl_error = 0;
+ pri->mdl_timer = 0;
+}
+
+static void q921_mdl_error(struct pri *pri, char error)
+{
+ if (pri->mdl_error) {
+ pri_error(pri, "Trying to queue an MDL error when one is already scheduled\n");
+ return;
+ }
+ pri->mdl_error = error;
+ pri->mdl_error_state = pri->q921_state;
+ pri->mdl_timer = pri_schedule_event(pri, 0, q921_mdl_handle_error_callback, pri);
+}
+
+static pri_event *q921_ua_rx(struct pri *pri, q921_h *h)
+{
+ pri_event * res = NULL;
+
+ switch (pri->q921_state) {
+ case Q921_TEI_ASSIGNED:
+ //pri_error(pri, "MDL-ERROR (C, D): UA received in state %d\n", pri->q921_state);
+ if (h->u.p_f)
+ q921_mdl_error(pri, 'C');
+ else
+ q921_mdl_error(pri, 'D');
break;
case Q921_AWAITING_ESTABLISHMENT:
if (!h->u.p_f) {
@@ -1091,6 +1269,7 @@
if (pri->v_s != pri->v_a) {
q921_discard_iqueue(pri);
/* return DL-ESTABLISH-INDICATION */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
}
} else {
/* Might not want this... */
@@ -1100,8 +1279,10 @@
/* return DL-ESTABLISH-CONFIRM */
}
- pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
- res = &pri->ev;
+ if (PTP_MODE(pri)) {
+ pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
+ res = &pri->ev;
+ }
stop_t200(pri);
start_t203(pri);
@@ -1112,7 +1293,8 @@
break;
case Q921_AWAITING_RELEASE:
if (!h->u.p_f) {
- pri_error(pri, "MDL-ERROR (D): UA in state %d w with P_F bit 0\n", pri->q921_state);
+ //pri_error(pri, "MDL-ERROR (D): UA in state %d w with P_F bit 0\n", pri->q921_state);
+ q921_mdl_error(pri, 'D');
} else {
/* return DL-RELEASE-CONFIRM */
stop_t200(pri);
@@ -1121,7 +1303,8 @@
break;
case Q921_MULTI_FRAME_ESTABLISHED:
case Q921_TIMER_RECOVERY:
- pri_error(pri, "MDL-ERROR (C, D) UA in state %d\n", pri->q921_state);
+ //pri_error(pri, "MDL-ERROR (C, D) UA in state %d\n", pri->q921_state);
+ q921_mdl_error(pri, 'C');
break;
default:
pri_error(pri, "Don't know what to do with UA in state %d\n", pri->q921_state);
@@ -1147,7 +1330,7 @@
static void n_r_error_recovery(struct pri *pri)
{
- pri_error(pri, "MDL-ERROR (J)\n");
+ q921_mdl_error(pri, 'J');
q921_establish_data_link(pri);
@@ -1250,7 +1433,8 @@
}
} else {
if (h->s.p_f) {
- pri_message(pri, "MDL-ERROR (A): Got RR response with p_f bit set to 1 in state %d\n", pri->q921_state);
+ //pri_message(pri, "MDL-ERROR (A): Got RR response with p_f bit set to 1 in state %d\n", pri->q921_state);
+ q921_mdl_error(pri, 'A');
}
}
@@ -1334,7 +1518,8 @@
}
} else {
if (h->s.p_f) {
- pri_message(pri, "MDL-ERROR (A): Got REJ response with p_f bit set to 1 in state %d\n", pri->q921_state);
+ //pri_message(pri, "MDL-ERROR (A): Got REJ response with p_f bit set to 1 in state %d\n", pri->q921_state);
+ q921_mdl_error(pri, 'A');
}
}
@@ -1463,6 +1648,7 @@
q921_discard_iqueue(pri);
/* DL-RELEASE indication */
+ q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
stop_t200(pri);
q921_setstate(pri, Q921_TEI_ASSIGNED);
break;
@@ -1476,11 +1662,11 @@
case Q921_MULTI_FRAME_ESTABLISHED:
if (h->u.p_f) {
/* MDL-ERROR (B) indication */
- pri_error(pri, "MDL-ERROR (B)\n");
- break;
- }
-
- /* MDL-ERROR (E) indication */
+ q921_mdl_error(pri, 'B');
+ break;
+ }
+
+ q921_mdl_error(pri, 'E');
q921_establish_data_link(pri);
pri->l3initiated = 0;
q921_setstate(pri, Q921_AWAITING_ESTABLISHMENT);
@@ -1488,10 +1674,10 @@
case Q921_TIMER_RECOVERY:
if (h->u.p_f) {
/* MDL-ERROR (B) indication */
- pri_error(pri, "MDL-ERROR (B)\n");
+ q921_mdl_error(pri, 'B');
} else {
/* MDL-ERROR (E) indication */
- pri_error(pri, "MDL-ERROR (E)\n");
+ q921_mdl_error(pri, 'E');
}
q921_establish_data_link(pri);
pri->l3initiated = 0;
@@ -1515,7 +1701,7 @@
if (!is_command(pri, h)) {
if (h->s.p_f) {
/* MDL-ERROR (A) indication */
- pri_error(pri, "MDL-ERROR(A)\n");
+ q921_mdl_error(pri, 'A');
}
} else {
if (h->s.p_f) {
More information about the libpri-commits
mailing list