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 static struct stateentry datastln1
[] =
704 MT_N1_INVALID
, l3_1tr6_invalid
},
706 MT_N1_SETUP
, l3_1tr6_setup
},
708 MT_N1_SETUP_ACK
, l3_1tr6_setup_ack
},
710 MT_N1_CALL_SENT
, l3_1tr6_call_sent
},
711 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
712 MT_N1_DISC
, l3_1tr6_disc
},
713 {SBIT(2) | SBIT(3) | SBIT(4),
714 MT_N1_ALERT
, l3_1tr6_alert
},
715 {SBIT(2) | SBIT(3) | SBIT(4),
716 MT_N1_CONN
, l3_1tr6_connect
},
718 MT_N1_INFO
, l3_1tr6_info_s2
},
720 MT_N1_CONN_ACK
, l3_1tr6_connect_ack
},
722 MT_N1_INFO
, l3_1tr6_info
},
723 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
724 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
725 MT_N1_REL
, l3_1tr6_rel
},
727 MT_N1_REL
, l3_1tr6_rel_ack
},
728 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
729 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
730 MT_N1_REL_ACK
, l3_1tr6_invalid
},
732 MT_N1_REL_ACK
, l3_1tr6_rel_ack
}
735 static struct stateentry manstatelist
[] =
738 DL_ESTABLISH
| INDICATION
, l3_1tr6_dl_reset
},
740 DL_RELEASE
| INDICATION
, l3_1tr6_dl_release
},
746 up1tr6(struct PStack
*st
, int pr
, void *arg
)
749 struct l3_process
*proc
;
750 struct sk_buff
*skb
= arg
;
754 case (DL_DATA
| INDICATION
):
755 case (DL_UNIT_DATA
| INDICATION
):
757 case (DL_ESTABLISH
| CONFIRM
):
758 case (DL_ESTABLISH
| INDICATION
):
759 case (DL_RELEASE
| INDICATION
):
760 case (DL_RELEASE
| CONFIRM
):
766 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
767 sprintf(tmp
, "up1tr6 len only %d", skb
->len
);
773 if ((skb
->data
[0] & 0xfe) != PROTO_DIS_N0
) {
774 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
775 sprintf(tmp
, "up1tr6%sunexpected discriminator %x message len %d",
776 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
777 skb
->data
[0], skb
->len
);
783 if (skb
->data
[1] != 1) {
784 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
785 sprintf(tmp
, "up1tr6 CR len not 1");
793 if (skb
->data
[0] == PROTO_DIS_N0
) {
795 if (st
->l3
.debug
& L3_DEB_STATE
) {
796 sprintf(tmp
, "up1tr6%s N0 mt %x unhandled",
797 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ", mt
);
800 } else if (skb
->data
[0] == PROTO_DIS_N1
) {
801 if (!(proc
= getl3proc(st
, cr
))) {
802 if (mt
== MT_N1_SETUP
) {
804 if (!(proc
= new_l3_process(st
, cr
))) {
805 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
806 sprintf(tmp
, "up1tr6 no roc mem");
816 } else if ((mt
== MT_N1_REL
) || (mt
== MT_N1_REL_ACK
) ||
817 (mt
== MT_N1_CANC_ACK
) || (mt
== MT_N1_CANC_REJ
) ||
818 (mt
== MT_N1_REG_ACK
) || (mt
== MT_N1_REG_REJ
) ||
819 (mt
== MT_N1_SUSP_ACK
) || (mt
== MT_N1_RES_REJ
) ||
820 (mt
== MT_N1_INFO
)) {
824 if (!(proc
= new_l3_process(st
, cr
))) {
825 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
826 sprintf(tmp
, "up1tr6 no roc mem");
835 for (i
= 0; i
< ARRAY_SIZE(datastln1
); i
++)
836 if ((mt
== datastln1
[i
].primitive
) &&
837 ((1 << proc
->state
) & datastln1
[i
].state
))
839 if (i
== ARRAY_SIZE(datastln1
)) {
841 if (st
->l3
.debug
& L3_DEB_STATE
) {
842 sprintf(tmp
, "up1tr6%sstate %d mt %x unhandled",
843 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
849 if (st
->l3
.debug
& L3_DEB_STATE
) {
850 sprintf(tmp
, "up1tr6%sstate %d mt %x",
851 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
855 datastln1
[i
].rout(proc
, pr
, skb
);
861 down1tr6(struct PStack
*st
, int pr
, void *arg
)
864 struct l3_process
*proc
;
865 struct Channel
*chan
;
868 if ((DL_ESTABLISH
| REQUEST
)== pr
) {
869 l3_msg(st
, pr
, NULL
);
871 } else if ((CC_SETUP
| REQUEST
) == pr
) {
875 if (!(proc
= new_l3_process(st
, cr
))) {
880 memcpy(&proc
->para
.setup
, &chan
->setup
, sizeof(setup_parm
));
887 for (i
= 0; i
< ARRAY_SIZE(downstl
); i
++)
888 if ((pr
== downstl
[i
].primitive
) &&
889 ((1 << proc
->state
) & downstl
[i
].state
))
891 if (i
== ARRAY_SIZE(downstl
)) {
892 if (st
->l3
.debug
& L3_DEB_STATE
) {
893 sprintf(tmp
, "down1tr6 state %d prim %d unhandled",
898 if (st
->l3
.debug
& L3_DEB_STATE
) {
899 sprintf(tmp
, "down1tr6 state %d prim %d",
903 downstl
[i
].rout(proc
, pr
, arg
);
908 man1tr6(struct PStack
*st
, int pr
, void *arg
)
911 struct l3_process
*proc
= arg
;
914 printk(KERN_ERR
"HiSax man1tr6 without proc pr=%04x\n", pr
);
917 for (i
= 0; i
< ARRAY_SIZE(manstatelist
); i
++)
918 if ((pr
== manstatelist
[i
].primitive
) &&
919 ((1 << proc
->state
) & manstatelist
[i
].state
))
921 if (i
== ARRAY_SIZE(manstatelist
)) {
922 if (st
->l3
.debug
& L3_DEB_STATE
) {
923 l3_debug(st
, "cr %d man1tr6 state %d prim %d unhandled",
924 proc
->callref
& 0x7f, proc
->state
, pr
);
927 if (st
->l3
.debug
& L3_DEB_STATE
) {
928 l3_debug(st
, "cr %d man1tr6 state %d prim %d",
929 proc
->callref
& 0x7f, proc
->state
, pr
);
931 manstatelist
[i
].rout(proc
, pr
, arg
);
936 setstack_1tr6(struct PStack
*st
)
940 st
->lli
.l4l3
= down1tr6
;
941 st
->l2
.l2l3
= up1tr6
;
942 st
->l3
.l3ml3
= man1tr6
;
945 strcpy(tmp
, l3_1tr6_revision
);
946 printk(KERN_INFO
"HiSax: 1TR6 Rev. %s\n", HiSax_getrev(tmp
));