Ignore files generated in the dependency checks.
[libpri-bristuff.git] / q921.c
blobd3053947ec62ff39596ce827032e64a02386ba61
1 /*
2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@linux-support.net>
6 * Copyright (C) 2001-2005, Digium, Inc.
7 * All Rights Reserved.
8 * Copyright (C) 2003-2006 Junghanns.NET GmbH
9 * Klaus-Peter Junghanns <kpj@junghanns.net>
13 * See http://www.asterisk.org for more information about
14 * the Asterisk project. Please do not directly contact
15 * any of the maintainers of this project for assistance;
16 * the project provides a web site, mailing lists and IRC
17 * channels for your use.
19 * This program is free software, distributed under the terms of
20 * the GNU General Public License Version 2 as published by the
21 * Free Software Foundation. See the LICENSE file included with
22 * this program for more details.
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include "compat.h"
31 #include "libpri.h"
32 #include "pri_internal.h"
33 #include "pri_q921.h"
34 #include "pri_q931.h"
37 * Define RANDOM_DROPS To randomly drop packets in order to simulate loss for testing
38 * retransmission functionality
42 #define RANDOM_DROPS
45 #define Q921_INIT(pri, hf) do { \
46 memset(&(hf),0,sizeof(hf)); \
47 (hf).h.sapi = (pri)->sapi; \
48 (hf).h.ea1 = 0; \
49 (hf).h.ea2 = 1; \
50 (hf).h.tei = (pri)->tei; \
51 } while(0)
53 static void reschedule_t203(struct pri *pri, int tei);
54 static void q921_flush_txqueue(struct pri *pri, int tei, int devnull);
55 static void q921_send_teiverify(struct pri *pri,int tei);
57 static void q921_discard_retransmissions(struct pri *pri, int tei)
59 struct q921_frame *f, *p;
60 int teio = tei - Q921_TEI_BASE;
61 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
63 f = pri->txqueue[teio];
64 while(f) {
65 p = f;
66 f = f->next;
67 /* Free frame */
68 free(p);
70 pri->txqueue[teio] = NULL;
73 static int q921_transmit(struct pri *pri, q921_h *h, int len)
75 int res;
76 if (pri->master)
77 return q921_transmit(pri->master, h, len);
78 #ifdef RANDOM_DROPS
79 if (!(random() % 3)) {
80 pri_message(pri, " === Dropping Packet ===\n");
81 return 0;
83 #endif
84 #ifdef LIBPRI_COUNTERS
85 pri->q921_txcount++;
86 #endif
87 /* Just send it raw */
88 if (pri->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
89 q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 1);
90 /* Write an extra two bytes for the FCS */
91 res = pri->write_func ? pri->write_func(pri, h, len + 2) : 0;
92 if (res != (len + 2)) {
93 pri_error(pri, "Short write: %d/%d (%s)\n", res, len + 2, strerror(errno));
94 return -1;
96 if (pri->localtype == BRI_CPE_PTMP) {
97 reschedule_t203(pri, pri->tei);
98 } else if (h->h.tei != Q921_TEI_GROUP) {
99 reschedule_t203(pri, h->h.tei);
101 return 0;
104 static void q921_send_ua(struct pri *pri, int pfbit, int tei)
106 q921_h h;
107 Q921_INIT(pri, h);
108 h.u.m3 = 3; /* M3 = 3 */
109 h.u.m2 = 0; /* M2 = 0 */
110 h.u.p_f = pfbit; /* Final bit on */
111 h.u.ft = Q921_FRAMETYPE_U;
112 h.h.tei = tei;
113 switch(pri->localtype) {
114 case PRI_NETWORK:
115 h.h.c_r = 0;
116 break;
117 case PRI_CPE:
118 h.h.c_r = 1;
119 break;
120 case BRI_NETWORK_PTMP:
121 h.h.c_r = 0;
122 break;
123 case BRI_CPE_PTMP:
124 h.h.tei = pri->tei;
125 h.h.c_r = 1;
126 break;
127 case BRI_NETWORK:
128 h.h.c_r = 0;
129 break;
130 case BRI_CPE:
131 h.h.c_r = 1;
132 break;
133 default:
134 pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
135 return;
137 if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
138 pri_message(pri, "Sending Unnumbered Acknowledgement\n");
139 q921_transmit(pri, &h, 3);
143 static void q921_send_disconnect(struct pri *pri, int pfbit, int tei) {
144 q921_h h;
145 Q921_INIT(pri, h);
146 h.u.m3 = 2;
147 h.u.m2 = 0;
148 h.u.p_f = pfbit;
149 h.u.ft = Q921_FRAMETYPE_U;
150 h.h.tei = tei;
151 switch(pri->localtype) {
152 case PRI_NETWORK:
153 h.h.c_r = 0;
154 break;
155 case PRI_CPE:
156 h.h.c_r = 1;
157 break;
158 case BRI_NETWORK_PTMP:
159 h.h.c_r = 0;
160 break;
161 case BRI_CPE_PTMP:
162 h.h.tei = pri->tei;
163 h.h.c_r = 1;
164 break;
165 case BRI_NETWORK:
166 h.h.c_r = 0;
167 break;
168 case BRI_CPE:
169 h.h.c_r = 1;
170 break;
171 default:
172 pri_error(pri, "Don't know how to disconnect on a type %d node\n", pri->localtype);
173 return;
175 if (pri->debug & PRI_DEBUG_Q921_STATE)
176 pri_message(pri, "Sending Disconnect\n");
177 q921_transmit(pri, &h, 3);
181 static void q921_send_dm(struct pri *pri, int pfbit, int tei)
183 q921_h h;
184 Q921_INIT(pri, h);
185 h.u.m3 = 0; /* M3 = 0 */
186 h.u.m2 = 3; /* M2 = 3 */
187 h.u.p_f = pfbit; /* Final bit on */
188 h.u.ft = Q921_FRAMETYPE_U;
189 h.h.tei = tei;
190 switch(pri->localtype) {
191 case PRI_NETWORK:
192 h.h.c_r = 0;
193 break;
194 case PRI_CPE:
195 h.h.c_r = 1;
196 break;
197 case BRI_NETWORK_PTMP:
198 h.h.c_r = 0;
199 break;
200 case BRI_CPE_PTMP:
201 h.h.tei = pri->tei;
202 h.h.c_r = 1;
203 break;
204 case BRI_NETWORK:
205 h.h.c_r = 0;
206 break;
207 case BRI_CPE:
208 h.h.c_r = 1;
209 break;
210 default:
211 pri_error(pri, "Don't know how to DM on a type %d node\n", pri->localtype);
212 return;
214 if (pri->debug & PRI_DEBUG_Q921_STATE)
215 pri_message(pri, "Sending DM\n");
216 q921_transmit(pri, &h, 3);
219 static void q921_send_teireq(void *vpri) {
220 struct pri *pri = vpri;
221 unsigned short ri=0x6464;
222 q921_u *f;
223 ri = rand();
225 if (pri->localtype != BRI_CPE_PTMP) {
226 pri_error(pri, "TEI req for non-ptmp???\n");
227 return;
229 if (pri->t202_timer[0]) {
230 pri_schedule_del(pri, pri->t202_timer[0]);
231 pri->t202_timer[0] = 0;
233 if (pri->sabme_retrans[0]++ > (pri->timers[PRI_TIMER_N202])) {
234 /* delete txqueue */
235 q921_flush_txqueue(pri, 0, 1);
236 /* N202 retransmissions, activation of layer 2 failed, tell upper layer, start again */
237 pri->schedev = 1;
238 pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
239 pri->ev.gen.tei = 0;
240 pri->sabme_retrans[0] = 0;
241 q921_send_teiverify(pri, 127);
242 #ifdef RELAX_TRB
243 pri->t202_timer[0] = pri_schedule_event(pri, pri->timers[PRI_TIMER_T202] + 3000, q921_send_teireq, pri);
244 #endif
245 return;
248 pri->t202_timer[0] = pri_schedule_event(pri, pri->timers[PRI_TIMER_T202], q921_send_teireq, pri);
250 pri->ri = ri;
251 f = malloc(sizeof(q921_u) + 5 + 2);
252 memset(f,0x0,sizeof(q921_u) + 5 + 2);
253 if (f) {
254 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
255 f->h.tei = Q921_TEI_GROUP;
256 f->h.c_r = 0;
257 f->h.ea1 = 0;
258 f->h.ea2 = 1;
259 f->m2 = 0;
260 f->m3 = 0;
261 f->ft = Q921_FRAMETYPE_U;
262 f->data[0] = 0xf;
263 f->data[1] = ri >> 8;
264 f->data[2] = ri & 0xff;
265 f->data[3] = Q921_TEI_ID_REQUEST;
266 f->data[4] = 0xff;
267 if (pri->debug & PRI_DEBUG_Q921_STATE)
268 pri_message(pri, "Sending TEI Request ri=%d\n",ri);
269 q921_transmit(pri,(q921_h *)&(f->h),8);
273 static void q921_send_teiassign(struct pri *pri,int ri,int tei) {
274 q921_u *f;
276 if (pri->localtype != BRI_NETWORK_PTMP) {
277 pri_error(pri, "TEI assign for non-ptmp???\n");
278 return;
281 f = malloc(sizeof(q921_u) + 5 + 2);
282 memset(f,0x0,sizeof(q921_u) + 5 + 2);
283 if (f) {
284 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
285 f->h.tei = Q921_TEI_GROUP;
286 f->h.c_r = 1;
287 f->h.ea1 = 0;
288 f->h.ea2 = 1;
289 f->m2 = 0;
290 f->m3 = 0;
291 f->ft = Q921_FRAMETYPE_U;
292 f->data[0] = 0xf;
293 f->data[1] = ri >> 8;
294 f->data[2] = ri & 0xff;
295 f->data[3] = Q921_TEI_ID_ASSIGNED;
296 f->data[4] = (tei << 1) | 0x1;
297 if (pri->debug & PRI_DEBUG_Q921_STATE)
298 pri_message(pri, "Sending TEI assign ri=%d tei=%d\n",ri,tei);
299 q921_transmit(pri,(q921_h *)&(f->h),8);
300 free(f);
301 } else {
302 pri_error(pri, "q921_send_teiassign: failed to malloc f!\n");
306 static void q921_send_teichkresp(struct pri *pri,int tei) {
307 q921_u *f;
308 unsigned short ri=0x6464;
309 ri = rand();
311 if (pri->localtype != BRI_CPE_PTMP) {
312 pri_error(pri, "TEI check response for non-ptmp???\n");
313 return;
316 f = malloc(sizeof(q921_u) + 5 + 2);
317 memset(f,0x0,sizeof(q921_u) + 5 + 2);
318 if (f) {
319 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
320 f->h.tei = Q921_TEI_GROUP;
321 f->h.c_r = 0; // command u->n
322 f->h.ea1 = 0;
323 f->h.ea2 = 1;
324 f->m2 = 0;
325 f->m3 = 0;
326 f->ft = Q921_FRAMETYPE_U;
327 f->data[0] = 0xf;
328 f->data[1] = ri >> 8;
329 f->data[2] = ri & 0xff;
330 f->data[3] = Q921_TEI_ID_CHK_RES;
331 f->data[4] = (tei << 1) | 0x1;
332 if (pri->debug & PRI_DEBUG_Q921_STATE)
333 pri_message(pri, "Sending TEI check resp ri=%d tei=%d\n",ri,tei);
334 q921_transmit(pri,(q921_h *)&(f->h),8);
335 free(f);
339 static void q921_send_teichkreq(struct pri *pri,int tei) {
340 q921_u *f;
341 unsigned short ri=0x6464;
342 ri = rand();
344 if (pri->localtype != BRI_NETWORK_PTMP) {
345 pri_error(pri, "TEI check response for non-ptmp???\n");
346 return;
349 f = malloc(sizeof(q921_u) + 5 + 2);
350 memset(f,0x0,sizeof(q921_u) + 5 + 2);
351 if (f) {
352 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
353 f->h.tei = Q921_TEI_GROUP;
354 f->h.c_r = 1; // command u->n
355 f->h.ea1 = 0;
356 f->h.ea2 = 1;
357 f->m2 = 0;
358 f->m3 = 0;
359 f->ft = Q921_FRAMETYPE_U;
360 f->data[0] = 0xf;
361 f->data[1] = 0;
362 f->data[2] = 0;
363 f->data[3] = Q921_TEI_ID_CHK_REQ;
364 f->data[4] = (tei << 1) | 0x1;
365 if (pri->debug & PRI_DEBUG_Q921_STATE)
366 pri_message(pri, "Sending TEI check request ri=%d tei=%d\n",ri,tei);
367 q921_transmit(pri,(q921_h *)&(f->h),8);
368 free(f);
372 static void q921_send_teiverify(struct pri *pri,int tei) {
373 q921_u *f;
375 if ((pri->localtype != BRI_CPE) && (pri->localtype != BRI_CPE_PTMP)) {
376 pri_error(pri, "TEI verify for non-ptmp???\n");
377 return;
380 f = malloc(sizeof(q921_u) + 5 + 2);
381 memset(f,0x0,sizeof(q921_u) + 5 + 2);
382 if (f) {
383 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
384 f->h.tei = Q921_TEI_GROUP;
385 f->h.c_r = 0; // command u->n
386 f->h.ea1 = 0;
387 f->h.ea2 = 1;
388 f->m2 = 0;
389 f->m3 = 0;
390 f->ft = Q921_FRAMETYPE_U;
391 f->data[0] = 0xf;
392 f->data[1] = 0;
393 f->data[2] = 0;
394 f->data[3] = Q921_TEI_ID_VERIFY;
395 f->data[4] = (tei << 1) | 0x1;
396 if (pri->debug & PRI_DEBUG_Q921_STATE)
397 pri_message(pri, "Sending TEI verify tei=%d\n", tei);
398 q921_transmit(pri,(q921_h *)&(f->h),8);
399 free(f);
403 static void q921_send_teiremove(struct pri *pri, int tei) {
404 q921_u *f;
405 unsigned short ri=0x6464;
406 ri = rand();
408 if (pri->localtype != BRI_NETWORK_PTMP) {
409 pri_error(pri, "TEI remove for non-ptmp???\n");
410 return;
413 f = malloc(sizeof(q921_u) + 5 + 2);
414 memset(f,0x0,sizeof(q921_u) + 5 + 2);
415 if (f) {
416 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
417 f->h.tei = Q921_TEI_GROUP;
418 f->h.c_r = 1;
419 f->h.ea1 = 0;
420 f->h.ea2 = 1;
421 f->m2 = 0;
422 f->m3 = 0;
423 f->ft = Q921_FRAMETYPE_U;
424 f->data[0] = 0xf;
425 f->data[1] = ri >> 8;
426 f->data[2] = ri & 0xff;
427 f->data[3] = Q921_TEI_ID_REMOVE;
428 f->data[4] = (tei << 1) | 0x1;
429 if (pri->debug & PRI_DEBUG_Q921_STATE)
430 pri_message(pri, "Sending TEI remove tei=%d\n",tei);
431 q921_transmit(pri,(q921_h *)&(f->h),8);
432 free(f);
436 static void q921_send_teidenied(struct pri *pri, int ri, int tei) {
437 q921_u *f;
439 if (pri->localtype != BRI_NETWORK_PTMP) {
440 pri_error(pri, "TEI ID denied for non-ptmp???\n");
441 return;
444 f = malloc(sizeof(q921_u) + 5 + 2);
445 memset(f,0x0,sizeof(q921_u) + 5 + 2);
446 if (f) {
447 f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
448 f->h.tei = Q921_TEI_GROUP;
449 f->h.c_r = 1;
450 f->h.ea1 = 0;
451 f->h.ea2 = 1;
452 f->m2 = 0;
453 f->m3 = 0;
454 f->ft = Q921_FRAMETYPE_U;
455 f->data[0] = 0xf;
456 f->data[1] = ri >> 8;
457 f->data[2] = ri & 0xff;
458 f->data[3] = Q921_TEI_ID_DENIED;
459 f->data[4] = (tei << 1) | 0x1;
460 if (pri->debug & PRI_DEBUG_Q921_STATE)
461 pri_message(pri, "Sending TEI ID denied tei=%d\n",tei);
462 q921_transmit(pri,(q921_h *)&(f->h),8);
463 free(f);
468 static void q921_send_sabme_now(void *vpri, int tei);
470 static void q921_send_sabme(void *vpri, int now, int tei)
472 struct pri *pri = vpri;
473 q921_h h;
474 int teio=tei - Q921_TEI_BASE;
475 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
477 if (pri->sabme_timer[teio]) {
478 pri_schedule_del(pri, pri->sabme_timer[teio]);
479 pri->sabme_timer[teio] = 0;
481 pri->sabme_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], q921_send_sabme_now, pri, tei);
482 if (!now)
483 return;
484 if (pri->sabme_retrans[teio]++ > (pri->timers[PRI_TIMER_N202])) {
485 /* delete txqueue */
486 q921_flush_txqueue(pri, tei, 1);
487 /* N202 retransmissions, activation of layer 2 failed, tell upper layer, start again */
488 pri->schedev = 1;
489 pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
490 pri->ev.gen.tei = tei;
491 pri->sabme_retrans[teio] = 0;
492 #ifdef RELAX_TRB
493 pri->sabme_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200] + 3000, q921_send_sabme_now, pri, tei);
494 #endif
495 return;
497 Q921_INIT(pri, h);
498 // XXX
499 h.h.tei = tei;
500 h.u.m3 = 3; /* M3 = 3 */
501 h.u.m2 = 3; /* M2 = 3 */
502 h.u.p_f = 1; /* Poll bit set */
503 h.u.ft = Q921_FRAMETYPE_U;
504 switch(pri->localtype) {
505 case PRI_NETWORK:
506 h.h.c_r = 1;
507 break;
508 case PRI_CPE:
509 h.h.c_r = 0;
510 break;
511 case BRI_NETWORK_PTMP:
512 h.h.c_r = 1;
513 break;
514 case BRI_CPE_PTMP:
515 h.h.c_r = 0;
516 h.h.tei = pri->tei;
517 break;
518 case BRI_NETWORK:
519 h.h.c_r = 1;
520 break;
521 case BRI_CPE:
522 h.h.c_r = 0;
523 break;
524 default:
525 pri_error(pri, "Don't know how to send SABME on a type %d node\n", pri->localtype);
526 return;
528 if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
529 pri_message(pri, "Sending Set Asynchronous Balanced Mode Extended\n");
530 q921_transmit(pri, &h, 3);
531 if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state[teio] != Q921_AWAITING_ESTABLISH)
532 pri_message(pri, DBGHEAD "q921_state now is Q921_AWAITING_ESTABLISH\n", DBGINFO);
533 pri->q921_state[teio] = Q921_AWAITING_ESTABLISH;
536 static void q921_send_sabme_now(void *vpri, int tei)
538 q921_send_sabme(vpri, 1, tei);
542 static int q921_ack_packet(struct pri *pri, int num, int tei)
544 struct q921_frame *f, *prev = NULL;
545 int teio=tei - Q921_TEI_BASE;
546 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
547 f = pri->txqueue[teio];
549 while(f) {
550 if (f->h.n_s == num) {
551 /* Cancel each packet as necessary */
552 /* That's our packet */
553 if (prev)
554 prev->next = f->next;
555 else
556 pri->txqueue[teio] = f->next;
557 if (pri->debug & PRI_DEBUG_Q921_DUMP)
558 pri_message(pri, "-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue[teio] ? pri->txqueue[teio]->h.n_s : -1);
559 /* Update v_a */
560 pri->v_a[teio] = num;
561 free(f);
562 /* Reset retransmission counter if we actually acked something */
563 pri->retrans[teio] = 0;
564 /* Decrement window size */
565 pri->windowlen[teio]--;
566 /* Search for something to send */
567 f = pri->txqueue[teio];
568 while(f) {
569 if (!f->transmitted) {
570 /* Send it now... */
571 if (pri->debug & PRI_DEBUG_Q921_DUMP)
572 pri_message(pri, "-- Finally transmitting %d, since window opened up\n", f->h.n_s);
573 f->transmitted++;
574 pri->windowlen[teio]++;
575 f->h.n_r = pri->v_r[teio];
576 q921_transmit(pri, (q921_h *)(&f->h), f->len);
577 break;
579 f = f->next;
581 return 1;
583 prev = f;
584 f = f->next;
586 return 0;
589 static void t203_expire(void *, int tei);
590 static void t200_expire(void *, int tei);
591 static pri_event *q921_dchannel_down(struct pri *pri, int tei);
593 static void reschedule_t203(struct pri *pri, int tei)
595 int teio=tei - Q921_TEI_BASE;
596 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
597 if (pri->t203_timer[teio]) {
598 pri_schedule_del(pri, pri->t203_timer[teio]);
599 pri->t203_timer[teio] = 0;
600 if (pri->q921_state[teio] != Q921_LINK_CONNECTION_RELEASED) {
601 if (pri->debug & PRI_DEBUG_Q921_STATE)
602 pri_message(pri, "-- Restarting T203 counter\n");
603 /* Nothing to transmit, start the T203 counter instead */
604 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
609 static void q921_flush_txqueue(struct pri *pri, int tei, int devnull)
611 struct q921_frame *f, *tmp = NULL;
612 int teio=tei - Q921_TEI_BASE;
613 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
614 f = pri->txqueue[teio];
616 /* nothing to send */
617 if (!f) return;
619 /* transmit all i-frames that were queued up while we were waiting for layer 2 to rise */
620 while(f) {
621 if (devnull) {
622 tmp = f;
623 f = f->next;
624 free(tmp);
625 tmp = NULL;
626 } else {
627 if (pri->localtype == BRI_CPE_PTMP) {
628 /* update TEI, it might have changed */
629 f->h.h.tei = pri->tei;
631 q921_transmit(pri, (q921_h *)&f->h, f->len);
632 f->transmitted++;
633 f = f->next;
637 if (devnull) {
638 pri->txqueue[teio] = NULL;
639 pri->v_s[teio] = 0;
640 } else {
641 if (pri->t200_timer[teio]) {
642 pri_schedule_del(pri, pri->t200_timer[teio]);
643 pri->t200_timer[teio] = 0;
645 if (pri->t203_timer[teio]) {
646 pri_schedule_del(pri, pri->t203_timer[teio]);
647 pri->t203_timer[teio] = 0;
649 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
653 static pri_event *q921_ack_rx(struct pri *pri, int ack, int tei)
655 int x;
656 int cnt=0;
657 pri_event *ev;
658 int teio=tei - Q921_TEI_BASE;
659 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
660 /* Make sure the ACK was within our window */
661 for (x=pri->v_a[teio]; (x != pri->v_s[teio]) && (x != ack); Q921_INC(x));
662 if (x != ack) {
663 /* ACK was outside of our window --- ignore */
664 pri_error(pri, "ACK received for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a[teio], pri->v_s[teio]);
665 ev = q921_dchannel_down(pri, tei);
666 q921_start(pri, 1, tei);
667 pri->schedev = 1;
668 return ev;
670 /* Cancel each packet as necessary */
671 if (pri->debug & PRI_DEBUG_Q921_DUMP)
672 pri_message(pri, "-- ACKing all packets from %d to (but not including) %d\n", pri->v_a[teio], ack);
673 for (x=pri->v_a[teio]; x != ack; Q921_INC(x))
674 cnt += q921_ack_packet(pri, x, tei);
675 if (!pri->txqueue[teio]) {
676 /* Something was ACK'd. Stop T200 counter */
677 pri_schedule_del(pri, pri->t200_timer[teio]);
678 pri->t200_timer[teio] = 0;
679 if (pri->debug & PRI_DEBUG_Q921_DUMP)
680 pri_message(pri, "-- Since there was nothing left, stopping T200 counter\n");
682 if (pri->t203_timer[teio]) {
683 pri_schedule_del(pri, pri->t203_timer[teio]);
684 pri->t203_timer[teio] = 0;
685 if (pri->debug & PRI_DEBUG_Q921_DUMP)
686 pri_message(pri, "-- Stopping T203 counter since we got an ACK\n");
688 if (pri->txqueue[teio]) {
689 /* Something left to transmit, Start the T200 counter again if we stopped it */
690 if (pri->debug & PRI_DEBUG_Q921_DUMP)
691 pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue[teio]->h.n_s);
692 if (!pri->t200_timer[teio])
693 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
694 } else {
695 if (pri->debug & PRI_DEBUG_Q921_DUMP)
696 pri_message(pri, "-- Nothing left, starting T203 counter\n");
697 /* Nothing to transmit, start the T203 counter instead */
698 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
700 return NULL;
703 static void q921_reject(struct pri *pri, int pf, int tei)
705 q921_h h;
706 int teio=tei - Q921_TEI_BASE;
707 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
708 Q921_INIT(pri, h);
709 h.s.x0 = 0; /* Always 0 */
710 h.s.ss = 2; /* Reject */
711 h.s.ft = 1; /* Frametype (01) */
712 h.s.n_r = pri->v_r[teio]; /* Where to start retransmission */
713 h.s.p_f = pf;
714 switch(pri->localtype) {
715 case PRI_NETWORK:
716 h.h.c_r = 0;
717 break;
718 case PRI_CPE:
719 h.h.c_r = 1;
720 break;
721 case BRI_NETWORK_PTMP:
722 h.h.c_r = 0;
723 break;
724 case BRI_CPE_PTMP:
725 h.h.c_r = 1;
726 h.h.tei = tei;
727 break;
728 case BRI_NETWORK:
729 h.h.c_r = 0;
730 break;
731 case BRI_CPE:
732 h.h.c_r = 1;
733 break;
734 default:
735 pri_error(pri, "Don't know how to REJECT on a type %d node\n", pri->localtype);
736 return;
738 if (pri->debug & PRI_DEBUG_Q921_DUMP)
739 pri_message(pri, "Sending Reject (%d)\n", pri->v_r[teio]);
740 pri->sentrej[teio] = 1;
741 q921_transmit(pri, &h, 4);
744 static void q921_rr(struct pri *pri, int pbit, int cmd, int tei) {
745 q921_h h;
746 int teio=tei - Q921_TEI_BASE;
747 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
748 Q921_INIT(pri, h);
749 h.s.x0 = 0; /* Always 0 */
750 h.s.ss = 0; /* Receive Ready */
751 h.s.ft = 1; /* Frametype (01) */
752 h.s.n_r = pri->v_r[teio]; /* N/R */
753 h.s.p_f = pbit; /* Poll/Final set appropriately */
754 switch(pri->localtype) {
755 case PRI_NETWORK:
756 if (cmd)
757 h.h.c_r = 1;
758 else
759 h.h.c_r = 0;
760 break;
761 case PRI_CPE:
762 if (cmd)
763 h.h.c_r = 0;
764 else
765 h.h.c_r = 1;
766 break;
767 case BRI_NETWORK_PTMP:
768 h.h.tei = tei;
769 if (cmd)
770 h.h.c_r = 1;
771 else
772 h.h.c_r = 0;
773 break;
774 case BRI_CPE_PTMP:
775 h.h.tei = tei;
776 if (cmd)
777 h.h.c_r = 0;
778 else
779 h.h.c_r = 1;
780 break;
781 case BRI_NETWORK:
782 if (cmd)
783 h.h.c_r = 1;
784 else
785 h.h.c_r = 0;
786 break;
787 case BRI_CPE:
788 if (cmd)
789 h.h.c_r = 0;
790 else
791 h.h.c_r = 1;
792 break;
793 default:
794 pri_error(pri, "Don't know how to RR on a type %d node\n", pri->localtype);
795 return;
797 pri->v_na[teio] = pri->v_r[teio]; /* Make a note that we've already acked this */
798 if (pri->debug & PRI_DEBUG_Q921_DUMP)
799 pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r[teio]);
800 q921_transmit(pri, &h, 4);
803 static void t200_expire(void *vpri, int tei)
805 struct pri *pri = vpri;
806 int teio=tei - Q921_TEI_BASE;
807 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
808 if (pri->txqueue[teio]) {
809 /* Retransmit first packet in the queue, setting the poll bit */
810 if (pri->debug & PRI_DEBUG_Q921_DUMP)
811 pri_message(pri, "-- T200 counter expired, What to do...\n");
812 /* Force Poll bit */
813 pri->txqueue[teio]->h.p_f = 1;
814 /* Update nr */
815 pri->txqueue[teio]->h.n_r = pri->v_r[teio];
816 pri->v_na[teio] = pri->v_r[teio];
817 pri->solicitfbit[teio] = 1;
818 pri->retrans[teio]++;
819 /* Up to three retransmissions */
820 if (pri->retrans[teio] + 1 < pri->timers[PRI_TIMER_N200]) {
821 /* Reschedule t200_timer */
822 if (pri->debug & PRI_DEBUG_Q921_DUMP)
823 pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue[teio]->len);
824 if (pri->busy[teio])
825 q921_rr(pri, 1, 1, tei);
826 else {
827 if (!pri->txqueue[teio]->transmitted)
828 pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
829 q921_transmit(pri, (q921_h *)&pri->txqueue[teio]->h, pri->txqueue[teio]->len);
831 if (pri->debug & PRI_DEBUG_Q921_DUMP)
832 pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans[teio]);
833 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
834 } else {
835 if (pri->debug & PRI_DEBUG_Q921_STATE)
836 pri_message(pri, "-- Timeout occured, restarting PRI\n");
837 if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state[teio] != Q921_LINK_CONNECTION_RELEASED)
838 pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n",DBGINFO);
839 pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
840 pri->t200_timer[teio] = 0;
841 q921_dchannel_down(pri, tei);
842 q921_start(pri, 1, tei);
843 pri->schedev = 1;
845 } else if (pri->solicitfbit[teio]) {
846 if (pri->debug & PRI_DEBUG_Q921_DUMP)
847 pri_message(pri, "-- Retrying poll with f-bit\n");
848 pri->retrans[teio]++;
849 if (pri->retrans[teio] < pri->timers[PRI_TIMER_N200]) {
850 pri->solicitfbit[teio] = 1;
851 q921_rr(pri, 1, 1, tei);
852 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
853 } else {
854 if (pri->debug & PRI_DEBUG_Q921_STATE)
855 pri_message(pri, "-- Timeout occured, restarting PRI\n");
856 if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state[teio] != Q921_LINK_CONNECTION_RELEASED)
857 pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);
858 pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
859 pri->t200_timer[teio] = 0;
860 q921_dchannel_down(pri, tei);
861 q921_start(pri, 1, tei);
862 pri->schedev = 1;
864 } else {
865 pri_error(pri, "T200 counter expired, nothing to send...\n");
866 pri->t200_timer[teio] = 0;
867 if (pri->busy[teio]) {
868 if ((pri->retrans[teio] + 1) <= pri->timers[PRI_TIMER_N200]) {
869 /* poll RR */
870 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
871 pri->retrans[teio]++;
872 q921_rr(pri, 1, 1, tei);
873 } else {
874 q921_reset(pri, tei, 1);
875 q921_start(pri, 1, tei);
881 int q921_transmit_uframe(struct pri *pri, void *buf, int len, int cr, int tei)
883 q921_u *uf;
884 uf = malloc(sizeof(q921_u) + len + 2);
885 memset(uf,0,sizeof(q921_u) + len + 2);
887 uf->h.sapi = 0;
888 uf->h.ea1 = 0;
889 uf->h.ea2 = 1;
890 uf->h.tei = tei;
891 uf->m3 = 0;
892 uf->m2 = 0;
893 uf->ft = Q921_FRAMETYPE_U;
894 switch(pri->localtype) {
895 case PRI_NETWORK:
896 uf->h.c_r = 1;
897 break;
898 case PRI_CPE:
899 uf->h.c_r = 0;
900 break;
901 case BRI_NETWORK_PTMP:
902 uf->h.c_r = 1;
903 break;
904 case BRI_CPE_PTMP:
905 uf->h.c_r = 0;
906 break;
907 case BRI_NETWORK:
908 uf->h.c_r = 1;
909 break;
910 case BRI_CPE:
911 uf->h.c_r = 0;
912 break;
913 default:
914 pri_error(pri, "Don't know how to send U frames on a type %d node\n", pri->localtype);
915 return -1;
917 memcpy(uf->data,buf,len);
918 q921_transmit(pri, (q921_h*)&(uf->h), 3+len);
919 free(uf);
920 return 0;
923 int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr, int tei)
925 q921_frame *f, *prev=NULL;
926 int teio=tei - Q921_TEI_BASE;
927 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
928 if ((pri->q921_state[teio] == Q921_LINK_CONNECTION_RELEASED) && (!pri->sabme_timer[teio])) {
929 if (pri->localtype == BRI_CPE_PTMP) {
930 if (pri->tei > 0) {
931 /* p2p datalink is down */
932 pri->sabme_retrans[teio] = 0;
933 q921_send_sabme_now(pri, pri->tei);
934 if (pri->debug & PRI_DEBUG_Q921_STATE)
935 pri_message(pri, "Reactivating layer 2\n");
936 } else {
937 /* no tei */
938 if (pri->debug & PRI_DEBUG_Q921_STATE)
939 pri_message(pri, "reactivating layer 2, sending tei req\n");
940 q921_send_teireq(pri);
942 } else if ((pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
943 /* p2p datalink is down */
944 pri->sabme_retrans[teio] = 0;
945 q921_send_sabme_now(pri, pri->tei);
946 if (pri->debug & PRI_DEBUG_Q921_STATE)
947 pri_message(pri, "Reactivating layer 2\n");
950 for (f=pri->txqueue[teio]; f; f = f->next) prev = f;
951 f = malloc(sizeof(q921_frame) + len + 2);
952 if (f) {
953 memset(f,0,sizeof(q921_frame) + len + 2);
954 Q921_INIT(pri, f->h);
955 switch(pri->localtype) {
956 case PRI_NETWORK:
957 if (cr)
958 f->h.h.c_r = 1;
959 else
960 f->h.h.c_r = 0;
961 break;
962 case PRI_CPE:
963 if (cr)
964 f->h.h.c_r = 0;
965 else
966 f->h.h.c_r = 1;
967 break;
968 case BRI_NETWORK_PTMP:
969 f->h.h.tei = tei;
970 if (cr)
971 f->h.h.c_r = 1;
972 else
973 f->h.h.c_r = 0;
974 break;
975 case BRI_CPE_PTMP:
976 f->h.h.tei = pri->tei;
977 if (cr)
978 f->h.h.c_r = 0;
979 else
980 f->h.h.c_r = 1;
981 break;
982 case BRI_NETWORK:
983 if (cr)
984 f->h.h.c_r = 1;
985 else
986 f->h.h.c_r = 0;
987 break;
988 case BRI_CPE:
989 if (cr)
990 f->h.h.c_r = 0;
991 else
992 f->h.h.c_r = 1;
993 break;
995 f->next = NULL;
996 f->transmitted = 0;
997 f->len = len + 4;
998 memcpy(f->h.data, buf, len);
999 f->h.n_s = pri->v_s[teio];
1000 f->h.n_r = pri->v_r[teio];
1001 pri->v_s[teio]++;
1002 pri->v_na[teio] = pri->v_r[teio];
1003 f->h.p_f = 0;
1004 f->h.ft = 0;
1005 if (prev)
1006 prev->next = f;
1007 else
1008 pri->txqueue[teio] = f;
1010 if ((pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) && ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK))){
1011 /* no p2p datalink, yet. queue up the iframes... */
1012 if (pri->debug & PRI_DEBUG_Q921_STATE)
1013 pri_message(pri, "Layer 3 transmit waiting for layer 2\n");
1014 } else {
1015 /* Immediately transmit unless we're in a recovery state, or the window
1016 size is too big */
1017 if (!pri->retrans[teio] && !pri->busy[teio]) {
1018 if (pri->windowlen[teio] < pri->window[teio]) {
1019 pri->windowlen[teio]++;
1020 q921_transmit(pri, (q921_h *)(&f->h), f->len);
1021 f->transmitted++;
1022 } else {
1023 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1024 pri_message(pri, "Delaying transmission of %d, window is %d/%d long\n",
1025 f->h.n_s, pri->windowlen[teio], pri->window[teio]);
1028 if (pri->t203_timer[teio]) {
1029 pri_schedule_del(pri, pri->t203_timer[teio]);
1030 pri->t203_timer[teio] = 0;
1031 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1032 pri_message(pri, "Stopping T_203 timer\n");
1034 if (!pri->t200_timer[teio]) {
1035 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
1036 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1037 pri_message(pri, "Starting T_200 timer\n");
1038 } else {
1039 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1040 pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer[teio]);
1043 } else {
1044 pri_error(pri, "!! Out of memory for Q.921 transmit\n");
1045 return -1;
1047 return 0;
1050 static void t203_expire(void *vpri, int tei)
1052 struct pri *pri = vpri;
1053 int teio=tei - Q921_TEI_BASE;
1054 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1055 if (pri->q921_state[teio] == Q921_LINK_CONNECTION_ESTABLISHED) {
1056 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1057 pri_message(pri, "T203 counter expired, sending RR and scheduling T203 again\n");
1058 /* Solicit an F-bit in the other's RR */
1059 pri->solicitfbit[teio] = 1;
1060 pri->retrans[teio] = 0;
1061 q921_rr(pri, 1, 1, tei);
1062 /* Start timer T200 to resend our RR if we don't get it */
1063 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
1064 } else {
1065 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1066 pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state[teio]);
1067 pri->t203_timer[teio] = 0;
1071 static void q921_start_tei(struct pri *pri, int tei);
1074 static void t201_expire(void *vpri, int tei)
1076 struct pri *pri = vpri;
1077 int teio=tei - Q921_TEI_BASE;
1078 int i = 0;
1079 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1080 if (tei == Q921_TEI_GROUP) {
1081 for (i=0;i<Q921_MAX_TEIS;i++) {
1082 if (pri->q921_tei_check[i] == 1) {
1083 pri->q921_tei_check[i] = 0;
1084 q921_start_tei(pri, Q921_TEI_BASE + i);
1087 } else {
1088 if (pri->q921_tei_check[teio] == 1) {
1089 pri->q921_tei_check[teio] = 0;
1090 q921_start_tei(pri, tei);
1093 pri->t201_timer[teio] = 0;
1096 static pri_event *q921_handle_iframe(struct pri *pri, q921_i *i, int len)
1098 int res;
1099 pri_event *ev;
1100 int teio= i->h.tei - Q921_TEI_BASE;
1101 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1102 /* Make sure this is a valid packet */
1103 if (i->n_s == pri->v_r[teio]) {
1104 /* Increment next expected I-frame */
1105 Q921_INC(pri->v_r[teio]);
1106 /* Handle their ACK */
1107 pri->sentrej[teio] = 0;
1108 ev = q921_ack_rx(pri, i->n_r, i->h.tei);
1109 if (ev)
1110 return ev;
1111 if (i->p_f) {
1112 /* If the Poll/Final bit is set, immediate send the RR */
1113 q921_rr(pri, 1, 0, i->h.tei);
1114 } else if (pri->busy) {
1115 q921_rr(pri, 0, 0, i->h.tei);
1117 /* Receive Q.931 data */
1118 res = q931_receive(pri, (q931_h *)i->data, len - 4, i->h.tei);
1119 /* Send an RR if one wasn't sent already */
1120 if (pri->v_na[teio] != pri->v_r[teio])
1121 q921_rr(pri, 0, 0, i->h.tei);
1122 if (res == -1) {
1123 return NULL;
1125 if (res & Q931_RES_HAVEEVENT)
1126 return &pri->ev;
1127 } else {
1128 /* If we haven't already sent a reject, send it now, otherwise
1129 we are obliged to RR */
1130 if (!pri->sentrej[teio])
1131 q921_reject(pri, i->p_f, i->h.tei);
1132 else if (i->p_f)
1133 q921_rr(pri, 1, 0, i->h.tei);
1135 return NULL;
1138 void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx)
1140 int x;
1141 char *type;
1142 char direction_tag;
1144 direction_tag = txrx ? '>' : '<';
1145 if (showraw) {
1146 char *buf = malloc(len * 3 + 1);
1147 int buflen = 0;
1148 if (buf) {
1149 for (x=0;x<len;x++)
1150 buflen += sprintf(buf + buflen, "%02x ", h->raw[x]);
1151 pri_message(pri, "\n%c [ %s]\n", direction_tag, buf);
1152 free(buf);
1156 switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
1157 case 0:
1158 case 2:
1159 pri_message(pri, "\n%c Informational frame:\n", direction_tag);
1160 break;
1161 case 1:
1162 pri_message(pri, "\n%c Supervisory frame:\n", direction_tag);
1163 break;
1164 case 3:
1165 pri_message(pri, "\n%c Unnumbered frame:\n", direction_tag);
1166 break;
1169 pri_message(pri,
1170 "%c SAPI: %02d C/R: %d EA: %d\n"
1171 "%c TEI: %03d EA: %d\n",
1172 direction_tag,
1173 h->h.sapi,
1174 h->h.c_r,
1175 h->h.ea1,
1176 direction_tag,
1177 h->h.tei,
1178 h->h.ea2);
1179 switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
1180 case 0:
1181 case 2:
1182 /* Informational frame */
1183 pri_message(pri,
1184 "%c N(S): %03d 0: %d\n"
1185 "%c N(R): %03d P: %d\n"
1186 "%c %d bytes of data\n",
1187 direction_tag,
1188 h->i.n_s,
1189 h->i.ft,
1190 direction_tag,
1191 h->i.n_r,
1192 h->i.p_f,
1193 direction_tag,
1194 len - 4);
1195 break;
1196 case 1:
1197 /* Supervisory frame */
1198 type = "???";
1199 switch (h->s.ss) {
1200 case 0:
1201 type = "RR (receive ready)";
1202 break;
1203 case 1:
1204 type = "RNR (receive not ready)";
1205 break;
1206 case 2:
1207 type = "REJ (reject)";
1208 break;
1210 pri_message(pri,
1211 "%c Zero: %d S: %d 01: %d [ %s ]\n"
1212 "%c N(R): %03d P/F: %d\n"
1213 "%c %d bytes of data\n",
1214 direction_tag,
1215 h->s.x0,
1216 h->s.ss,
1217 h->s.ft,
1218 type,
1219 direction_tag,
1220 h->s.n_r,
1221 h->s.p_f,
1222 direction_tag,
1223 len - 4);
1224 break;
1225 case 3:
1226 /* Unnumbered frame */
1227 type = "???";
1228 if (h->u.ft == 3) {
1229 switch (h->u.m3) {
1230 case 0:
1231 if (h->u.m2 == 3)
1232 type = "DM (disconnect mode)";
1233 else if (h->u.m2 == 0)
1234 type = "UI (unnumbered information)";
1235 break;
1236 case 2:
1237 if (h->u.m2 == 0)
1238 type = "DISC (disconnect)";
1239 break;
1240 case 3:
1241 if (h->u.m2 == 3)
1242 type = "SABME (set asynchronous balanced mode extended)";
1243 else if (h->u.m2 == 0)
1244 type = "UA (unnumbered acknowledgement)";
1245 break;
1246 case 4:
1247 if (h->u.m2 == 1)
1248 type = "FRMR (frame reject)";
1249 break;
1250 case 5:
1251 if (h->u.m2 == 3)
1252 type = "XID (exchange identification note)";
1253 break;
1256 pri_message(pri,
1257 "%c M3: %d P/F: %d M2: %d 11: %d [ %s ]\n"
1258 "%c %d bytes of data\n",
1259 direction_tag,
1260 h->u.m3,
1261 h->u.p_f,
1262 h->u.m2,
1263 h->u.ft,
1264 type,
1265 direction_tag,
1266 len - 3);
1267 break;
1271 static void q921_tei_recovery(struct pri *pri, int tei) {
1272 int i = 0;
1273 int teio=tei - Q921_TEI_BASE;
1274 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1275 for (i=0;i<Q921_MAX_TEIS;i++) {
1276 if ((i + Q921_TEI_BASE == tei) || (tei == Q921_TEI_GROUP)) {
1277 pri->q921_tei_check[i] = 1;
1280 q921_send_teichkreq(pri, tei);
1281 if (!pri->t201_timer[teio]) {
1282 pri->t201_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T201], t201_expire, pri, tei);
1286 static pri_event *q921_dchannel_up(struct pri *pri, int tei)
1288 // q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
1289 // we treat this as MFE
1290 int teio=tei - Q921_TEI_BASE;
1291 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1293 if (((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) && (pri->txqueue[teio])) {
1294 /* Reset counters, etc */
1295 q921_reset(pri, tei, 0);
1296 } else {
1297 /* Reset counters, discard frames, etc */
1298 q921_reset(pri, tei, 1);
1301 /* Stop any SABME retransmissions */
1302 if (pri->sabme_timer[teio]) {
1303 pri_schedule_del(pri, pri->sabme_timer[teio]);
1304 pri->sabme_timer[teio] = 0;
1307 if (pri->t202_timer[teio]) {
1308 pri_schedule_del(pri, pri->t202_timer[teio]);
1309 pri->t202_timer[teio] = 0;
1312 /* neonova test */
1313 if (pri->t203_timer[teio]) {
1314 pri_schedule_del(pri, pri->t203_timer[teio]);
1315 pri->t203_timer[teio] = 0;
1318 /* Reset any rejects */
1319 pri->sentrej[teio] = 0;
1321 /* Go into connection established state */
1322 pri->q921_state[teio] = Q921_LINK_CONNECTION_ESTABLISHED;
1324 if (((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) && (pri->txqueue[teio])) {
1325 /* transmit queued iframes ans start T200 (handled by flush_txqueue) */
1326 q921_flush_txqueue(pri, tei, 0);
1327 /* dont upset upper layers if we reactivate layer 2 */
1328 return NULL;
1329 } else {
1330 /* Start the T203 timer */
1331 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
1333 /* Report event that D-Channel is now up */
1334 pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
1335 pri->ev.gen.tei = tei;
1336 return &pri->ev;
1340 static pri_event *q921_dchannel_down(struct pri *pri, int tei)
1342 int teio=tei - Q921_TEI_BASE;
1343 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1345 pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
1347 /* Reset counters, reset sabme timer etc */
1348 if (pri->localtype == BRI_NETWORK_PTMP) {
1349 if (pri->t203_timer[teio]) {
1350 pri_schedule_del(pri, pri->t203_timer[teio]);
1351 pri->t203_timer[teio] = 0;
1352 if (pri->debug & PRI_DEBUG_Q921_STATE) {
1353 pri_message(pri, "Stopping T_203 timer for TEI %d\n", tei);
1358 q921_reset(pri, tei, 1);
1360 /* Report event that D-Channel is now down */
1361 pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
1362 pri->ev.gen.tei = tei;
1363 return &pri->ev;
1366 void q921_reset(struct pri *pri, int tei, int discard)
1368 int teio=tei - Q921_TEI_BASE;
1369 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1370 /* Having gotten a SABME we MUST reset our entire state */
1371 if (discard) {
1372 pri->v_s[teio] = 0;
1374 pri->v_a[teio] = 0;
1375 pri->v_r[teio] = 0;
1376 pri->v_na[teio] = 0;
1377 pri->window[teio] = pri->timers[PRI_TIMER_K];
1378 pri->windowlen[teio] = 0;
1379 pri_schedule_del(pri, pri->sabme_timer[teio]);
1380 pri_schedule_del(pri, pri->t203_timer[teio]);
1381 pri_schedule_del(pri, pri->t200_timer[teio]);
1382 pri->sabme_timer[teio] = 0;
1383 pri->t203_timer[teio] = 0;
1384 pri->t200_timer[teio] = 0;
1385 pri_schedule_del(pri, pri->t202_timer[teio]);
1386 pri->t202_timer[teio] = 0;
1387 pri_schedule_del(pri, pri->t201_timer[teio]);
1388 pri->t201_timer[teio] = 0;
1389 pri->busy[teio] = 0;
1390 pri->solicitfbit[teio] = 0;
1391 pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
1392 pri->retrans[teio] = 0;
1393 pri->sabme_retrans[teio] = 0;
1394 pri->sentrej[teio] = 0;
1396 if (discard) {
1397 /* Discard anything waiting to go out */
1398 q921_discard_retransmissions(pri, tei);
1402 static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
1404 q921_frame *f;
1405 pri_event *ev;
1406 int sendnow;
1407 int tei;
1408 int res=-1;
1409 int teio=h->h.tei - Q921_TEI_BASE;
1410 if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
1412 switch(h->h.data[0] & Q921_FRAMETYPE_MASK) {
1413 case 0:
1414 case 2:
1415 if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
1416 pri_error(pri, "!! Got I-frame while link state %d\n", pri->q921_state[teio]);
1417 return NULL;
1419 /* Informational frame */
1420 if (len < 4) {
1421 pri_error(pri, "!! Received short I-frame (expected 4, got %d)\n", len);
1422 break;
1424 return q921_handle_iframe(pri, &h->i, len);
1425 break;
1426 case 1:
1427 if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
1428 pri_error(pri, "!! Got S-frame while link down\n");
1429 q921_send_dm(pri, 1, h->h.tei);
1430 q921_reset(pri, h->h.tei, 1);
1431 return NULL;
1433 if (len < 4) {
1434 pri_error(pri, "!! Received short S-frame (expected 4, got %d)\n", len);
1435 break;
1437 switch(h->s.ss) {
1438 case 0:
1439 /* Receiver Ready */
1440 pri->busy[teio] = 0;
1441 /* Acknowledge frames as necessary */
1442 ev = q921_ack_rx(pri, h->s.n_r, h->h.tei);
1443 if (ev)
1444 return ev;
1445 if (h->s.p_f) {
1446 /* If it's a p/f one then send back a RR in return with the p/f bit set */
1447 if (pri->solicitfbit[teio]) {
1448 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1449 pri_message(pri, "-- Got RR response to our frame\n");
1450 } else {
1451 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1452 pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
1453 q921_rr(pri, 1, 0, h->h.tei);
1455 pri->solicitfbit[teio] = 0;
1457 break;
1458 case 1:
1459 /* Receiver not ready */
1460 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1461 pri_message(pri, "-- Got receiver not ready\n");
1462 if ((pri->localtype != PRI_NETWORK) && (pri->localtype != BRI_NETWORK) && (pri->localtype != BRI_NETWORK_PTMP)) {
1463 if (h->s.p_f && h->s.h.c_r) {
1464 // if (!pri->t200_timer[teio]) {
1465 /* Send RR if poll bit set */
1466 q921_rr(pri, h->s.p_f, 0, h->h.tei);
1467 // }
1469 } else {
1470 if (h->s.p_f && (!h->s.h.c_r)) {
1471 // if (!pri->t200_timer[teio]) {
1472 /* Send RR if poll bit set */
1473 q921_rr(pri, h->s.p_f, 0, h->h.tei);
1474 // }
1477 pri->busy[teio] = 1;
1478 if (pri->t200_timer[teio]) {
1479 pri_schedule_del(pri, pri->t200_timer[teio]);
1480 pri->t200_timer[teio] = 0;
1482 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, h->h.tei);
1483 break;
1484 case 2:
1485 /* Just retransmit */
1486 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1487 pri_message(pri, "-- Got reject requesting packet %d... Retransmitting.\n", h->s.n_r);
1488 sendnow = 0;
1489 q921_ack_rx(pri, h->s.n_r, h->h.tei);
1490 /* Reset t200 timer if it was somehow going */
1491 if (pri->t200_timer[teio]) {
1492 pri_schedule_del(pri, pri->t200_timer[teio]);
1493 pri->t200_timer[teio] = 0;
1496 /* Resend the proper I-frame */
1497 for(f=pri->txqueue[teio];f;f=f->next) {
1498 if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {
1499 /* Matches the request, or follows in our window, and has
1500 already been transmitted. */
1501 sendnow = 1;
1502 pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
1503 f->h.n_r = pri->v_r[teio];
1504 q921_transmit(pri, (q921_h *)(&f->h), f->len);
1507 if (!sendnow) {
1508 if (pri->txqueue[teio]) {
1509 /* This should never happen */
1510 if (!h->s.p_f || h->s.n_r) {
1511 pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
1513 } else {
1514 /* Hrm, we have nothing to send, but have been REJ'd. Reset v_a, v_s, etc */
1515 pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
1516 pri->v_a[teio] = h->s.n_r;
1517 pri->v_s[teio] = h->s.n_r;
1518 /* Reset t200 timer if it was somehow going */
1519 if (pri->t200_timer[teio]) {
1520 pri_schedule_del(pri, pri->t200_timer[teio]);
1521 pri->t200_timer[teio] = 0;
1523 /* Reset and restart t203 timer */
1524 if (pri->t203_timer[teio])
1525 pri_schedule_del(pri, pri->t203_timer[teio]);
1526 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, h->h.tei);
1528 } else {
1529 if (h->s.p_f) {
1530 /* If it has the poll bit set (and an iframe was retransmitted), send an appropriate supervisory response */
1531 /* Reset t200 timer if it was somehow going */
1532 if (pri->t200_timer[teio]) {
1533 pri_schedule_del(pri, pri->t200_timer[teio]);
1534 pri->t200_timer[teio] = 0;
1536 /* Reset and restart t203 timer */
1537 pri->solicitfbit[teio] = 0;
1538 if (pri->t203_timer[teio])
1539 pri_schedule_del(pri, pri->t203_timer[teio]);
1540 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, h->h.tei);
1543 break;
1544 default:
1545 pri_error(pri, "!! XXX Unknown Supervisory frame ss=0x%02x,pf=%02xnr=%02x vs=%02x, va=%02x XXX\n", h->s.ss, h->s.p_f, h->s.n_r,
1546 pri->v_s[teio], pri->v_a[teio]);
1548 break;
1549 case 3:
1550 if (len < 3) {
1551 pri_error(pri, "!! Received short unnumbered frame\n");
1552 break;
1554 switch(h->u.m3) {
1555 case 0:
1556 if (h->u.m2 == 3) {
1557 if (h->u.p_f) {
1558 /* Section 5.7.1 says we should restart on receiving a DM response with the f-bit set to
1559 one, but we wait T200 first */
1560 if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
1561 pri_message(pri, "-- Got DM Mode from peer.\n");
1562 /* Disconnected mode, try again after T200 */
1563 ev = q921_dchannel_down(pri, h->h.tei);
1564 if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
1565 /* release layer 2 */
1566 // pri_error(pri, "got DM, restarting layer 2.\n");
1567 // return NULL;
1568 q921_start(pri, 0, h->h.tei);
1570 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)){
1571 q921_start(pri, 0, h->h.tei);
1573 return ev;
1575 } else {
1576 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1577 pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n");
1578 #if 0
1579 /* Requesting that we start */
1580 q921_start(pri, 0, h->h.tei);
1581 #endif
1583 break;
1584 } else if (h->u.m2 == 0) {
1585 if (h->u.ft == 3) {
1586 switch (h->u.data[0]) { /* Management Entity Identifier */
1587 case 0x0f:
1588 /* TEI Procedure */
1589 switch (h->u.data[3]) {
1590 case Q921_TEI_ID_VERIFY:
1591 if (pri->localtype != BRI_NETWORK_PTMP)
1592 break;
1593 if (pri->debug & PRI_DEBUG_Q921_STATE)
1594 pri_message(pri, "got TEI verify for TEI = %d\n",h->u.data[4] >> 1);
1595 break;
1596 case Q921_TEI_ID_ASSIGNED:
1597 if (pri->localtype != BRI_CPE_PTMP)
1598 break;
1599 if (pri->tei == (h->u.data[4] >> 1)) {
1600 // TEI already assgined, CHECK_TEI or REMOVE_TEI
1601 pri_error(pri, "Double assgined TEI!\n");
1603 if (pri->ri == ((unsigned short) (h->u.data[1] << 8) + h->u.data[2])) {
1604 if (pri->t202_timer[0]) {
1605 pri_schedule_del(pri, pri->t202_timer[0]);
1606 pri->t202_timer[0] = 0;
1608 pri->tei = h->u.data[4] >> 1;
1609 pri->ri = 0;
1610 if (pri->debug & PRI_DEBUG_Q921_STATE)
1611 pri_message(pri, "received TEI assign TEI = %d ri=%d\n",pri->tei,(unsigned short) (h->u.data[1] << 8) + h->u.data[2]);
1612 pri->sabme_retrans[teio] = 0;
1613 q921_send_sabme_now(pri, pri->tei);
1615 break;
1616 case Q921_TEI_ID_REMOVE:
1617 if (pri->localtype != BRI_CPE_PTMP)
1618 break;
1619 if (((h->u.data[4] >> 1) == Q921_TEI_GROUP) || (pri->tei == (h->u.data[4] >> 1))){
1620 if (pri->debug & PRI_DEBUG_Q921_STATE)
1621 pri_message(pri, "received TEI remove TEI = %d\n",pri->tei);
1622 pri->tei = 0;
1623 pri->ri = 0;
1624 // get a new TEI
1625 q921_reset(pri, 0, 1);
1626 q921_send_teireq(pri);
1628 break;
1629 case Q921_TEI_ID_REQUEST:
1630 if (pri->localtype != BRI_NETWORK_PTMP)
1631 break;
1633 tei = h->u.data[4] >> 1;
1634 if (tei != Q921_TEI_GROUP) {
1635 pri_message(pri, "got TEI request for unavailable TEI..\n");
1636 q921_send_teidenied(pri,((unsigned int)(h->u.data[1] << 8) + h->u.data[2]),h->u.data[4] >> 1);
1637 break;
1640 for (tei=0;tei<Q921_MAX_TEIS;tei++) {
1641 if (pri->q921_teis[tei] == 0) {
1642 pri->q921_teis[tei] = 1;
1643 break;
1646 if (tei < Q921_MAX_TEIS) {
1647 q921_send_teiassign(pri,((unsigned int)(h->u.data[1] << 8) + h->u.data[2]),tei + Q921_TEI_BASE);
1648 } else {
1649 pri_error(pri, "no TEI available. starting TEI recovery procedure. dont worry!\n");
1650 q921_tei_recovery(pri, 127);
1653 break;
1654 case Q921_TEI_ID_CHK_REQ:
1655 if (pri->localtype != BRI_CPE_PTMP)
1656 break;
1657 if ((((h->u.data[4] >> 1) == Q921_TEI_GROUP) || ((h->u.data[4] >> 1) == 0) || ((h->u.data[4] >> 1) == pri->tei)) && (pri->tei > 0)) {
1658 pri_message(pri, "received TEI check request for TEI = %d\n",h->u.data[4] >> 1);
1659 q921_send_teichkresp(pri, pri->tei);
1661 break;
1662 case Q921_TEI_ID_CHK_RES:
1663 if (pri->localtype != BRI_NETWORK_PTMP)
1664 break;
1665 teio = (h->u.data[4] >> 1) - Q921_TEI_BASE;
1666 if ((teio < 0) || (teio >= Q921_MAX_TEIS)) break;
1667 if (pri->q921_tei_check[teio] == 1) {
1668 pri->q921_tei_check_ri[teio] = (h->u.data[1] << 8) + h->u.data[2];
1669 pri->q921_tei_check[teio] = 0;
1670 } else {
1671 // d a t
1672 pri_error(pri, "double assgined tei for tei %d teio %d\n", h->u.data[4] >> 1, teio);
1673 pri->q921_tei_check[teio] = 0;
1674 q921_start_tei(pri, h->u.data[4] >> 1);
1676 break;
1677 default:
1678 pri_message(pri, "Ri = %d TEI msg = %x TEI = %x\n", (h->u.data[1] << 8) + h->u.data[2], h->u.data[3], h->u.data[4] >> 1);
1680 break;
1681 case Q931_PROTOCOL_DISCRIMINATOR:
1682 if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE)){
1683 res = q931_receive(pri, (q931_h *)h->u.data, len-3, h->h.tei);
1684 /* Send an RR if one wasn't sent already */
1685 if (pri->v_na[teio] != pri->v_r[teio])
1686 q921_rr(pri, 0, 0, pri->tei);
1687 if (res == -1) {
1688 return NULL;
1690 if (res & Q931_RES_HAVEEVENT)
1691 return &pri->ev;
1693 break;
1696 } else {
1697 pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
1699 break;
1700 case 2:
1701 if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
1702 pri_message(pri, "-- Got Disconnect from peer.\n");
1703 #ifndef RELAX_TRB
1704 if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
1705 q921_send_dm(pri, 1, h->h.tei);
1706 return NULL;
1708 #endif
1709 /* Acknowledge */
1710 q921_send_ua(pri, h->u.p_f, h->h.tei);
1711 ev = q921_dchannel_down(pri, h->h.tei);
1712 if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
1713 #ifndef LAYER2ALWAYSUP
1714 /* release layer 2 */
1715 return NULL;
1716 #else
1717 /* keep layer 2 up */
1718 if (pri->t203_timer[teio])
1719 pri_schedule_del(pri, pri->t203_timer[teio]);
1720 pri->t203_timer[teio] = 0;
1721 q921_send_sabme(pri, 1, pri->tei);
1722 #endif
1724 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)){
1725 q921_start(pri, 0, 0);
1727 return ev;
1728 case 3:
1729 if (h->u.m2 == 3) {
1730 /* SABME */
1731 if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP)) {
1732 pri_message(pri, "-- Got SABME from %s peer.\n", h->h.c_r ? "network" : "cpe");
1734 if (h->h.c_r) {
1735 pri->remotetype = PRI_NETWORK;
1736 if (pri->localtype == PRI_NETWORK) {
1737 /* We can't both be networks */
1738 return pri_mkerror(pri, "We think we're the network, but they think they're the network, too.");
1740 } else {
1741 pri->remotetype = PRI_CPE;
1742 if (pri->localtype == PRI_CPE) {
1743 /* We can't both be CPE */
1744 return pri_mkerror(pri, "We think we're the CPE, but they think they're the CPE too.\n");
1747 /* Send Unnumbered Acknowledgement */
1748 q921_send_ua(pri, h->u.p_f, h->h.tei);
1749 if (pri->q921_state[teio] == Q921_LINK_CONNECTION_RELEASED)
1750 return q921_dchannel_up(pri, h->h.tei);
1751 } else if (h->u.m2 == 0) {
1752 /* It's a UA */
1753 if (pri->q921_state[teio] == Q921_AWAITING_ESTABLISH) {
1754 if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP)) {
1755 pri_message(pri, "-- Got UA from %s peer Link up.\n", h->h.c_r ? "cpe" : "network");
1757 return q921_dchannel_up(pri, h->h.tei);
1758 } else {
1759 pri_error(pri, "!! Got a UA, but i'm in state %d\n", pri->q921_state[teio]);
1760 if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE)) {
1761 q921_reset(pri, h->h.tei, 1);
1762 q921_send_teiverify(pri, h->h.tei);
1763 } else {
1764 #ifndef RELAX_TRB
1765 q921_reset(pri, h->h.tei, 1);
1766 #else
1767 /* send DM */
1768 q921_send_dm(pri, 1, h->h.tei);
1769 #endif
1772 } else
1773 pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);
1774 break;
1775 case 4:
1776 pri_error(pri, "!! Frame got rejected!\n");
1777 break;
1778 case 5:
1779 pri_error(pri, "!! XID frames not supported\n");
1780 break;
1781 default:
1782 pri_error(pri, "!! Don't know what to do with M3=%d u-frames\n", h->u.m3);
1784 break;
1787 return NULL;
1790 static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
1792 pri_event *ev;
1793 /* Discard FCS */
1794 len -= 2;
1796 if (!pri->master && pri->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
1797 q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
1799 /* Check some reject conditions -- Start by rejecting improper ea's */
1800 if (h->h.ea1 || !(h->h.ea2))
1801 return NULL;
1803 if ((pri->localtype == PRI_CPE) || (pri->localtype == PRI_NETWORK)) {
1804 /* Check for broadcasts - not yet handled (for PRI) */
1805 if (h->h.tei == Q921_TEI_GROUP) {
1806 return NULL;
1808 } else if ((pri->localtype == BRI_CPE) || (pri->localtype == BRI_CPE_PTMP)) {
1809 if ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP)) {
1810 return NULL;
1812 } else if (pri->localtype == BRI_NETWORK_PTMP) {
1813 /* discard anything from a strange TEI (strange == not assigned by us or the broadcast tei) */
1814 if (((h->h.tei < Q921_TEI_BASE) || (h->h.tei > Q921_TEI_BASE + Q921_MAX_TEIS)) && (h->h.tei != Q921_TEI_GROUP)) {
1815 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1816 pri_message(pri, "Received a Q.921 message from strange/unassigned TEI %d.\n");
1817 return NULL;
1818 } else {
1819 if ((pri->q921_teis[h->h.tei - Q921_TEI_BASE] != 1) && (h->h.tei != Q921_TEI_GROUP)) {
1820 if (pri->debug & PRI_DEBUG_Q921_DUMP)
1821 pri_message(pri, "Received a Q.921 message from unassigned TEI %d.. Sending DM and assigning.\n", h->h.tei);
1822 // send DM
1823 q921_send_dm(pri, 1, h->h.tei);
1824 pri->q921_teis[h->h.tei - Q921_TEI_BASE] = 1;
1825 return NULL;
1830 /* Check for SAPIs we don't yet handle */
1831 if (pri->localtype != BRI_NETWORK_PTMP) {
1832 /* Check for SAPIs we don't yet handle */
1833 if (((h->h.sapi != pri->sapi) && (h->h.sapi != Q921_SAPI_LAYER2_MANAGEMENT)) || ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP) )) {
1834 #ifdef PROCESS_SUBCHANNELS
1835 /* If it's not us, try any subchannels we have */
1836 if (pri->subchannel)
1837 return q921_receive(pri->subchannel, h, len + 2);
1838 else
1839 #endif
1840 return NULL;
1843 ev = __q921_receive_qualified(pri, h, len);
1845 // Q921_GROUP_TEI
1846 if (pri->localtype == BRI_CPE_PTMP) {
1847 reschedule_t203(pri, pri->tei);
1848 } else {
1849 reschedule_t203(pri, h->h.tei);
1851 return ev;
1854 pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
1856 pri_event *e;
1857 e = __q921_receive(pri, h, len);
1858 #ifdef LIBPRI_COUNTERS
1859 pri->q921_rxcount++;
1860 #endif
1861 return e;
1864 static void q921_start_tei(struct pri *pri, int tei)
1866 int teio=tei - Q921_TEI_BASE;
1867 if (pri->localtype != BRI_NETWORK_PTMP) { return; }
1868 if (((teio < 0) || (teio > Q921_MAX_TEIS))) { teio=0; }
1869 pri->q921_teis[teio] = 0;
1870 q921_send_teiremove(pri, tei);
1871 q921_reset(pri,tei,1);
1874 void q921_start(struct pri *pri, int now, int tei)
1876 int i=0;
1877 /* if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {
1878 pri_error(pri, "!! q921_start: Not in 'Link Connection Released' state\n");
1879 return;
1880 } */
1881 /* Reset our interface */
1882 if (pri->localtype != BRI_NETWORK_PTMP) {
1883 q921_reset(pri,0,1);
1885 /* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
1886 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE) || (pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_CPE)) {
1887 pri->sabme_retrans[0] = 0;
1888 q921_send_sabme(pri, now, 0);
1891 if (pri->localtype == BRI_NETWORK_PTMP) {
1892 if (tei == 0) {
1893 // initial start or complete restart
1894 q921_send_teiremove(pri, 127);
1895 pri->dchanup = 0;
1896 for (i=0;i<Q921_MAX_TEIS;i++) {
1897 q921_start_tei(pri,Q921_TEI_BASE+i);
1899 /* clean up those TEIs */
1900 // pri_schedule_event2(pri, 10000, q921_invoke_tei_recovery, pri, 127 );
1901 } else if ((tei >= Q921_TEI_BASE) && (tei < Q921_TEI_BASE + Q921_MAX_TEIS)){
1902 // restart of a single p2p datalink
1903 q921_start_tei(pri,tei);
1906 if (pri->localtype == BRI_CPE_PTMP){
1907 if (tei == 0) {
1908 #ifdef RELAX_TRB
1909 /* let's get a TEI */
1910 q921_send_teireq(pri);
1911 #endif
1912 } else {
1913 /* save the planet by recycling */
1914 pri->sabme_retrans[0] = 0;
1915 q921_send_sabme(pri, now, tei);