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
;
167 /* Channel Identification */
168 p
= findie(skb
->data
, skb
->len
, WE0_chanID
, 0);
171 l3_1tr6_error(pc
, "setup wrong chanID len", skb
);
174 if ((p
[2] & 0xf4) != 0x80) {
175 l3_1tr6_error(pc
, "setup wrong WE0_chanID", skb
);
178 if ((pc
->para
.bchannel
= p
[2] & 0x3))
181 l3_1tr6_error(pc
, "missing setup chanID", skb
);
186 if ((p
= findie(p
, skb
->len
, WE6_serviceInd
, 6))) {
187 pc
->para
.setup
.si1
= p
[2];
188 pc
->para
.setup
.si2
= p
[3];
190 l3_1tr6_error(pc
, "missing setup SI", skb
);
195 if ((p
= findie(p
, skb
->len
, WE0_destAddr
, 0)))
196 iecpy(pc
->para
.setup
.eazmsn
, p
, 1);
198 pc
->para
.setup
.eazmsn
[0] = 0;
201 if ((p
= findie(p
, skb
->len
, WE0_origAddr
, 0))) {
202 iecpy(pc
->para
.setup
.phone
, p
, 1);
204 pc
->para
.setup
.phone
[0] = 0;
208 if ((p
= findie(p
, skb
->len
, WE0_netSpecFac
, 0))) {
209 if ((FAC_SPV
== p
[3]) || (FAC_Activate
== p
[3]))
214 /* Signal all services, linklevel takes care of Service-Indicator */
216 if ((pc
->para
.setup
.si1
!= 7) && (pc
->st
->l3
.debug
& L3_DEB_WARN
)) {
217 sprintf(tmp
, "non-digital call: %s -> %s",
218 pc
->para
.setup
.phone
,
219 pc
->para
.setup
.eazmsn
);
220 l3_debug(pc
->st
, tmp
);
223 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| INDICATION
, pc
);
225 release_l3_process(pc
);
229 l3_1tr6_setup_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
232 struct sk_buff
*skb
= arg
;
234 L3DelTimer(&pc
->timer
);
237 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
239 l3_1tr6_error(pc
, "setup_ack wrong chanID len", skb
);
242 if ((p
[2] & 0xf4) != 0x80) {
243 l3_1tr6_error(pc
, "setup_ack wrong WE0_chanID", skb
);
246 pc
->para
.bchannel
= p
[2] & 0x3;
248 l3_1tr6_error(pc
, "missing setup_ack WE0_chanID", skb
);
252 L3AddTimer(&pc
->timer
, T304
, CC_T304
);
253 pc
->st
->l3
.l3l4(pc
->st
, CC_MORE_INFO
| INDICATION
, pc
);
257 l3_1tr6_call_sent(struct l3_process
*pc
, u_char pr
, void *arg
)
260 struct sk_buff
*skb
= arg
;
262 L3DelTimer(&pc
->timer
);
264 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
266 l3_1tr6_error(pc
, "call sent wrong chanID len", skb
);
269 if ((p
[2] & 0xf4) != 0x80) {
270 l3_1tr6_error(pc
, "call sent wrong WE0_chanID", skb
);
273 if ((pc
->state
== 2) && (pc
->para
.bchannel
!= (p
[2] & 0x3))) {
274 l3_1tr6_error(pc
, "call sent wrong chanID value", skb
);
277 pc
->para
.bchannel
= p
[2] & 0x3;
279 l3_1tr6_error(pc
, "missing call sent WE0_chanID", skb
);
283 L3AddTimer(&pc
->timer
, T310
, CC_T310
);
285 pc
->st
->l3
.l3l4(pc
->st
, CC_PROCEEDING
| INDICATION
, pc
);
289 l3_1tr6_alert(struct l3_process
*pc
, u_char pr
, void *arg
)
291 struct sk_buff
*skb
= arg
;
294 L3DelTimer(&pc
->timer
); /* T304 */
296 pc
->st
->l3
.l3l4(pc
->st
, CC_ALERTING
| INDICATION
, pc
);
300 l3_1tr6_info(struct l3_process
*pc
, u_char pr
, void *arg
)
303 int i
, tmpcharge
= 0;
304 char a_charge
[8], tmp
[32];
305 struct sk_buff
*skb
= arg
;
308 if ((p
= findie(p
, skb
->len
, WE6_chargingInfo
, 6))) {
309 iecpy(a_charge
, p
, 1);
310 for (i
= 0; i
< strlen(a_charge
); i
++) {
312 tmpcharge
+= a_charge
[i
] & 0xf;
314 if (tmpcharge
> pc
->para
.chargeinfo
) {
315 pc
->para
.chargeinfo
= tmpcharge
;
316 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
318 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
319 sprintf(tmp
, "charging info %d", pc
->para
.chargeinfo
);
320 l3_debug(pc
->st
, tmp
);
322 } else if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
)
323 l3_debug(pc
->st
, "charging info not found");
329 l3_1tr6_info_s2(struct l3_process
*pc
, u_char pr
, void *arg
)
331 struct sk_buff
*skb
= arg
;
337 l3_1tr6_connect(struct l3_process
*pc
, u_char pr
, void *arg
)
339 struct sk_buff
*skb
= arg
;
341 L3DelTimer(&pc
->timer
); /* T310 */
342 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
343 l3_1tr6_error(pc
, "missing connect date", skb
);
348 pc
->para
.chargeinfo
= 0;
349 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| CONFIRM
, pc
);
353 l3_1tr6_rel(struct l3_process
*pc
, u_char pr
, void *arg
)
355 struct sk_buff
*skb
= arg
;
359 if ((p
= findie(p
, skb
->len
, WE0_cause
, 0))) {
361 pc
->para
.cause
= p
[2];
371 pc
->para
.cause
= NO_CAUSE
;
372 l3_1tr6_error(pc
, "missing REL cause", skb
);
378 l3_1TR6_message(pc
, MT_N1_REL_ACK
, PROTO_DIS_N1
);
379 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
380 release_l3_process(pc
);
384 l3_1tr6_rel_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
386 struct sk_buff
*skb
= arg
;
391 pc
->para
.cause
= NO_CAUSE
;
392 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| CONFIRM
, pc
);
393 release_l3_process(pc
);
397 l3_1tr6_disc(struct l3_process
*pc
, u_char pr
, void *arg
)
399 struct sk_buff
*skb
= arg
;
401 int i
, tmpcharge
= 0;
402 char a_charge
[8], tmp
[32];
406 if ((p
= findie(p
, skb
->len
, WE6_chargingInfo
, 6))) {
407 iecpy(a_charge
, p
, 1);
408 for (i
= 0; i
< strlen(a_charge
); i
++) {
410 tmpcharge
+= a_charge
[i
] & 0xf;
412 if (tmpcharge
> pc
->para
.chargeinfo
) {
413 pc
->para
.chargeinfo
= tmpcharge
;
414 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
416 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
417 sprintf(tmp
, "charging info %d", pc
->para
.chargeinfo
);
418 l3_debug(pc
->st
, tmp
);
420 } else if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
)
421 l3_debug(pc
->st
, "charging info not found");
425 if ((p
= findie(p
, skb
->len
, WE0_cause
, 0))) {
427 pc
->para
.cause
= p
[2];
437 if (pc
->st
->l3
.debug
& L3_DEB_WARN
)
438 l3_debug(pc
->st
, "cause not found");
439 pc
->para
.cause
= NO_CAUSE
;
441 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
442 l3_1tr6_error(pc
, "missing connack date", skb
);
447 pc
->st
->l3
.l3l4(pc
->st
, CC_DISCONNECT
| INDICATION
, pc
);
452 l3_1tr6_connect_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
454 struct sk_buff
*skb
= arg
;
456 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
457 l3_1tr6_error(pc
, "missing connack date", skb
);
462 pc
->para
.chargeinfo
= 0;
463 L3DelTimer(&pc
->timer
);
464 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_COMPL
| INDICATION
, pc
);
468 l3_1tr6_alert_req(struct l3_process
*pc
, u_char pr
, void *arg
)
471 l3_1TR6_message(pc
, MT_N1_ALERT
, PROTO_DIS_N1
);
475 l3_1tr6_setup_rsp(struct l3_process
*pc
, u_char pr
, void *arg
)
482 MsgHead(p
, pc
->callref
, MT_N1_CONN
, PROTO_DIS_N1
);
483 if (pc
->para
.spv
) { /* SPV ? */
485 *p
++ = WE0_netSpecFac
;
486 *p
++ = 4; /* Laenge */
488 *p
++ = FAC_SPV
; /* SPV */
489 *p
++ = pc
->para
.setup
.si1
;
490 *p
++ = pc
->para
.setup
.si2
;
491 *p
++ = WE0_netSpecFac
;
492 *p
++ = 4; /* Laenge */
494 *p
++ = FAC_Activate
; /* aktiviere SPV */
495 *p
++ = pc
->para
.setup
.si1
;
496 *p
++ = pc
->para
.setup
.si2
;
500 if (!(skb
= l3_alloc_skb(l
)))
502 memcpy(skb_put(skb
, l
), tmp
, l
);
503 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
504 L3DelTimer(&pc
->timer
);
505 L3AddTimer(&pc
->timer
, T313
, CC_T313
);
509 l3_1tr6_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
511 release_l3_process(pc
);
515 l3_1tr6_disconnect_req(struct l3_process
*pc
, u_char pr
, void *arg
)
524 if (pc
->para
.cause
> 0)
525 cause
= pc
->para
.cause
;
526 /* Map DSS1 causes */
527 switch (cause
& 0x7f) {
532 cause
= CAUSE_UserBusy
;
535 cause
= CAUSE_CallRejected
;
539 MsgHead(p
, pc
->callref
, MT_N1_DISC
, PROTO_DIS_N1
);
541 *p
++ = clen
; /* Laenge */
546 if (!(skb
= l3_alloc_skb(l
)))
548 memcpy(skb_put(skb
, l
), tmp
, l
);
549 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
550 L3AddTimer(&pc
->timer
, T305
, CC_T305
);
554 l3_1tr6_t303(struct l3_process
*pc
, u_char pr
, void *arg
)
558 L3DelTimer(&pc
->timer
);
559 l3_1tr6_setup_req(pc
, pr
, arg
);
561 L3DelTimer(&pc
->timer
);
563 l3_1tr6_disconnect_req(pc
, 0, NULL
);
568 l3_1tr6_t304(struct l3_process
*pc
, u_char pr
, void *arg
)
570 L3DelTimer(&pc
->timer
);
571 pc
->para
.cause
= 0xE6;
572 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
573 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
577 l3_1tr6_t305(struct l3_process
*pc
, u_char pr
, void *arg
)
586 L3DelTimer(&pc
->timer
);
587 if (pc
->para
.cause
!= NO_CAUSE
)
588 cause
= pc
->para
.cause
;
589 /* Map DSS1 causes */
590 switch (cause
& 0x7f) {
595 cause
= CAUSE_CallRejected
;
598 MsgHead(p
, pc
->callref
, MT_N1_REL
, PROTO_DIS_N1
);
600 *p
++ = clen
; /* Laenge */
605 if (!(skb
= l3_alloc_skb(l
)))
607 memcpy(skb_put(skb
, l
), tmp
, l
);
608 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
609 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
613 l3_1tr6_t310(struct l3_process
*pc
, u_char pr
, void *arg
)
615 L3DelTimer(&pc
->timer
);
616 pc
->para
.cause
= 0xE6;
617 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
618 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
622 l3_1tr6_t313(struct l3_process
*pc
, u_char pr
, void *arg
)
624 L3DelTimer(&pc
->timer
);
625 pc
->para
.cause
= 0xE6;
626 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
627 pc
->st
->l3
.l3l4(pc
->st
, CC_CONNECT_ERR
, pc
);
631 l3_1tr6_t308_1(struct l3_process
*pc
, u_char pr
, void *arg
)
633 L3DelTimer(&pc
->timer
);
634 l3_1TR6_message(pc
, MT_N1_REL
, PROTO_DIS_N1
);
635 L3AddTimer(&pc
->timer
, T308
, CC_T308_2
);
640 l3_1tr6_t308_2(struct l3_process
*pc
, u_char pr
, void *arg
)
642 L3DelTimer(&pc
->timer
);
643 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE_ERR
, pc
);
644 release_l3_process(pc
);
648 l3_1tr6_dl_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
650 pc
->para
.cause
= CAUSE_LocalProcErr
;
651 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
652 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
656 l3_1tr6_dl_release(struct l3_process
*pc
, u_char pr
, void *arg
)
659 pc
->para
.cause
= 0x1b; /* Destination out of order */
661 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
662 release_l3_process(pc
);
666 static struct stateentry downstl
[] =
669 CC_SETUP
| REQUEST
, l3_1tr6_setup_req
},
670 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
672 CC_DISCONNECT
| REQUEST
, l3_1tr6_disconnect_req
},
674 CC_RELEASE
| REQUEST
, l3_1tr6_release_req
},
676 CC_IGNORE
| REQUEST
, l3_1tr6_reset
},
678 CC_REJECT
| REQUEST
, l3_1tr6_disconnect_req
},
680 CC_ALERTING
| REQUEST
, l3_1tr6_alert_req
},
682 CC_SETUP
| RESPONSE
, l3_1tr6_setup_rsp
},
684 CC_T303
, l3_1tr6_t303
},
686 CC_T304
, l3_1tr6_t304
},
688 CC_T310
, l3_1tr6_t310
},
690 CC_T313
, l3_1tr6_t313
},
692 CC_T305
, l3_1tr6_t305
},
694 CC_T308_1
, l3_1tr6_t308_1
},
696 CC_T308_2
, l3_1tr6_t308_2
},
699 static struct stateentry datastln1
[] =
702 MT_N1_INVALID
, l3_1tr6_invalid
},
704 MT_N1_SETUP
, l3_1tr6_setup
},
706 MT_N1_SETUP_ACK
, l3_1tr6_setup_ack
},
708 MT_N1_CALL_SENT
, l3_1tr6_call_sent
},
709 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
710 MT_N1_DISC
, l3_1tr6_disc
},
711 {SBIT(2) | SBIT(3) | SBIT(4),
712 MT_N1_ALERT
, l3_1tr6_alert
},
713 {SBIT(2) | SBIT(3) | SBIT(4),
714 MT_N1_CONN
, l3_1tr6_connect
},
716 MT_N1_INFO
, l3_1tr6_info_s2
},
718 MT_N1_CONN_ACK
, l3_1tr6_connect_ack
},
720 MT_N1_INFO
, l3_1tr6_info
},
721 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
722 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
723 MT_N1_REL
, l3_1tr6_rel
},
725 MT_N1_REL
, l3_1tr6_rel_ack
},
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_ACK
, l3_1tr6_invalid
},
730 MT_N1_REL_ACK
, l3_1tr6_rel_ack
}
733 static struct stateentry manstatelist
[] =
736 DL_ESTABLISH
| INDICATION
, l3_1tr6_dl_reset
},
738 DL_RELEASE
| INDICATION
, l3_1tr6_dl_release
},
744 up1tr6(struct PStack
*st
, int pr
, void *arg
)
747 struct l3_process
*proc
;
748 struct sk_buff
*skb
= arg
;
752 case (DL_DATA
| INDICATION
):
753 case (DL_UNIT_DATA
| INDICATION
):
755 case (DL_ESTABLISH
| CONFIRM
):
756 case (DL_ESTABLISH
| INDICATION
):
757 case (DL_RELEASE
| INDICATION
):
758 case (DL_RELEASE
| CONFIRM
):
764 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
765 sprintf(tmp
, "up1tr6 len only %d", skb
->len
);
771 if ((skb
->data
[0] & 0xfe) != PROTO_DIS_N0
) {
772 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
773 sprintf(tmp
, "up1tr6%sunexpected discriminator %x message len %d",
774 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
775 skb
->data
[0], skb
->len
);
781 if (skb
->data
[1] != 1) {
782 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
783 sprintf(tmp
, "up1tr6 CR len not 1");
791 if (skb
->data
[0] == PROTO_DIS_N0
) {
793 if (st
->l3
.debug
& L3_DEB_STATE
) {
794 sprintf(tmp
, "up1tr6%s N0 mt %x unhandled",
795 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ", mt
);
798 } else if (skb
->data
[0] == PROTO_DIS_N1
) {
799 if (!(proc
= getl3proc(st
, cr
))) {
800 if (mt
== MT_N1_SETUP
) {
802 if (!(proc
= new_l3_process(st
, cr
))) {
803 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
804 sprintf(tmp
, "up1tr6 no roc mem");
814 } else if ((mt
== MT_N1_REL
) || (mt
== MT_N1_REL_ACK
) ||
815 (mt
== MT_N1_CANC_ACK
) || (mt
== MT_N1_CANC_REJ
) ||
816 (mt
== MT_N1_REG_ACK
) || (mt
== MT_N1_REG_REJ
) ||
817 (mt
== MT_N1_SUSP_ACK
) || (mt
== MT_N1_RES_REJ
) ||
818 (mt
== MT_N1_INFO
)) {
822 if (!(proc
= new_l3_process(st
, cr
))) {
823 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
824 sprintf(tmp
, "up1tr6 no roc mem");
833 for (i
= 0; i
< ARRAY_SIZE(datastln1
); i
++)
834 if ((mt
== datastln1
[i
].primitive
) &&
835 ((1 << proc
->state
) & datastln1
[i
].state
))
837 if (i
== ARRAY_SIZE(datastln1
)) {
839 if (st
->l3
.debug
& L3_DEB_STATE
) {
840 sprintf(tmp
, "up1tr6%sstate %d mt %x unhandled",
841 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
847 if (st
->l3
.debug
& L3_DEB_STATE
) {
848 sprintf(tmp
, "up1tr6%sstate %d mt %x",
849 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
853 datastln1
[i
].rout(proc
, pr
, skb
);
859 down1tr6(struct PStack
*st
, int pr
, void *arg
)
862 struct l3_process
*proc
;
863 struct Channel
*chan
;
866 if ((DL_ESTABLISH
| REQUEST
)== pr
) {
867 l3_msg(st
, pr
, NULL
);
869 } else if ((CC_SETUP
| REQUEST
) == pr
) {
873 if (!(proc
= new_l3_process(st
, cr
))) {
878 memcpy(&proc
->para
.setup
, &chan
->setup
, sizeof(setup_parm
));
885 for (i
= 0; i
< ARRAY_SIZE(downstl
); i
++)
886 if ((pr
== downstl
[i
].primitive
) &&
887 ((1 << proc
->state
) & downstl
[i
].state
))
889 if (i
== ARRAY_SIZE(downstl
)) {
890 if (st
->l3
.debug
& L3_DEB_STATE
) {
891 sprintf(tmp
, "down1tr6 state %d prim %d unhandled",
896 if (st
->l3
.debug
& L3_DEB_STATE
) {
897 sprintf(tmp
, "down1tr6 state %d prim %d",
901 downstl
[i
].rout(proc
, pr
, arg
);
906 man1tr6(struct PStack
*st
, int pr
, void *arg
)
909 struct l3_process
*proc
= arg
;
912 printk(KERN_ERR
"HiSax man1tr6 without proc pr=%04x\n", pr
);
915 for (i
= 0; i
< ARRAY_SIZE(manstatelist
); i
++)
916 if ((pr
== manstatelist
[i
].primitive
) &&
917 ((1 << proc
->state
) & manstatelist
[i
].state
))
919 if (i
== ARRAY_SIZE(manstatelist
)) {
920 if (st
->l3
.debug
& L3_DEB_STATE
) {
921 l3_debug(st
, "cr %d man1tr6 state %d prim %d unhandled",
922 proc
->callref
& 0x7f, proc
->state
, pr
);
925 if (st
->l3
.debug
& L3_DEB_STATE
) {
926 l3_debug(st
, "cr %d man1tr6 state %d prim %d",
927 proc
->callref
& 0x7f, proc
->state
, pr
);
929 manstatelist
[i
].rout(proc
, pr
, arg
);
934 setstack_1tr6(struct PStack
*st
)
938 st
->lli
.l4l3
= down1tr6
;
939 st
->l2
.l2l3
= up1tr6
;
940 st
->l3
.l3ml3
= man1tr6
;
943 strcpy(tmp
, l3_1tr6_revision
);
944 printk(KERN_INFO
"HiSax: 1TR6 Rev. %s\n", HiSax_getrev(tmp
));