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
, "%s", 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 skb_put_data(skb
, 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
)
164 struct sk_buff
*skb
= arg
;
166 /* Channel Identification */
167 p
= findie(skb
->data
, skb
->len
, WE0_chanID
, 0);
170 l3_1tr6_error(pc
, "setup wrong chanID len", skb
);
173 if ((p
[2] & 0xf4) != 0x80) {
174 l3_1tr6_error(pc
, "setup wrong WE0_chanID", skb
);
177 if ((pc
->para
.bchannel
= p
[2] & 0x3))
180 l3_1tr6_error(pc
, "missing setup chanID", skb
);
185 if ((p
= findie(p
, skb
->len
, WE6_serviceInd
, 6))) {
186 pc
->para
.setup
.si1
= p
[2];
187 pc
->para
.setup
.si2
= p
[3];
189 l3_1tr6_error(pc
, "missing setup SI", skb
);
194 if ((p
= findie(p
, skb
->len
, WE0_destAddr
, 0)))
195 iecpy(pc
->para
.setup
.eazmsn
, p
, 1);
197 pc
->para
.setup
.eazmsn
[0] = 0;
200 if ((p
= findie(p
, skb
->len
, WE0_origAddr
, 0))) {
201 iecpy(pc
->para
.setup
.phone
, p
, 1);
203 pc
->para
.setup
.phone
[0] = 0;
207 if ((p
= findie(p
, skb
->len
, WE0_netSpecFac
, 0))) {
208 if ((FAC_SPV
== p
[3]) || (FAC_Activate
== p
[3]))
213 /* Signal all services, linklevel takes care of Service-Indicator */
215 if ((pc
->para
.setup
.si1
!= 7) && (pc
->st
->l3
.debug
& L3_DEB_WARN
)) {
216 l3_debug(pc
->st
, "non-digital call: %s -> %s",
217 pc
->para
.setup
.phone
,
218 pc
->para
.setup
.eazmsn
);
221 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| INDICATION
, pc
);
223 release_l3_process(pc
);
227 l3_1tr6_setup_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
230 struct sk_buff
*skb
= arg
;
232 L3DelTimer(&pc
->timer
);
235 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
237 l3_1tr6_error(pc
, "setup_ack wrong chanID len", skb
);
240 if ((p
[2] & 0xf4) != 0x80) {
241 l3_1tr6_error(pc
, "setup_ack wrong WE0_chanID", skb
);
244 pc
->para
.bchannel
= p
[2] & 0x3;
246 l3_1tr6_error(pc
, "missing setup_ack WE0_chanID", skb
);
250 L3AddTimer(&pc
->timer
, T304
, CC_T304
);
251 pc
->st
->l3
.l3l4(pc
->st
, CC_MORE_INFO
| INDICATION
, pc
);
255 l3_1tr6_call_sent(struct l3_process
*pc
, u_char pr
, void *arg
)
258 struct sk_buff
*skb
= arg
;
260 L3DelTimer(&pc
->timer
);
262 if ((p
= findie(p
, skb
->len
, WE0_chanID
, 0))) {
264 l3_1tr6_error(pc
, "call sent wrong chanID len", skb
);
267 if ((p
[2] & 0xf4) != 0x80) {
268 l3_1tr6_error(pc
, "call sent wrong WE0_chanID", skb
);
271 if ((pc
->state
== 2) && (pc
->para
.bchannel
!= (p
[2] & 0x3))) {
272 l3_1tr6_error(pc
, "call sent wrong chanID value", skb
);
275 pc
->para
.bchannel
= p
[2] & 0x3;
277 l3_1tr6_error(pc
, "missing call sent WE0_chanID", skb
);
281 L3AddTimer(&pc
->timer
, T310
, CC_T310
);
283 pc
->st
->l3
.l3l4(pc
->st
, CC_PROCEEDING
| INDICATION
, pc
);
287 l3_1tr6_alert(struct l3_process
*pc
, u_char pr
, void *arg
)
289 struct sk_buff
*skb
= arg
;
292 L3DelTimer(&pc
->timer
); /* T304 */
294 pc
->st
->l3
.l3l4(pc
->st
, CC_ALERTING
| INDICATION
, pc
);
298 l3_1tr6_info(struct l3_process
*pc
, u_char pr
, void *arg
)
301 int i
, tmpcharge
= 0;
303 struct sk_buff
*skb
= arg
;
306 if ((p
= findie(p
, skb
->len
, WE6_chargingInfo
, 6))) {
307 iecpy(a_charge
, p
, 1);
308 for (i
= 0; i
< strlen(a_charge
); i
++) {
310 tmpcharge
+= a_charge
[i
] & 0xf;
312 if (tmpcharge
> pc
->para
.chargeinfo
) {
313 pc
->para
.chargeinfo
= tmpcharge
;
314 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
316 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
317 l3_debug(pc
->st
, "charging info %d",
318 pc
->para
.chargeinfo
);
320 } else if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
)
321 l3_debug(pc
->st
, "charging info not found");
327 l3_1tr6_info_s2(struct l3_process
*pc
, u_char pr
, void *arg
)
329 struct sk_buff
*skb
= arg
;
335 l3_1tr6_connect(struct l3_process
*pc
, u_char pr
, void *arg
)
337 struct sk_buff
*skb
= arg
;
339 L3DelTimer(&pc
->timer
); /* T310 */
340 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
341 l3_1tr6_error(pc
, "missing connect date", skb
);
346 pc
->para
.chargeinfo
= 0;
347 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| CONFIRM
, pc
);
351 l3_1tr6_rel(struct l3_process
*pc
, u_char pr
, void *arg
)
353 struct sk_buff
*skb
= arg
;
357 if ((p
= findie(p
, skb
->len
, WE0_cause
, 0))) {
359 pc
->para
.cause
= p
[2];
369 pc
->para
.cause
= NO_CAUSE
;
370 l3_1tr6_error(pc
, "missing REL cause", skb
);
376 l3_1TR6_message(pc
, MT_N1_REL_ACK
, PROTO_DIS_N1
);
377 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
378 release_l3_process(pc
);
382 l3_1tr6_rel_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
384 struct sk_buff
*skb
= arg
;
389 pc
->para
.cause
= NO_CAUSE
;
390 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| CONFIRM
, pc
);
391 release_l3_process(pc
);
395 l3_1tr6_disc(struct l3_process
*pc
, u_char pr
, void *arg
)
397 struct sk_buff
*skb
= arg
;
399 int i
, tmpcharge
= 0;
404 if ((p
= findie(p
, skb
->len
, WE6_chargingInfo
, 6))) {
405 iecpy(a_charge
, p
, 1);
406 for (i
= 0; i
< strlen(a_charge
); i
++) {
408 tmpcharge
+= a_charge
[i
] & 0xf;
410 if (tmpcharge
> pc
->para
.chargeinfo
) {
411 pc
->para
.chargeinfo
= tmpcharge
;
412 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
414 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
415 l3_debug(pc
->st
, "charging info %d",
416 pc
->para
.chargeinfo
);
418 } else if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
)
419 l3_debug(pc
->st
, "charging info not found");
423 if ((p
= findie(p
, skb
->len
, WE0_cause
, 0))) {
425 pc
->para
.cause
= p
[2];
435 if (pc
->st
->l3
.debug
& L3_DEB_WARN
)
436 l3_debug(pc
->st
, "cause not found");
437 pc
->para
.cause
= NO_CAUSE
;
439 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
440 l3_1tr6_error(pc
, "missing connack date", skb
);
445 pc
->st
->l3
.l3l4(pc
->st
, CC_DISCONNECT
| INDICATION
, pc
);
450 l3_1tr6_connect_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
452 struct sk_buff
*skb
= arg
;
454 if (!findie(skb
->data
, skb
->len
, WE6_date
, 6)) {
455 l3_1tr6_error(pc
, "missing connack date", skb
);
460 pc
->para
.chargeinfo
= 0;
461 L3DelTimer(&pc
->timer
);
462 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_COMPL
| INDICATION
, pc
);
466 l3_1tr6_alert_req(struct l3_process
*pc
, u_char pr
, void *arg
)
469 l3_1TR6_message(pc
, MT_N1_ALERT
, PROTO_DIS_N1
);
473 l3_1tr6_setup_rsp(struct l3_process
*pc
, u_char pr
, void *arg
)
480 MsgHead(p
, pc
->callref
, MT_N1_CONN
, PROTO_DIS_N1
);
481 if (pc
->para
.spv
) { /* SPV ? */
483 *p
++ = WE0_netSpecFac
;
484 *p
++ = 4; /* Laenge */
486 *p
++ = FAC_SPV
; /* SPV */
487 *p
++ = pc
->para
.setup
.si1
;
488 *p
++ = pc
->para
.setup
.si2
;
489 *p
++ = WE0_netSpecFac
;
490 *p
++ = 4; /* Laenge */
492 *p
++ = FAC_Activate
; /* aktiviere SPV */
493 *p
++ = pc
->para
.setup
.si1
;
494 *p
++ = pc
->para
.setup
.si2
;
498 if (!(skb
= l3_alloc_skb(l
)))
500 skb_put_data(skb
, tmp
, l
);
501 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
502 L3DelTimer(&pc
->timer
);
503 L3AddTimer(&pc
->timer
, T313
, CC_T313
);
507 l3_1tr6_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
509 release_l3_process(pc
);
513 l3_1tr6_disconnect_req(struct l3_process
*pc
, u_char pr
, void *arg
)
522 if (pc
->para
.cause
> 0)
523 cause
= pc
->para
.cause
;
524 /* Map DSS1 causes */
525 switch (cause
& 0x7f) {
530 cause
= CAUSE_UserBusy
;
533 cause
= CAUSE_CallRejected
;
537 MsgHead(p
, pc
->callref
, MT_N1_DISC
, PROTO_DIS_N1
);
539 *p
++ = clen
; /* Laenge */
544 if (!(skb
= l3_alloc_skb(l
)))
546 skb_put_data(skb
, tmp
, l
);
547 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
548 L3AddTimer(&pc
->timer
, T305
, CC_T305
);
552 l3_1tr6_t303(struct l3_process
*pc
, u_char pr
, void *arg
)
556 L3DelTimer(&pc
->timer
);
557 l3_1tr6_setup_req(pc
, pr
, arg
);
559 L3DelTimer(&pc
->timer
);
561 l3_1tr6_disconnect_req(pc
, 0, NULL
);
566 l3_1tr6_t304(struct l3_process
*pc
, u_char pr
, void *arg
)
568 L3DelTimer(&pc
->timer
);
569 pc
->para
.cause
= 0xE6;
570 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
571 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
575 l3_1tr6_t305(struct l3_process
*pc
, u_char pr
, void *arg
)
584 L3DelTimer(&pc
->timer
);
585 if (pc
->para
.cause
!= NO_CAUSE
)
586 cause
= pc
->para
.cause
;
587 /* Map DSS1 causes */
588 switch (cause
& 0x7f) {
593 cause
= CAUSE_CallRejected
;
596 MsgHead(p
, pc
->callref
, MT_N1_REL
, PROTO_DIS_N1
);
598 *p
++ = clen
; /* Laenge */
603 if (!(skb
= l3_alloc_skb(l
)))
605 skb_put_data(skb
, tmp
, l
);
606 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
607 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
611 l3_1tr6_t310(struct l3_process
*pc
, u_char pr
, void *arg
)
613 L3DelTimer(&pc
->timer
);
614 pc
->para
.cause
= 0xE6;
615 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
616 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
620 l3_1tr6_t313(struct l3_process
*pc
, u_char pr
, void *arg
)
622 L3DelTimer(&pc
->timer
);
623 pc
->para
.cause
= 0xE6;
624 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
625 pc
->st
->l3
.l3l4(pc
->st
, CC_CONNECT_ERR
, pc
);
629 l3_1tr6_t308_1(struct l3_process
*pc
, u_char pr
, void *arg
)
631 L3DelTimer(&pc
->timer
);
632 l3_1TR6_message(pc
, MT_N1_REL
, PROTO_DIS_N1
);
633 L3AddTimer(&pc
->timer
, T308
, CC_T308_2
);
638 l3_1tr6_t308_2(struct l3_process
*pc
, u_char pr
, void *arg
)
640 L3DelTimer(&pc
->timer
);
641 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE_ERR
, pc
);
642 release_l3_process(pc
);
646 l3_1tr6_dl_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
648 pc
->para
.cause
= CAUSE_LocalProcErr
;
649 l3_1tr6_disconnect_req(pc
, pr
, NULL
);
650 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
654 l3_1tr6_dl_release(struct l3_process
*pc
, u_char pr
, void *arg
)
657 pc
->para
.cause
= 0x1b; /* Destination out of order */
659 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
660 release_l3_process(pc
);
664 static struct stateentry downstl
[] =
667 CC_SETUP
| REQUEST
, l3_1tr6_setup_req
},
668 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
670 CC_DISCONNECT
| REQUEST
, l3_1tr6_disconnect_req
},
672 CC_RELEASE
| REQUEST
, l3_1tr6_release_req
},
674 CC_IGNORE
| REQUEST
, l3_1tr6_reset
},
676 CC_REJECT
| REQUEST
, l3_1tr6_disconnect_req
},
678 CC_ALERTING
| REQUEST
, l3_1tr6_alert_req
},
680 CC_SETUP
| RESPONSE
, l3_1tr6_setup_rsp
},
682 CC_T303
, l3_1tr6_t303
},
684 CC_T304
, l3_1tr6_t304
},
686 CC_T310
, l3_1tr6_t310
},
688 CC_T313
, l3_1tr6_t313
},
690 CC_T305
, l3_1tr6_t305
},
692 CC_T308_1
, l3_1tr6_t308_1
},
694 CC_T308_2
, l3_1tr6_t308_2
},
697 static struct stateentry datastln1
[] =
700 MT_N1_INVALID
, l3_1tr6_invalid
},
702 MT_N1_SETUP
, l3_1tr6_setup
},
704 MT_N1_SETUP_ACK
, l3_1tr6_setup_ack
},
706 MT_N1_CALL_SENT
, l3_1tr6_call_sent
},
707 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
708 MT_N1_DISC
, l3_1tr6_disc
},
709 {SBIT(2) | SBIT(3) | SBIT(4),
710 MT_N1_ALERT
, l3_1tr6_alert
},
711 {SBIT(2) | SBIT(3) | SBIT(4),
712 MT_N1_CONN
, l3_1tr6_connect
},
714 MT_N1_INFO
, l3_1tr6_info_s2
},
716 MT_N1_CONN_ACK
, l3_1tr6_connect_ack
},
718 MT_N1_INFO
, l3_1tr6_info
},
719 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
720 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
721 MT_N1_REL
, l3_1tr6_rel
},
723 MT_N1_REL
, l3_1tr6_rel_ack
},
724 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
725 SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
726 MT_N1_REL_ACK
, l3_1tr6_invalid
},
728 MT_N1_REL_ACK
, l3_1tr6_rel_ack
}
731 static struct stateentry manstatelist
[] =
734 DL_ESTABLISH
| INDICATION
, l3_1tr6_dl_reset
},
736 DL_RELEASE
| INDICATION
, l3_1tr6_dl_release
},
742 up1tr6(struct PStack
*st
, int pr
, void *arg
)
745 struct l3_process
*proc
;
746 struct sk_buff
*skb
= arg
;
749 case (DL_DATA
| INDICATION
):
750 case (DL_UNIT_DATA
| INDICATION
):
752 case (DL_ESTABLISH
| CONFIRM
):
753 case (DL_ESTABLISH
| INDICATION
):
754 case (DL_RELEASE
| INDICATION
):
755 case (DL_RELEASE
| CONFIRM
):
761 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
762 l3_debug(st
, "up1tr6 len only %d", skb
->len
);
767 if ((skb
->data
[0] & 0xfe) != PROTO_DIS_N0
) {
768 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
769 l3_debug(st
, "up1tr6%sunexpected discriminator %x message len %d",
770 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
771 skb
->data
[0], skb
->len
);
776 if (skb
->data
[1] != 1) {
777 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
778 l3_debug(st
, "up1tr6 CR len not 1");
785 if (skb
->data
[0] == PROTO_DIS_N0
) {
787 if (st
->l3
.debug
& L3_DEB_STATE
) {
788 l3_debug(st
, "up1tr6%s N0 mt %x unhandled",
789 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ", mt
);
791 } else if (skb
->data
[0] == PROTO_DIS_N1
) {
792 if (!(proc
= getl3proc(st
, cr
))) {
793 if (mt
== MT_N1_SETUP
) {
795 if (!(proc
= new_l3_process(st
, cr
))) {
796 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
797 l3_debug(st
, "up1tr6 no roc mem");
806 } else if ((mt
== MT_N1_REL
) || (mt
== MT_N1_REL_ACK
) ||
807 (mt
== MT_N1_CANC_ACK
) || (mt
== MT_N1_CANC_REJ
) ||
808 (mt
== MT_N1_REG_ACK
) || (mt
== MT_N1_REG_REJ
) ||
809 (mt
== MT_N1_SUSP_ACK
) || (mt
== MT_N1_RES_REJ
) ||
810 (mt
== MT_N1_INFO
)) {
814 if (!(proc
= new_l3_process(st
, cr
))) {
815 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
816 l3_debug(st
, "up1tr6 no roc mem");
824 for (i
= 0; i
< ARRAY_SIZE(datastln1
); i
++)
825 if ((mt
== datastln1
[i
].primitive
) &&
826 ((1 << proc
->state
) & datastln1
[i
].state
))
828 if (i
== ARRAY_SIZE(datastln1
)) {
830 if (st
->l3
.debug
& L3_DEB_STATE
) {
831 l3_debug(st
, "up1tr6%sstate %d mt %x unhandled",
832 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
837 if (st
->l3
.debug
& L3_DEB_STATE
) {
838 l3_debug(st
, "up1tr6%sstate %d mt %x",
839 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
842 datastln1
[i
].rout(proc
, pr
, skb
);
848 down1tr6(struct PStack
*st
, int pr
, void *arg
)
851 struct l3_process
*proc
;
852 struct Channel
*chan
;
854 if ((DL_ESTABLISH
| REQUEST
) == pr
) {
855 l3_msg(st
, pr
, NULL
);
857 } else if ((CC_SETUP
| REQUEST
) == pr
) {
861 if (!(proc
= new_l3_process(st
, cr
))) {
866 memcpy(&proc
->para
.setup
, &chan
->setup
, sizeof(setup_parm
));
873 for (i
= 0; i
< ARRAY_SIZE(downstl
); i
++)
874 if ((pr
== downstl
[i
].primitive
) &&
875 ((1 << proc
->state
) & downstl
[i
].state
))
877 if (i
== ARRAY_SIZE(downstl
)) {
878 if (st
->l3
.debug
& L3_DEB_STATE
) {
879 l3_debug(st
, "down1tr6 state %d prim %d unhandled",
883 if (st
->l3
.debug
& L3_DEB_STATE
) {
884 l3_debug(st
, "down1tr6 state %d prim %d",
887 downstl
[i
].rout(proc
, pr
, arg
);
892 man1tr6(struct PStack
*st
, int pr
, void *arg
)
895 struct l3_process
*proc
= arg
;
898 printk(KERN_ERR
"HiSax man1tr6 without proc pr=%04x\n", pr
);
901 for (i
= 0; i
< ARRAY_SIZE(manstatelist
); i
++)
902 if ((pr
== manstatelist
[i
].primitive
) &&
903 ((1 << proc
->state
) & manstatelist
[i
].state
))
905 if (i
== ARRAY_SIZE(manstatelist
)) {
906 if (st
->l3
.debug
& L3_DEB_STATE
) {
907 l3_debug(st
, "cr %d man1tr6 state %d prim %d unhandled",
908 proc
->callref
& 0x7f, proc
->state
, pr
);
911 if (st
->l3
.debug
& L3_DEB_STATE
) {
912 l3_debug(st
, "cr %d man1tr6 state %d prim %d",
913 proc
->callref
& 0x7f, proc
->state
, pr
);
915 manstatelist
[i
].rout(proc
, pr
, arg
);
920 setstack_1tr6(struct PStack
*st
)
924 st
->lli
.l4l3
= down1tr6
;
925 st
->l2
.l2l3
= up1tr6
;
926 st
->l3
.l3ml3
= man1tr6
;
929 strcpy(tmp
, l3_1tr6_revision
);
930 printk(KERN_INFO
"HiSax: 1TR6 Rev. %s\n", HiSax_getrev(tmp
));