1 /* $Id: l3_1tr6.c,v 2.15.2.3 2004/01/13 14:31:25 keil Exp $
3 * German 1TR6 D-channel protocol
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * For changes and modifications please read
12 * Documentation/isdn/HiSax.cert
19 #include <linux/ctype.h>
21 extern char *HiSax_getrev(const char *revision
);
22 static const char *l3_1tr6_revision
= "$Revision: 2.15.2.3 $";
24 #define MsgHead(ptr, cref, mty, dis) \
27 *ptr++ = cref ^ 0x80; \
31 l3_1TR6_message(struct l3_process
*pc
, u_char mt
, u_char pd
)
36 if (!(skb
= l3_alloc_skb(4)))
39 MsgHead(p
, pc
->callref
, mt
, pd
);
40 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
44 l3_1tr6_release_req(struct l3_process
*pc
, u_char pr
, void *arg
)
48 l3_1TR6_message(pc
, MT_N1_REL
, PROTO_DIS_N1
);
49 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
53 l3_1tr6_invalid(struct l3_process
*pc
, u_char pr
, void *arg
)
55 struct sk_buff
*skb
= arg
;
58 l3_1tr6_release_req(pc
, 0, NULL
);
62 l3_1tr6_error(struct l3_process
*pc
, u_char
*msg
, struct sk_buff
*skb
)
65 if (pc
->st
->l3
.debug
& L3_DEB_WARN
)
66 l3_debug(pc
->st
, msg
);
67 l3_1tr6_release_req(pc
, 0, NULL
);
71 l3_1tr6_setup_req(struct l3_process
*pc
, u_char pr
, void *arg
)
81 MsgHead(p
, pc
->callref
, MT_N1_SETUP
, PROTO_DIS_N1
);
82 teln
= pc
->para
.setup
.phone
;
84 if (!isdigit(*teln
)) {
85 switch (0x5f & *teln
) {
100 if (pc
->st
->l3
.debug
& L3_DEB_WARN
)
101 l3_debug(pc
->st
, "Wrong MSN Code");
107 *p
++ = 0x18; /* channel indicator */
111 if (pc
->para
.spv
) { /* SPV ? */
113 *p
++ = WE0_netSpecFac
;
114 *p
++ = 4; /* Laenge */
116 *p
++ = FAC_SPV
; /* SPV */
117 *p
++ = pc
->para
.setup
.si1
; /* 0 for all Services */
118 *p
++ = pc
->para
.setup
.si2
; /* 0 for all Services */
119 *p
++ = WE0_netSpecFac
;
120 *p
++ = 4; /* Laenge */
122 *p
++ = FAC_Activate
; /* aktiviere SPV (default) */
123 *p
++ = pc
->para
.setup
.si1
; /* 0 for all Services */
124 *p
++ = pc
->para
.setup
.si2
; /* 0 for all Services */
126 eaz
= pc
->para
.setup
.eazmsn
;
129 *p
++ = strlen(eaz
) + 1;
130 /* Classify as AnyPref. */
131 *p
++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
133 *p
++ = *eaz
++ & 0x7f;
136 *p
++ = strlen(teln
) + 1;
137 /* Classify as AnyPref. */
138 *p
++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
140 *p
++ = *teln
++ & 0x7f;
143 /* Codesatz 6 fuer Service */
144 *p
++ = WE6_serviceInd
;
145 *p
++ = 2; /* len=2 info,info2 */
146 *p
++ = pc
->para
.setup
.si1
;
147 *p
++ = pc
->para
.setup
.si2
;
150 if (!(skb
= l3_alloc_skb(l
)))
152 memcpy(skb_put(skb
, l
), tmp
, l
);
153 L3DelTimer(&pc
->timer
);
154 L3AddTimer(&pc
->timer
, T303
, CC_T303
);
156 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
160 l3_1tr6_setup(struct l3_process
*pc
, u_char pr
, void *arg
)
165 struct sk_buff
*skb
= arg
;
169 /* Channel Identification */
171 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
173 l3_1tr6_error(pc
, "setup wrong chanID len", skb
);
176 if ((p
[2] & 0xf4) != 0x80) {
177 l3_1tr6_error(pc
, "setup wrong WE0_chanID", skb
);
180 if ((pc
->para
.bchannel
= p
[2] & 0x3))
183 l3_1tr6_error(pc
, "missing setup chanID", skb
);
188 if ((p
= findie(p
, skb
->len
, WE6_serviceInd
, 6))) {
189 pc
->para
.setup
.si1
= p
[2];
190 pc
->para
.setup
.si2
= p
[3];
192 l3_1tr6_error(pc
, "missing setup SI", skb
);
197 if ((p
= findie(p
, skb
->len
, WE0_destAddr
, 0)))
198 iecpy(pc
->para
.setup
.eazmsn
, p
, 1);
200 pc
->para
.setup
.eazmsn
[0] = 0;
203 if ((p
= findie(p
, skb
->len
, WE0_origAddr
, 0))) {
204 iecpy(pc
->para
.setup
.phone
, p
, 1);
206 pc
->para
.setup
.phone
[0] = 0;
210 if ((p
= findie(p
, skb
->len
, WE0_netSpecFac
, 0))) {
211 if ((FAC_SPV
== p
[3]) || (FAC_Activate
== p
[3]))
216 /* Signal all services, linklevel takes care of Service-Indicator */
218 if ((pc
->para
.setup
.si1
!= 7) && (pc
->st
->l3
.debug
& L3_DEB_WARN
)) {
219 sprintf(tmp
, "non-digital call: %s -> %s",
220 pc
->para
.setup
.phone
,
221 pc
->para
.setup
.eazmsn
);
222 l3_debug(pc
->st
, tmp
);
225 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| INDICATION
, pc
);
227 release_l3_process(pc
);
231 l3_1tr6_setup_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
234 struct sk_buff
*skb
= arg
;
236 L3DelTimer(&pc
->timer
);
239 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
241 l3_1tr6_error(pc
, "setup_ack wrong chanID len", skb
);
244 if ((p
[2] & 0xf4) != 0x80) {
245 l3_1tr6_error(pc
, "setup_ack wrong WE0_chanID", skb
);
248 pc
->para
.bchannel
= p
[2] & 0x3;
250 l3_1tr6_error(pc
, "missing setup_ack WE0_chanID", skb
);
254 L3AddTimer(&pc
->timer
, T304
, CC_T304
);
255 pc
->st
->l3
.l3l4(pc
->st
, CC_MORE_INFO
| INDICATION
, pc
);
259 l3_1tr6_call_sent(struct l3_process
*pc
, u_char pr
, void *arg
)
262 struct sk_buff
*skb
= arg
;
264 L3DelTimer(&pc
->timer
);
266 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
268 l3_1tr6_error(pc
, "call sent wrong chanID len", skb
);
271 if ((p
[2] & 0xf4) != 0x80) {
272 l3_1tr6_error(pc
, "call sent wrong WE0_chanID", skb
);
275 if ((pc
->state
== 2) && (pc
->para
.bchannel
!= (p
[2] & 0x3))) {
276 l3_1tr6_error(pc
, "call sent wrong chanID value", skb
);
279 pc
->para
.bchannel
= p
[2] & 0x3;
281 l3_1tr6_error(pc
, "missing call sent WE0_chanID", skb
);
285 L3AddTimer(&pc
->timer
, T310
, CC_T310
);
287 pc
->st
->l3
.l3l4(pc
->st
, CC_PROCEEDING
| INDICATION
, pc
);
291 l3_1tr6_alert(struct l3_process
*pc
, u_char pr
, void *arg
)
293 struct sk_buff
*skb
= arg
;
296 L3DelTimer(&pc
->timer
); /* T304 */
298 pc
->st
->l3
.l3l4(pc
->st
, CC_ALERTING
| INDICATION
, pc
);
302 l3_1tr6_info(struct l3_process
*pc
, u_char pr
, void *arg
)
305 int i
, tmpcharge
= 0;
306 char a_charge
[8], tmp
[32];
307 struct sk_buff
*skb
= arg
;
310 if ((p
= findie(p
, skb
->len
, WE6_chargingInfo
, 6))) {
311 iecpy(a_charge
, p
, 1);
312 for (i
= 0; i
< strlen(a_charge
); i
++) {
314 tmpcharge
+= a_charge
[i
] & 0xf;
316 if (tmpcharge
> pc
->para
.chargeinfo
) {
317 pc
->para
.chargeinfo
= tmpcharge
;
318 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
320 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
321 sprintf(tmp
, "charging info %d", pc
->para
.chargeinfo
);
322 l3_debug(pc
->st
, tmp
);
324 } else if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
)
325 l3_debug(pc
->st
, "charging info not found");
331 l3_1tr6_info_s2(struct l3_process
*pc
, u_char pr
, void *arg
)
333 struct sk_buff
*skb
= arg
;
339 l3_1tr6_connect(struct l3_process
*pc
, u_char pr
, void *arg
)
341 struct sk_buff
*skb
= arg
;
343 L3DelTimer(&pc
->timer
); /* T310 */
344 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
345 l3_1tr6_error(pc
, "missing connect date", skb
);
350 pc
->para
.chargeinfo
= 0;
351 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| CONFIRM
, pc
);
355 l3_1tr6_rel(struct l3_process
*pc
, u_char pr
, void *arg
)
357 struct sk_buff
*skb
= arg
;
361 if ((p
= findie(p
, skb
->len
, WE0_cause
, 0))) {
363 pc
->para
.cause
= p
[2];
373 pc
->para
.cause
= NO_CAUSE
;
374 l3_1tr6_error(pc
, "missing REL cause", skb
);
380 l3_1TR6_message(pc
, MT_N1_REL_ACK
, PROTO_DIS_N1
);
381 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
382 release_l3_process(pc
);
386 l3_1tr6_rel_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
388 struct sk_buff
*skb
= arg
;
393 pc
->para
.cause
= NO_CAUSE
;
394 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| CONFIRM
, pc
);
395 release_l3_process(pc
);
399 l3_1tr6_disc(struct l3_process
*pc
, u_char pr
, void *arg
)
401 struct sk_buff
*skb
= arg
;
403 int i
, tmpcharge
= 0;
404 char a_charge
[8], tmp
[32];
408 if ((p
= findie(p
, skb
->len
, WE6_chargingInfo
, 6))) {
409 iecpy(a_charge
, p
, 1);
410 for (i
= 0; i
< strlen(a_charge
); i
++) {
412 tmpcharge
+= a_charge
[i
] & 0xf;
414 if (tmpcharge
> pc
->para
.chargeinfo
) {
415 pc
->para
.chargeinfo
= tmpcharge
;
416 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
418 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
419 sprintf(tmp
, "charging info %d", pc
->para
.chargeinfo
);
420 l3_debug(pc
->st
, tmp
);
422 } else if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
)
423 l3_debug(pc
->st
, "charging info not found");
427 if ((p
= findie(p
, skb
->len
, WE0_cause
, 0))) {
429 pc
->para
.cause
= p
[2];
439 if (pc
->st
->l3
.debug
& L3_DEB_WARN
)
440 l3_debug(pc
->st
, "cause not found");
441 pc
->para
.cause
= NO_CAUSE
;
443 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
444 l3_1tr6_error(pc
, "missing connack date", skb
);
449 pc
->st
->l3
.l3l4(pc
->st
, CC_DISCONNECT
| INDICATION
, pc
);
454 l3_1tr6_connect_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
456 struct sk_buff
*skb
= arg
;
458 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
459 l3_1tr6_error(pc
, "missing connack date", skb
);
464 pc
->para
.chargeinfo
= 0;
465 L3DelTimer(&pc
->timer
);
466 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_COMPL
| INDICATION
, pc
);
470 l3_1tr6_alert_req(struct l3_process
*pc
, u_char pr
, void *arg
)
473 l3_1TR6_message(pc
, MT_N1_ALERT
, PROTO_DIS_N1
);
477 l3_1tr6_setup_rsp(struct l3_process
*pc
, u_char pr
, void *arg
)
484 MsgHead(p
, pc
->callref
, MT_N1_CONN
, PROTO_DIS_N1
);
485 if (pc
->para
.spv
) { /* SPV ? */
487 *p
++ = WE0_netSpecFac
;
488 *p
++ = 4; /* Laenge */
490 *p
++ = FAC_SPV
; /* SPV */
491 *p
++ = pc
->para
.setup
.si1
;
492 *p
++ = pc
->para
.setup
.si2
;
493 *p
++ = WE0_netSpecFac
;
494 *p
++ = 4; /* Laenge */
496 *p
++ = FAC_Activate
; /* aktiviere SPV */
497 *p
++ = pc
->para
.setup
.si1
;
498 *p
++ = pc
->para
.setup
.si2
;
502 if (!(skb
= l3_alloc_skb(l
)))
504 memcpy(skb_put(skb
, l
), tmp
, l
);
505 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
506 L3DelTimer(&pc
->timer
);
507 L3AddTimer(&pc
->timer
, T313
, CC_T313
);
511 l3_1tr6_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
513 release_l3_process(pc
);
517 l3_1tr6_disconnect_req(struct l3_process
*pc
, u_char pr
, void *arg
)
526 if (pc
->para
.cause
> 0)
527 cause
= pc
->para
.cause
;
528 /* Map DSS1 causes */
529 switch (cause
& 0x7f) {
534 cause
= CAUSE_UserBusy
;
537 cause
= CAUSE_CallRejected
;
541 MsgHead(p
, pc
->callref
, MT_N1_DISC
, PROTO_DIS_N1
);
543 *p
++ = clen
; /* Laenge */
548 if (!(skb
= l3_alloc_skb(l
)))
550 memcpy(skb_put(skb
, l
), tmp
, l
);
551 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
552 L3AddTimer(&pc
->timer
, T305
, CC_T305
);
556 l3_1tr6_t303(struct l3_process
*pc
, u_char pr
, void *arg
)
560 L3DelTimer(&pc
->timer
);
561 l3_1tr6_setup_req(pc
, pr
, arg
);
563 L3DelTimer(&pc
->timer
);
565 l3_1tr6_disconnect_req(pc
, 0, NULL
);
570 l3_1tr6_t304(struct l3_process
*pc
, u_char pr
, void *arg
)
572 L3DelTimer(&pc
->timer
);
573 pc
->para
.cause
= 0xE6;
574 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
575 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
579 l3_1tr6_t305(struct l3_process
*pc
, u_char pr
, void *arg
)
588 L3DelTimer(&pc
->timer
);
589 if (pc
->para
.cause
!= NO_CAUSE
)
590 cause
= pc
->para
.cause
;
591 /* Map DSS1 causes */
592 switch (cause
& 0x7f) {
597 cause
= CAUSE_CallRejected
;
600 MsgHead(p
, pc
->callref
, MT_N1_REL
, PROTO_DIS_N1
);
602 *p
++ = clen
; /* Laenge */
607 if (!(skb
= l3_alloc_skb(l
)))
609 memcpy(skb_put(skb
, l
), tmp
, l
);
610 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
611 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
615 l3_1tr6_t310(struct l3_process
*pc
, u_char pr
, void *arg
)
617 L3DelTimer(&pc
->timer
);
618 pc
->para
.cause
= 0xE6;
619 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
620 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
624 l3_1tr6_t313(struct l3_process
*pc
, u_char pr
, void *arg
)
626 L3DelTimer(&pc
->timer
);
627 pc
->para
.cause
= 0xE6;
628 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
629 pc
->st
->l3
.l3l4(pc
->st
, CC_CONNECT_ERR
, pc
);
633 l3_1tr6_t308_1(struct l3_process
*pc
, u_char pr
, void *arg
)
635 L3DelTimer(&pc
->timer
);
636 l3_1TR6_message(pc
, MT_N1_REL
, PROTO_DIS_N1
);
637 L3AddTimer(&pc
->timer
, T308
, CC_T308_2
);
642 l3_1tr6_t308_2(struct l3_process
*pc
, u_char pr
, void *arg
)
644 L3DelTimer(&pc
->timer
);
645 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE_ERR
, pc
);
646 release_l3_process(pc
);
650 l3_1tr6_dl_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
652 pc
->para
.cause
= CAUSE_LocalProcErr
;
653 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
654 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
658 l3_1tr6_dl_release(struct l3_process
*pc
, u_char pr
, void *arg
)
661 pc
->para
.cause
= 0x1b; /* Destination out of order */
663 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
664 release_l3_process(pc
);
668 static struct stateentry downstl
[] =
671 CC_SETUP
| REQUEST
, l3_1tr6_setup_req
},
672 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
674 CC_DISCONNECT
| REQUEST
, l3_1tr6_disconnect_req
},
676 CC_RELEASE
| REQUEST
, l3_1tr6_release_req
},
678 CC_IGNORE
| REQUEST
, l3_1tr6_reset
},
680 CC_REJECT
| REQUEST
, l3_1tr6_disconnect_req
},
682 CC_ALERTING
| REQUEST
, l3_1tr6_alert_req
},
684 CC_SETUP
| RESPONSE
, l3_1tr6_setup_rsp
},
686 CC_T303
, l3_1tr6_t303
},
688 CC_T304
, l3_1tr6_t304
},
690 CC_T310
, l3_1tr6_t310
},
692 CC_T313
, l3_1tr6_t313
},
694 CC_T305
, l3_1tr6_t305
},
696 CC_T308_1
, l3_1tr6_t308_1
},
698 CC_T308_2
, l3_1tr6_t308_2
},
701 #define DOWNSTL_LEN \
702 (sizeof(downstl) / sizeof(struct stateentry))
704 static struct stateentry datastln1
[] =
707 MT_N1_INVALID
, l3_1tr6_invalid
},
709 MT_N1_SETUP
, l3_1tr6_setup
},
711 MT_N1_SETUP_ACK
, l3_1tr6_setup_ack
},
713 MT_N1_CALL_SENT
, l3_1tr6_call_sent
},
714 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
715 MT_N1_DISC
, l3_1tr6_disc
},
716 {SBIT(2) | SBIT(3) | SBIT(4),
717 MT_N1_ALERT
, l3_1tr6_alert
},
718 {SBIT(2) | SBIT(3) | SBIT(4),
719 MT_N1_CONN
, l3_1tr6_connect
},
721 MT_N1_INFO
, l3_1tr6_info_s2
},
723 MT_N1_CONN_ACK
, l3_1tr6_connect_ack
},
725 MT_N1_INFO
, l3_1tr6_info
},
726 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
727 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
728 MT_N1_REL
, l3_1tr6_rel
},
730 MT_N1_REL
, l3_1tr6_rel_ack
},
731 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
732 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
733 MT_N1_REL_ACK
, l3_1tr6_invalid
},
735 MT_N1_REL_ACK
, l3_1tr6_rel_ack
}
738 #define DATASTLN1_LEN \
739 (sizeof(datastln1) / sizeof(struct stateentry))
741 static struct stateentry manstatelist
[] =
744 DL_ESTABLISH
| INDICATION
, l3_1tr6_dl_reset
},
746 DL_RELEASE
| INDICATION
, l3_1tr6_dl_release
},
750 (sizeof(manstatelist) / sizeof(struct stateentry))
754 up1tr6(struct PStack
*st
, int pr
, void *arg
)
757 struct l3_process
*proc
;
758 struct sk_buff
*skb
= arg
;
762 case (DL_DATA
| INDICATION
):
763 case (DL_UNIT_DATA
| INDICATION
):
765 case (DL_ESTABLISH
| CONFIRM
):
766 case (DL_ESTABLISH
| INDICATION
):
767 case (DL_RELEASE
| INDICATION
):
768 case (DL_RELEASE
| CONFIRM
):
774 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
775 sprintf(tmp
, "up1tr6 len only %d", skb
->len
);
781 if ((skb
->data
[0] & 0xfe) != PROTO_DIS_N0
) {
782 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
783 sprintf(tmp
, "up1tr6%sunexpected discriminator %x message len %d",
784 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
785 skb
->data
[0], skb
->len
);
791 if (skb
->data
[1] != 1) {
792 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
793 sprintf(tmp
, "up1tr6 CR len not 1");
801 if (skb
->data
[0] == PROTO_DIS_N0
) {
803 if (st
->l3
.debug
& L3_DEB_STATE
) {
804 sprintf(tmp
, "up1tr6%s N0 mt %x unhandled",
805 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ", mt
);
808 } else if (skb
->data
[0] == PROTO_DIS_N1
) {
809 if (!(proc
= getl3proc(st
, cr
))) {
810 if (mt
== MT_N1_SETUP
) {
812 if (!(proc
= new_l3_process(st
, cr
))) {
813 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
814 sprintf(tmp
, "up1tr6 no roc mem");
824 } else if ((mt
== MT_N1_REL
) || (mt
== MT_N1_REL_ACK
) ||
825 (mt
== MT_N1_CANC_ACK
) || (mt
== MT_N1_CANC_REJ
) ||
826 (mt
== MT_N1_REG_ACK
) || (mt
== MT_N1_REG_REJ
) ||
827 (mt
== MT_N1_SUSP_ACK
) || (mt
== MT_N1_RES_REJ
) ||
828 (mt
== MT_N1_INFO
)) {
832 if (!(proc
= new_l3_process(st
, cr
))) {
833 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
834 sprintf(tmp
, "up1tr6 no roc mem");
843 for (i
= 0; i
< DATASTLN1_LEN
; i
++)
844 if ((mt
== datastln1
[i
].primitive
) &&
845 ((1 << proc
->state
) & datastln1
[i
].state
))
847 if (i
== DATASTLN1_LEN
) {
849 if (st
->l3
.debug
& L3_DEB_STATE
) {
850 sprintf(tmp
, "up1tr6%sstate %d mt %x unhandled",
851 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
857 if (st
->l3
.debug
& L3_DEB_STATE
) {
858 sprintf(tmp
, "up1tr6%sstate %d mt %x",
859 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
863 datastln1
[i
].rout(proc
, pr
, skb
);
869 down1tr6(struct PStack
*st
, int pr
, void *arg
)
872 struct l3_process
*proc
;
873 struct Channel
*chan
;
876 if ((DL_ESTABLISH
| REQUEST
)== pr
) {
877 l3_msg(st
, pr
, NULL
);
879 } else if ((CC_SETUP
| REQUEST
) == pr
) {
883 if (!(proc
= new_l3_process(st
, cr
))) {
888 memcpy(&proc
->para
.setup
, &chan
->setup
, sizeof(setup_parm
));
895 for (i
= 0; i
< DOWNSTL_LEN
; i
++)
896 if ((pr
== downstl
[i
].primitive
) &&
897 ((1 << proc
->state
) & downstl
[i
].state
))
899 if (i
== DOWNSTL_LEN
) {
900 if (st
->l3
.debug
& L3_DEB_STATE
) {
901 sprintf(tmp
, "down1tr6 state %d prim %d unhandled",
906 if (st
->l3
.debug
& L3_DEB_STATE
) {
907 sprintf(tmp
, "down1tr6 state %d prim %d",
911 downstl
[i
].rout(proc
, pr
, arg
);
916 man1tr6(struct PStack
*st
, int pr
, void *arg
)
919 struct l3_process
*proc
= arg
;
922 printk(KERN_ERR
"HiSax man1tr6 without proc pr=%04x\n", pr
);
925 for (i
= 0; i
< MANSLLEN
; i
++)
926 if ((pr
== manstatelist
[i
].primitive
) &&
927 ((1 << proc
->state
) & manstatelist
[i
].state
))
930 if (st
->l3
.debug
& L3_DEB_STATE
) {
931 l3_debug(st
, "cr %d man1tr6 state %d prim %d unhandled",
932 proc
->callref
& 0x7f, proc
->state
, pr
);
935 if (st
->l3
.debug
& L3_DEB_STATE
) {
936 l3_debug(st
, "cr %d man1tr6 state %d prim %d",
937 proc
->callref
& 0x7f, proc
->state
, pr
);
939 manstatelist
[i
].rout(proc
, pr
, arg
);
944 setstack_1tr6(struct PStack
*st
)
948 st
->lli
.l4l3
= down1tr6
;
949 st
->l2
.l2l3
= up1tr6
;
950 st
->l3
.l3ml3
= man1tr6
;
953 strcpy(tmp
, l3_1tr6_revision
);
954 printk(KERN_INFO
"HiSax: 1TR6 Rev. %s\n", HiSax_getrev(tmp
));