1 /* $Id: l3dss1.c,v 2.12 1998/11/15 23:55:10 keil Exp $
3 * EURO/DSS1 D-channel protocol
5 * Author Karsten Keil (keil@isdn4linux.de)
6 * based on the teles driver from Jan den Ouden
8 * This file is (c) under GNU PUBLIC LICENSE
9 * For changes and modifications please read
10 * ../../../Documentation/isdn/HiSax.cert
12 * Thanks to Jan den Ouden
16 * Revision 2.12 1998/11/15 23:55:10 keil
19 * Revision 2.11 1998/08/13 23:36:51 keil
20 * HiSax 3.1 - don't work stable with current LinkLevel
22 * Revision 2.10 1998/05/25 14:10:20 keil
24 * X.75 and leased are working again.
26 * Revision 2.9 1998/05/25 12:58:17 keil
27 * HiSax golden code from certification, Don't use !!!
28 * No leased lines, no X75, but many changes.
30 * Revision 2.8 1998/03/19 13:18:47 keil
31 * Start of a CAPI like interface for supplementary Service
32 * first service: SUSPEND
34 * Revision 2.7 1998/02/12 23:08:01 keil
35 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
37 * Revision 2.6 1998/02/03 23:26:35 keil
38 * V110 extensions from Thomas Pfeiffer
40 * Revision 2.5 1998/02/02 13:34:28 keil
41 * Support australian Microlink net and german AOCD
43 * Revision 2.4 1997/11/06 17:12:25 keil
44 * KERN_NOTICE --> KERN_INFO
46 * Revision 2.3 1997/10/29 19:03:01 keil
49 * Revision 2.2 1997/08/07 17:44:36 keil
52 * Revision 2.1 1997/08/03 14:36:33 keil
53 * Implement RESTART procedure
55 * Revision 2.0 1997/07/27 21:15:43 keil
56 * New Callref based layer3
58 * Revision 1.17 1997/06/26 11:11:46 keil
59 * SET_SKBFREE now on creation of a SKB
61 * Revision 1.15 1997/04/17 11:50:48 keil
62 * pa->loc was undefined, if it was not send by the exchange
64 * Old log removed /KKe
68 #define __NO_VERSION__
72 #include <linux/ctype.h>
74 extern char *HiSax_getrev(const char *revision
);
75 const char *dss1_revision
= "$Revision: 2.12 $";
77 #define MsgHead(ptr, cref, mty) \
86 l3dss1_parse_facility(struct l3_process
*pc
, u_char
* p
)
93 l3_debug(pc
->st
, "qd_len == 0");
96 if ((*p
& 0x1F) != 0x11) { /* Service discriminator, supplementary service */
97 l3_debug(pc
->st
, "supplementary service != 0x11");
100 while (qd_len
> 0 && !(*p
& 0x80)) { /* extension ? */
105 l3_debug(pc
->st
, "qd_len < 2");
110 if ((*p
& 0xE0) != 0xA0) { /* class and form */
111 l3_debug(pc
->st
, "class and form != 0xA0");
114 switch (*p
& 0x1F) { /* component tag */
117 unsigned char nlen
= 0, ilen
;
123 l3_debug(pc
->st
, "qd_len < 1");
126 if (*p
& 0x80) { /* length format */
127 l3_debug(pc
->st
, "*p & 0x80 length format");
133 l3_debug(pc
->st
, "qd_len < nlen");
139 l3_debug(pc
->st
, "nlen < 2");
142 if (*p
!= 0x02) { /* invoke identifier tag */
143 l3_debug(pc
->st
, "invoke identifier tag !=0x02");
148 if (*p
& 0x80) { /* length format */
149 l3_debug(pc
->st
, "*p & 0x80 length format 2");
154 if (ilen
> nlen
|| ilen
== 0) {
155 l3_debug(pc
->st
, "ilen > nlen || ilen == 0");
161 ident
= (ident
<< 8) | (*p
++ & 0xFF); /* invoke identifier */
166 l3_debug(pc
->st
, "nlen < 2 22");
169 if (*p
!= 0x02) { /* operation value */
170 l3_debug(pc
->st
, "operation value !=0x02");
177 if (ilen
> nlen
|| ilen
== 0) {
178 l3_debug(pc
->st
, "ilen > nlen || ilen == 0 22");
184 ident
= (ident
<< 8) | (*p
++ & 0xFF);
188 #define FOO1(s,a,b) \
191 if(nlen < ilen+2) { \
192 l3_debug(pc->st, "FOO1 nlen < ilen+2"); \
196 if((*p & 0xFF) == (a)) { \
208 case 0x22: /* during */
209 FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( {
211 nlen
= (nlen
)?nlen
:0; /* Make gcc happy */
213 ident
= (ident
<< 8) | *p
++;
216 if (ident
> pc
->para
.chargeinfo
) {
217 pc
->para
.chargeinfo
= ident
;
218 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
220 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
222 l3_debug(pc
->st
, "charging info during %d", pc
->para
.chargeinfo
);
225 l3_debug(pc
->st
, "charging info final %d", pc
->para
.chargeinfo
);
231 case 0x24: /* final */
232 FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( {
234 nlen
= (nlen
)?nlen
:0; /* Make gcc happy */
236 ident
= (ident
<< 8) | *p
++;
239 if (ident
> pc
->para
.chargeinfo
) {
240 pc
->para
.chargeinfo
= ident
;
241 pc
->st
->l3
.l3l4(pc
->st
, CC_CHARGE
| INDICATION
, pc
);
243 if (pc
->st
->l3
.debug
& L3_DEB_CHARGE
) {
244 l3_debug(pc
->st
, "charging info final %d", pc
->para
.chargeinfo
);
254 case 2: /* return result */
255 l3_debug(pc
->st
, "return result break");
257 case 3: /* return error */
258 l3_debug(pc
->st
, "return error break");
261 l3_debug(pc
->st
, "default break");
268 l3dss1_check_messagetype_validity(int mt
)
270 /* verify if a message type exists */
273 case MT_CALL_PROCEEDING
:
275 case MT_CONNECT_ACKNOWLEDGE
:
278 case MT_SETUP_ACKNOWLEDGE
:
280 case MT_RESUME_ACKNOWLEDGE
:
281 case MT_RESUME_REJECT
:
283 case MT_SUSPEND_ACKNOWLEDGE
:
284 case MT_SUSPEND_REJECT
:
285 case MT_USER_INFORMATION
:
288 case MT_RELEASE_COMPLETE
:
290 case MT_RESTART_ACKNOWLEDGE
:
292 case MT_CONGESTION_CONTROL
:
297 case MT_STATUS_ENQUIRY
:
306 l3dss1_message(struct l3_process
*pc
, u_char mt
)
311 if (!(skb
= l3_alloc_skb(4)))
314 MsgHead(p
, pc
->callref
, mt
);
315 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
319 l3dss1_release_req(struct l3_process
*pc
, u_char pr
, void *arg
)
323 l3dss1_message(pc
, MT_RELEASE
);
324 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
328 l3dss1_release_cmpl(struct l3_process
*pc
, u_char pr
, void *arg
)
331 struct sk_buff
*skb
= arg
;
336 if ((p
= findie(p
, skb
->len
, IE_CAUSE
, 0))) {
344 pc
->para
.cause
= cause
;
346 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| CONFIRM
, pc
);
347 release_l3_process(pc
);
353 EncodeASyncParams(u_char
* p
, u_char si2
)
354 { // 7c 06 88 90 21 42 00 bb
358 if (si2
& 32) // 7 data bits
365 if (si2
& 16) // 2 stop bits
372 if (si2
& 8) // even parity
379 switch (si2
& 0x07) {
381 p
[0] = 66; // 1200 bit/s
385 p
[0] = 88; // 1200/75 bit/s
389 p
[0] = 87; // 75/1200 bit/s
393 p
[0] = 67; // 2400 bit/s
397 p
[0] = 69; // 4800 bit/s
401 p
[0] = 72; // 9600 bit/s
405 p
[0] = 73; // 14400 bit/s
409 p
[0] = 75; // 19200 bit/s
417 EncodeSyncParams(u_char si2
, u_char ai
)
422 return ai
+ 2; // 1200 bit/s
425 return ai
+ 24; // 1200/75 bit/s
428 return ai
+ 23; // 75/1200 bit/s
431 return ai
+ 3; // 2400 bit/s
434 return ai
+ 5; // 4800 bit/s
437 return ai
+ 8; // 9600 bit/s
440 return ai
+ 9; // 14400 bit/s
443 return ai
+ 11; // 19200 bit/s
446 return ai
+ 14; // 48000 bit/s
449 return ai
+ 15; // 56000 bit/s
452 return ai
+ 40; // negotiate bit/s
462 DecodeASyncParams(u_char si2
, u_char
* p
)
467 case 66: // 1200 bit/s
469 break; // si2 don't change
471 case 88: // 1200/75 bit/s
475 case 87: // 75/1200 bit/s
479 case 67: // 2400 bit/s
483 case 69: // 4800 bit/s
487 case 72: // 9600 bit/s
491 case 73: // 14400 bit/s
495 case 75: // 19200 bit/s
502 if ((info
& 16) && (!(info
& 8))) // 7 data bits
504 si2
+= 32; // else 8 data bits
506 if ((info
& 96) == 96) // 2 stop bits
508 si2
+= 16; // else 1 stop bit
510 if ((info
& 2) && (!(info
& 1))) // even parity
512 si2
+= 8; // else no parity
519 DecodeSyncParams(u_char si2
, u_char info
)
523 case 40: // bit/s negotiation failed ai := 165 not 175!
526 case 15: // 56000 bit/s failed, ai := 0 not 169 !
529 case 14: // 48000 bit/s
532 case 11: // 19200 bit/s
535 case 9: // 14400 bit/s
538 case 8: // 9600 bit/s
541 case 5: // 4800 bit/s
544 case 3: // 2400 bit/s
547 case 23: // 75/1200 bit/s
550 case 24: // 1200/75 bit/s
553 default: // 1200 bit/s
560 DecodeSI2(struct sk_buff
*skb
)
562 u_char
*p
; //, *pend=skb->data + skb->len;
564 if ((p
= findie(skb
->data
, skb
->len
, 0x7c, 0))) {
565 switch (p
[4] & 0x0f) {
567 if (p
[1] == 0x04) // sync. Bitratenadaption
569 return DecodeSyncParams(160, p
[5]); // V.110/X.30
571 else if (p
[1] == 0x06) // async. Bitratenadaption
573 return DecodeASyncParams(192, p
); // V.110/X.30
576 case 0x08: // if (p[5] == 0x02) // sync. Bitratenadaption
578 return DecodeSyncParams(176, p
[5]); // V.120
590 l3dss1_setup_req(struct l3_process
*pc
, u_char pr
,
597 u_char screen
= 0x80;
604 MsgHead(p
, pc
->callref
, MT_SETUP
);
607 * Set Bearer Capability, Map info from 1TR6-convention to EDSS1
609 #if HISAX_EURO_SENDCOMPLETE
610 *p
++ = 0xa1; /* complete indicator */
612 switch (pc
->para
.setup
.si1
) {
613 case 1: /* Telephony */
614 *p
++ = 0x4; /* BC-IE-code */
615 *p
++ = 0x3; /* Length */
616 *p
++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */
617 *p
++ = 0x90; /* Circuit-Mode 64kbps */
618 *p
++ = 0xa3; /* A-Law Audio */
620 case 5: /* Datatransmission 64k, BTX */
621 case 7: /* Datatransmission 64k */
623 *p
++ = 0x4; /* BC-IE-code */
624 *p
++ = 0x2; /* Length */
625 *p
++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */
626 *p
++ = 0x90; /* Circuit-Mode 64kbps */
630 * What about info2? Mapping to High-Layer-Compatibility?
632 teln
= pc
->para
.setup
.phone
;
634 /* parse number for special things */
635 if (!isdigit(*teln
)) {
636 switch (0x5f & *teln
) {
654 if (pc
->debug
& L3_DEB_WARN
)
655 l3_debug(pc
->st
, "Wrong MSN Code");
662 *p
++ = IE_CHANNEL_ID
;
666 msn
= pc
->para
.setup
.eazmsn
;
678 *p
++ = strlen(msn
) + (screen
? 2 : 1);
679 /* Classify as AnyPref. */
681 *p
++ = 0x01; /* Ext = '0'B, Type = '000'B, Plan = '0001'B. */
684 *p
++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
686 *p
++ = *msn
++ & 0x7f;
690 *p
++ = 0x6d; /* Calling party subaddress */
691 *p
++ = strlen(sub
) + 2;
692 *p
++ = 0x80; /* NSAP coded */
693 *p
++ = 0x50; /* local IDI format */
695 *p
++ = *sub
++ & 0x7f;
707 *p
++ = strlen(teln
) + 1;
708 /* Classify as AnyPref. */
709 *p
++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
711 *p
++ = *teln
++ & 0x7f;
715 *p
++ = 0x71; /* Called party subaddress */
716 *p
++ = strlen(sub
) + 2;
717 *p
++ = 0x80; /* NSAP coded */
718 *p
++ = 0x50; /* local IDI format */
720 *p
++ = *sub
++ & 0x7f;
723 if ((pc
->para
.setup
.si2
>= 160) && (pc
->para
.setup
.si2
<= 175)) { // sync. Bitratenadaption, V.110/X.30
730 *p
++ = EncodeSyncParams(pc
->para
.setup
.si2
- 160, 0x80);
731 } else if ((pc
->para
.setup
.si2
>= 176) && (pc
->para
.setup
.si2
<= 191)) { // sync. Bitratenadaption, V.120
738 *p
++ = EncodeSyncParams(pc
->para
.setup
.si2
- 176, 0);
740 } else if (pc
->para
.setup
.si2
>= 192) { // async. Bitratenadaption, V.110/X.30
747 p
= EncodeASyncParams(p
, pc
->para
.setup
.si2
- 192);
748 #if HISAX_SEND_STD_LLC_IE
758 if (!(skb
= l3_alloc_skb(l
)))
760 memcpy(skb_put(skb
, l
), tmp
, l
);
761 L3DelTimer(&pc
->timer
);
762 L3AddTimer(&pc
->timer
, T303
, CC_T303
);
764 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
768 l3dss1_call_proc(struct l3_process
*pc
, u_char pr
, void *arg
)
771 struct sk_buff
*skb
= arg
;
773 L3DelTimer(&pc
->timer
);
775 if ((p
= findie(p
, skb
->len
, IE_CHANNEL_ID
, 0))) {
776 pc
->para
.bchannel
= p
[2] & 0x3;
777 if ((!pc
->para
.bchannel
) && (pc
->debug
& L3_DEB_WARN
))
778 l3_debug(pc
->st
, "setup answer without bchannel");
779 } else if (pc
->debug
& L3_DEB_WARN
)
780 l3_debug(pc
->st
, "setup answer without bchannel");
783 L3AddTimer(&pc
->timer
, T310
, CC_T310
);
784 pc
->st
->l3
.l3l4(pc
->st
, CC_PROCEEDING
| INDICATION
, pc
);
788 l3dss1_setup_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
791 struct sk_buff
*skb
= arg
;
793 L3DelTimer(&pc
->timer
);
795 if ((p
= findie(p
, skb
->len
, IE_CHANNEL_ID
, 0))) {
796 pc
->para
.bchannel
= p
[2] & 0x3;
797 if ((!pc
->para
.bchannel
) && (pc
->debug
& L3_DEB_WARN
))
798 l3_debug(pc
->st
, "setup answer without bchannel");
799 } else if (pc
->debug
& L3_DEB_WARN
)
800 l3_debug(pc
->st
, "setup answer without bchannel");
803 L3AddTimer(&pc
->timer
, T304
, CC_T304
);
804 pc
->st
->l3
.l3l4(pc
->st
, CC_MORE_INFO
| INDICATION
, pc
);
808 l3dss1_disconnect(struct l3_process
*pc
, u_char pr
, void *arg
)
811 struct sk_buff
*skb
= arg
;
817 if ((p
= findie(p
, skb
->len
, IE_CAUSE
, 0))) {
825 pc
->para
.cause
= cause
;
826 pc
->st
->l3
.l3l4(pc
->st
, CC_DISCONNECT
| INDICATION
, pc
);
830 l3dss1_connect(struct l3_process
*pc
, u_char pr
, void *arg
)
832 struct sk_buff
*skb
= arg
;
835 L3DelTimer(&pc
->timer
); /* T310 */
837 pc
->para
.chargeinfo
= 0;
838 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| CONFIRM
, pc
);
842 l3dss1_alerting(struct l3_process
*pc
, u_char pr
, void *arg
)
844 struct sk_buff
*skb
= arg
;
847 L3DelTimer(&pc
->timer
); /* T304 */
849 pc
->st
->l3
.l3l4(pc
->st
, CC_ALERTING
| INDICATION
, pc
);
853 l3dss1_msg_without_setup(struct l3_process
*pc
, u_char pr
, void *arg
)
855 /* This routine is called if here was no SETUP made (checks in dss1up and in
856 * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
857 * MT_STATUS_ENQUIRE in the NULL state is handled too
864 switch (pc
->para
.cause
) {
865 case 81: /* 0x51 invalid callreference */
866 case 88: /* 0x58 incomp destination */
867 case 96: /* 0x60 mandory IE missing */
868 case 101: /* 0x65 incompatible Callstate */
869 MsgHead(p
, pc
->callref
, MT_RELEASE_COMPLETE
);
873 *p
++ = pc
->para
.cause
| 0x80;
876 printk(KERN_ERR
"HiSax internal error l3dss1_msg_without_setup\n");
880 if (!(skb
= l3_alloc_skb(l
)))
882 memcpy(skb_put(skb
, l
), tmp
, l
);
883 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
884 release_l3_process(pc
);
888 l3dss1_setup(struct l3_process
*pc
, u_char pr
, void *arg
)
894 struct sk_buff
*skb
= arg
;
896 /* ETS 300-104 1.3.4 and 1.3.5
897 * we need to detect unknown inform. element from 0 to 7
900 for (i
= 0; i
< 8; i
++)
902 if (findie(ptmp
[1], skb
->len
, 0x01, 0)
903 || findie(ptmp
[2], skb
->len
, 0x02, 0)
904 || findie(ptmp
[3], skb
->len
, 0x03, 0)
905 || findie(ptmp
[5], skb
->len
, 0x05, 0)
906 || findie(ptmp
[6], skb
->len
, 0x06, 0)
907 || findie(ptmp
[7], skb
->len
, 0x07, 0)) {
908 /* if ie is < 8 and not 0 nor 4, send RELEASE_COMPLETE
911 pc
->para
.cause
= 0x60;
913 l3dss1_msg_without_setup(pc
, pr
, NULL
);
917 * Channel Identification
920 if ((p
= findie(p
, skb
->len
, IE_CHANNEL_ID
, 0))) {
921 pc
->para
.bchannel
= p
[2] & 0x3;
922 if (pc
->para
.bchannel
)
924 else if (pc
->debug
& L3_DEB_WARN
)
925 l3_debug(pc
->st
, "setup without bchannel");
927 if (pc
->debug
& L3_DEB_WARN
)
928 l3_debug(pc
->st
, "setup without bchannel");
929 pc
->para
.cause
= 0x60;
931 l3dss1_msg_without_setup(pc
, pr
, NULL
);
935 * Bearer Capabilities
938 if ((p
= findie(p
, skb
->len
, 0x04, 0))) {
939 pc
->para
.setup
.si2
= 0;
940 switch (p
[2] & 0x1f) {
945 pc
->para
.setup
.si1
= 1;
948 /* Unrestricted digital information */
949 pc
->para
.setup
.si1
= 7;
950 /* JIM, 05.11.97 I wanna set service indicator 2 */
952 pc
->para
.setup
.si2
= DecodeSI2(skb
);
953 printk(KERN_DEBUG
"HiSax: SI=%d, AI=%d\n",
954 pc
->para
.setup
.si1
, pc
->para
.setup
.si2
);
958 /* Restricted digital information */
959 pc
->para
.setup
.si1
= 2;
962 /* Unrestr. digital information with tones/announcements */
963 pc
->para
.setup
.si1
= 3;
967 pc
->para
.setup
.si1
= 4;
970 pc
->para
.setup
.si1
= 0;
973 if (pc
->debug
& L3_DEB_WARN
)
974 l3_debug(pc
->st
, "setup without bearer capabilities");
975 /* ETS 300-104 1.3.3 */
976 pc
->para
.cause
= 0x60;
978 l3dss1_msg_without_setup(pc
, pr
, NULL
);
983 if ((p
= findie(p
, skb
->len
, 0x70, 0)))
984 iecpy(pc
->para
.setup
.eazmsn
, p
, 1);
986 pc
->para
.setup
.eazmsn
[0] = 0;
989 if ((p
= findie(p
, skb
->len
, 0x71, 0))) {
990 /* Called party subaddress */
991 if ((p
[1] >= 2) && (p
[2] == 0x80) && (p
[3] == 0x50)) {
993 iecpy(&tmp
[1], p
, 2);
994 strcat(pc
->para
.setup
.eazmsn
, tmp
);
995 } else if (pc
->debug
& L3_DEB_WARN
)
996 l3_debug(pc
->st
, "wrong called subaddress");
999 if ((p
= findie(p
, skb
->len
, 0x6c, 0))) {
1000 pc
->para
.setup
.plan
= p
[2];
1002 iecpy(pc
->para
.setup
.phone
, p
, 1);
1003 pc
->para
.setup
.screen
= 0;
1005 iecpy(pc
->para
.setup
.phone
, p
, 2);
1006 pc
->para
.setup
.screen
= p
[3];
1009 pc
->para
.setup
.phone
[0] = 0;
1010 pc
->para
.setup
.plan
= 0;
1011 pc
->para
.setup
.screen
= 0;
1014 if ((p
= findie(p
, skb
->len
, 0x6d, 0))) {
1015 /* Calling party subaddress */
1016 if ((p
[1] >= 2) && (p
[2] == 0x80) && (p
[3] == 0x50)) {
1018 iecpy(&tmp
[1], p
, 2);
1019 strcat(pc
->para
.setup
.phone
, tmp
);
1020 } else if (pc
->debug
& L3_DEB_WARN
)
1021 l3_debug(pc
->st
, "wrong calling subaddress");
1026 if ((pc
->para
.setup
.si1
!= 7) && (pc
->debug
& L3_DEB_WARN
)) {
1027 l3_debug(pc
->st
, "non-digital call: %s -> %s",
1028 pc
->para
.setup
.phone
, pc
->para
.setup
.eazmsn
);
1030 if ((pc
->para
.setup
.si1
!= 7) &&
1031 test_bit(FLG_PTP
, &pc
->st
->l2
.flag
)) {
1032 pc
->para
.cause
= 0x58;
1033 l3dss1_msg_without_setup(pc
, pr
, NULL
);
1037 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP
| INDICATION
, pc
);
1039 release_l3_process(pc
);
1043 l3dss1_reset(struct l3_process
*pc
, u_char pr
, void *arg
)
1045 release_l3_process(pc
);
1049 l3dss1_setup_rsp(struct l3_process
*pc
, u_char pr
,
1053 l3dss1_message(pc
, MT_CONNECT
);
1054 L3DelTimer(&pc
->timer
);
1055 L3AddTimer(&pc
->timer
, T313
, CC_T313
);
1059 l3dss1_connect_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
1061 struct sk_buff
*skb
= arg
;
1065 L3DelTimer(&pc
->timer
);
1066 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_COMPL
| INDICATION
, pc
);
1070 l3dss1_disconnect_req(struct l3_process
*pc
, u_char pr
, void *arg
)
1072 struct sk_buff
*skb
;
1076 u_char cause
= 0x10;
1078 if (pc
->para
.cause
> 0)
1079 cause
= pc
->para
.cause
;
1083 MsgHead(p
, pc
->callref
, MT_DISCONNECT
);
1088 *p
++ = cause
| 0x80;
1091 if (!(skb
= l3_alloc_skb(l
)))
1093 memcpy(skb_put(skb
, l
), tmp
, l
);
1095 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1096 L3AddTimer(&pc
->timer
, T305
, CC_T305
);
1100 l3dss1_reject_req(struct l3_process
*pc
, u_char pr
, void *arg
)
1102 struct sk_buff
*skb
;
1106 u_char cause
= 0x95;
1108 if (pc
->para
.cause
> 0)
1109 cause
= pc
->para
.cause
;
1111 MsgHead(p
, pc
->callref
, MT_RELEASE_COMPLETE
);
1119 if (!(skb
= l3_alloc_skb(l
)))
1121 memcpy(skb_put(skb
, l
), tmp
, l
);
1122 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1123 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
1125 release_l3_process(pc
);
1129 l3dss1_release(struct l3_process
*pc
, u_char pr
, void *arg
)
1132 struct sk_buff
*skb
= arg
;
1136 if ((p
= findie(p
, skb
->len
, IE_CAUSE
, 0))) {
1139 pc
->para
.loc
= *p
++;
1143 if ((p
= findie(p
, skb
->len
, IE_FACILITY
, 0))) {
1145 l3dss1_parse_facility(pc
, p
);
1152 pc
->para
.cause
= cause
;
1153 l3dss1_message(pc
, MT_RELEASE_COMPLETE
);
1154 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
1156 release_l3_process(pc
);
1160 l3dss1_alert_req(struct l3_process
*pc
, u_char pr
,
1164 l3dss1_message(pc
, MT_ALERTING
);
1168 l3dss1_status_enq(struct l3_process
*pc
, u_char pr
, void *arg
)
1173 struct sk_buff
*skb
= arg
;
1177 MsgHead(p
, pc
->callref
, MT_STATUS
);
1182 *p
++ = 0x9E; /* answer status enquire */
1184 *p
++ = 0x14; /* CallState */
1186 *p
++ = pc
->state
& 0x3f;
1189 if (!(skb
= l3_alloc_skb(l
)))
1191 memcpy(skb_put(skb
, l
), tmp
, l
);
1192 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1196 l3dss1_status_req(struct l3_process
*pc
, u_char pr
, void *arg
)
1198 /* ETS 300-104 7.4.1, 8.4.1, 10.3.1, 11.4.1, 12.4.1, 13.4.1, 14.4.1...
1199 if setup has been made and a non expected message type is received, we must send MT_STATUS cause 0x62 */
1203 struct sk_buff
*skb
= arg
;
1207 MsgHead(p
, pc
->callref
, MT_STATUS
);
1212 *p
++ = 0x62 | 0x80; /* status sending */
1214 *p
++ = 0x14; /* CallState */
1216 *p
++ = pc
->state
& 0x3f;
1219 if (!(skb
= l3_alloc_skb(l
)))
1221 memcpy(skb_put(skb
, l
), tmp
, l
);
1222 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1226 l3dss1_release_ind(struct l3_process
*pc
, u_char pr
, void *arg
)
1229 struct sk_buff
*skb
= arg
;
1233 if ((p
= findie(p
, skb
->len
, IE_CALL_STATE
, 0))) {
1238 if (callState
== 0) {
1239 /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
1240 * set down layer 3 without sending any message
1242 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE
| INDICATION
, pc
);
1244 release_l3_process(pc
);
1246 pc
->st
->l3
.l3l4(pc
->st
, CC_IGNORE
| INDICATION
, pc
);
1251 l3dss1_t303(struct l3_process
*pc
, u_char pr
, void *arg
)
1255 L3DelTimer(&pc
->timer
);
1256 l3dss1_setup_req(pc
, pr
, arg
);
1258 L3DelTimer(&pc
->timer
);
1259 pc
->st
->l3
.l3l4(pc
->st
, CC_NOSETUP_RSP
, pc
);
1260 release_l3_process(pc
);
1265 l3dss1_t304(struct l3_process
*pc
, u_char pr
, void *arg
)
1267 L3DelTimer(&pc
->timer
);
1268 pc
->para
.cause
= 0xE6;
1269 l3dss1_disconnect_req(pc
, pr
, NULL
);
1270 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
1275 l3dss1_t305(struct l3_process
*pc
, u_char pr
, void *arg
)
1280 struct sk_buff
*skb
;
1281 u_char cause
= 0x90;
1283 L3DelTimer(&pc
->timer
);
1284 if (pc
->para
.cause
> 0)
1285 cause
= pc
->para
.cause
| 0x80;
1287 MsgHead(p
, pc
->callref
, MT_RELEASE
);
1295 if (!(skb
= l3_alloc_skb(l
)))
1297 memcpy(skb_put(skb
, l
), tmp
, l
);
1299 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1300 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
1304 l3dss1_t310(struct l3_process
*pc
, u_char pr
, void *arg
)
1306 L3DelTimer(&pc
->timer
);
1307 pc
->para
.cause
= 0xE6;
1308 l3dss1_disconnect_req(pc
, pr
, NULL
);
1309 pc
->st
->l3
.l3l4(pc
->st
, CC_SETUP_ERR
, pc
);
1313 l3dss1_t313(struct l3_process
*pc
, u_char pr
, void *arg
)
1315 L3DelTimer(&pc
->timer
);
1316 pc
->para
.cause
= 0xE6;
1317 l3dss1_disconnect_req(pc
, pr
, NULL
);
1318 pc
->st
->l3
.l3l4(pc
->st
, CC_CONNECT_ERR
, pc
);
1322 l3dss1_t308_1(struct l3_process
*pc
, u_char pr
, void *arg
)
1325 L3DelTimer(&pc
->timer
);
1326 l3dss1_message(pc
, MT_RELEASE
);
1327 L3AddTimer(&pc
->timer
, T308
, CC_T308_2
);
1331 l3dss1_t308_2(struct l3_process
*pc
, u_char pr
, void *arg
)
1333 L3DelTimer(&pc
->timer
);
1334 pc
->st
->l3
.l3l4(pc
->st
, CC_RELEASE_ERR
, pc
);
1335 release_l3_process(pc
);
1339 l3dss1_t318(struct l3_process
*pc
, u_char pr
, void *arg
)
1341 L3DelTimer(&pc
->timer
);
1342 pc
->para
.cause
= 0x66; /* Timer expiry */
1343 pc
->para
.loc
= 0; /* local */
1344 pc
->st
->l3
.l3l4(pc
->st
, CC_RESUME_ERR
, pc
);
1346 l3dss1_message(pc
, MT_RELEASE
);
1347 L3AddTimer(&pc
->timer
, T308
, CC_T308_1
);
1351 l3dss1_t319(struct l3_process
*pc
, u_char pr
, void *arg
)
1353 L3DelTimer(&pc
->timer
);
1354 pc
->para
.cause
= 0x66; /* Timer expiry */
1355 pc
->para
.loc
= 0; /* local */
1356 pc
->st
->l3
.l3l4(pc
->st
, CC_SUSPEND_ERR
, pc
);
1361 l3dss1_restart(struct l3_process
*pc
, u_char pr
, void *arg
)
1363 L3DelTimer(&pc
->timer
);
1364 pc
->st
->l3
.l3l4(pc
->st
, CC_DLRL
| INDICATION
, pc
);
1365 release_l3_process(pc
);
1369 l3dss1_status(struct l3_process
*pc
, u_char pr
, void *arg
)
1374 struct sk_buff
*skb
= arg
;
1375 int cause
, callState
;
1377 cause
= callState
= -1;
1380 if ((p
= findie(p
, skb
->len
, IE_CAUSE
, 0))) {
1383 t
+= sprintf(t
, "Status CR %x Cause:", pc
->callref
);
1386 t
+= sprintf(t
, " %2x", *p
++);
1389 sprintf(t
, "Status CR %x no Cause", pc
->callref
);
1390 l3_debug(pc
->st
, tmp
);
1393 t
+= sprintf(t
, "Status state %x ", pc
->state
);
1394 if ((p
= findie(p
, skb
->len
, IE_CALL_STATE
, 0))) {
1398 t
+= sprintf(t
, "peer state %x", *p
);
1400 t
+= sprintf(t
, "peer state len error");
1402 sprintf(t
, "no peer state");
1403 l3_debug(pc
->st
, tmp
);
1404 if (((cause
& 0x7f) == 0x6f) && (callState
== 0)) {
1405 /* ETS 300-104 7.6.1, 8.6.1, 10.6.1...
1406 * if received MT_STATUS with cause == 0x6f and call
1407 * state == 0, then we must set down layer 3
1409 l3dss1_release_ind(pc
, pr
, arg
);
1415 l3dss1_facility(struct l3_process
*pc
, u_char pr
, void *arg
)
1418 struct sk_buff
*skb
= arg
;
1421 if ((p
= findie(p
, skb
->len
, IE_FACILITY
, 0))) {
1423 l3dss1_parse_facility(pc
, p
);
1431 l3dss1_suspend_req(struct l3_process
*pc
, u_char pr
, void *arg
)
1433 struct sk_buff
*skb
;
1437 u_char
*msg
= pc
->chan
->setup
.phone
;
1439 MsgHead(p
, pc
->callref
, MT_SUSPEND
);
1443 if (l
&& (l
<= 10)) { /* Max length 10 octets */
1445 for (i
= 0; i
< l
; i
++)
1448 l3_debug(pc
->st
, "SUS wrong CALLID len %d", l
);
1452 if (!(skb
= l3_alloc_skb(l
)))
1454 memcpy(skb_put(skb
, l
), tmp
, l
);
1455 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1457 L3AddTimer(&pc
->timer
, T319
, CC_T319
);
1461 l3dss1_suspend_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
1463 struct sk_buff
*skb
= arg
;
1465 L3DelTimer(&pc
->timer
);
1468 pc
->para
.cause
= -1;
1469 pc
->st
->l3
.l3l4(pc
->st
, CC_SUSPEND
| CONFIRM
, pc
);
1470 release_l3_process(pc
);
1474 l3dss1_suspend_rej(struct l3_process
*pc
, u_char pr
, void *arg
)
1477 struct sk_buff
*skb
= arg
;
1480 L3DelTimer(&pc
->timer
);
1482 if ((p
= findie(p
, skb
->len
, IE_CAUSE
, 0))) {
1485 pc
->para
.loc
= *p
++;
1489 pc
->para
.cause
= cause
;
1490 pc
->st
->l3
.l3l4(pc
->st
, CC_SUSPEND_ERR
, pc
);
1495 l3dss1_resume_req(struct l3_process
*pc
, u_char pr
, void *arg
)
1497 struct sk_buff
*skb
;
1501 u_char
*msg
= pc
->para
.setup
.phone
;
1503 MsgHead(p
, pc
->callref
, MT_RESUME
);
1507 if (l
&& (l
<= 10)) { /* Max length 10 octets */
1509 for (i
= 0; i
< l
; i
++)
1512 l3_debug(pc
->st
, "RES wrong CALLID len %d", l
);
1516 if (!(skb
= l3_alloc_skb(l
)))
1518 memcpy(skb_put(skb
, l
), tmp
, l
);
1519 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1521 L3AddTimer(&pc
->timer
, T319
, CC_T319
);
1525 l3dss1_resume_ack(struct l3_process
*pc
, u_char pr
, void *arg
)
1528 struct sk_buff
*skb
= arg
;
1530 L3DelTimer(&pc
->timer
);
1532 if ((p
= findie(p
, skb
->len
, IE_CHANNEL_ID
, 0))) {
1533 pc
->para
.bchannel
= p
[2] & 0x3;
1534 if ((!pc
->para
.bchannel
) && (pc
->debug
& L3_DEB_WARN
))
1535 l3_debug(pc
->st
, "resume ack without bchannel");
1536 } else if (pc
->debug
& L3_DEB_WARN
)
1537 l3_debug(pc
->st
, "resume ack without bchannel");
1539 pc
->st
->l3
.l3l4(pc
->st
, CC_RESUME
| CONFIRM
, pc
);
1544 l3dss1_resume_rej(struct l3_process
*pc
, u_char pr
, void *arg
)
1547 struct sk_buff
*skb
= arg
;
1550 L3DelTimer(&pc
->timer
);
1552 if ((p
= findie(p
, skb
->len
, IE_CAUSE
, 0))) {
1555 pc
->para
.loc
= *p
++;
1559 pc
->para
.cause
= cause
;
1561 pc
->st
->l3
.l3l4(pc
->st
, CC_RESUME_ERR
, pc
);
1562 release_l3_process(pc
);
1566 l3dss1_global_restart(struct l3_process
*pc
, u_char pr
, void *arg
)
1570 u_char ri
, ch
= 0, chan
= 0;
1572 struct sk_buff
*skb
= arg
;
1573 struct l3_process
*up
;
1576 L3DelTimer(&pc
->timer
);
1578 if ((p
= findie(p
, skb
->len
, IE_RESTART_IND
, 0))) {
1580 l3_debug(pc
->st
, "Restart %x", ri
);
1582 l3_debug(pc
->st
, "Restart without restart IE");
1586 if ((p
= findie(p
, skb
->len
, IE_CHANNEL_ID
, 0))) {
1589 if (pc
->st
->l3
.debug
)
1590 l3_debug(pc
->st
, "Restart for channel %d", chan
);
1594 up
= pc
->st
->l3
.proc
;
1597 up
->st
->lli
.l4l3(up
->st
, CC_RESTART
| REQUEST
, up
);
1598 else if (up
->para
.bchannel
== chan
)
1599 up
->st
->lli
.l4l3(up
->st
, CC_RESTART
| REQUEST
, up
);
1603 MsgHead(p
, pc
->callref
, MT_RESTART_ACKNOWLEDGE
);
1605 *p
++ = IE_CHANNEL_ID
;
1609 *p
++ = 0x79; /* RESTART Ind */
1613 if (!(skb
= l3_alloc_skb(l
)))
1615 memcpy(skb_put(skb
, l
), tmp
, l
);
1617 l3_msg(pc
->st
, DL_DATA
| REQUEST
, skb
);
1620 static struct stateentry downstatelist
[] =
1623 CC_SETUP
| REQUEST
, l3dss1_setup_req
},
1625 CC_RESUME
| REQUEST
, l3dss1_resume_req
},
1626 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(10),
1627 CC_DISCONNECT
| REQUEST
, l3dss1_disconnect_req
},
1629 CC_RELEASE
| REQUEST
, l3dss1_release_req
},
1631 CC_DLRL
| REQUEST
, l3dss1_reset
},
1633 CC_RESTART
| REQUEST
, l3dss1_restart
},
1635 CC_IGNORE
| REQUEST
, l3dss1_reset
},
1637 CC_REJECT
| REQUEST
, l3dss1_reject_req
},
1639 CC_ALERTING
| REQUEST
, l3dss1_alert_req
},
1641 CC_SETUP
| RESPONSE
, l3dss1_setup_rsp
},
1643 CC_SUSPEND
| REQUEST
, l3dss1_suspend_req
},
1645 CC_T303
, l3dss1_t303
},
1647 CC_T304
, l3dss1_t304
},
1649 CC_T310
, l3dss1_t310
},
1651 CC_T313
, l3dss1_t313
},
1653 CC_T305
, l3dss1_t305
},
1655 CC_T319
, l3dss1_t319
},
1657 CC_T318
, l3dss1_t318
},
1659 CC_T308_1
, l3dss1_t308_1
},
1661 CC_T308_2
, l3dss1_t308_2
},
1665 (sizeof(downstatelist) / sizeof(struct stateentry))
1667 static struct stateentry datastatelist
[] =
1670 MT_STATUS_ENQUIRY
, l3dss1_status_enq
},
1672 MT_FACILITY
, l3dss1_facility
},
1674 MT_STATUS
, l3dss1_release_ind
},
1676 MT_STATUS
, l3dss1_status
},
1678 MT_SETUP
, l3dss1_setup
},
1680 MT_CALL_PROCEEDING
, l3dss1_call_proc
},
1681 {SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1682 MT_CALL_PROCEEDING
, l3dss1_status_req
},
1684 MT_SETUP_ACKNOWLEDGE
, l3dss1_setup_ack
},
1685 {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1686 MT_SETUP_ACKNOWLEDGE
, l3dss1_status_req
},
1687 {SBIT(1) | SBIT(2) | SBIT(3),
1688 MT_ALERTING
, l3dss1_alerting
},
1689 {SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1690 MT_ALERTING
, l3dss1_status_req
},
1691 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
1692 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
1693 MT_RELEASE_COMPLETE
, l3dss1_release_cmpl
},
1694 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
1695 SBIT(11) | SBIT(12) | SBIT(15) /* | SBIT(17) | SBIT(19)*/,
1696 MT_RELEASE
, l3dss1_release
},
1697 {SBIT(19), MT_RELEASE
, l3dss1_release_ind
},
1698 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | SBIT(15),
1699 MT_DISCONNECT
, l3dss1_disconnect
},
1701 MT_DISCONNECT
, l3dss1_release_req
},
1702 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4),
1703 MT_CONNECT
, l3dss1_connect
},
1704 {SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1705 MT_CONNECT
, l3dss1_status_req
},
1706 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(11) | SBIT(19),
1707 MT_CONNECT_ACKNOWLEDGE
, l3dss1_status_req
},
1709 MT_CONNECT_ACKNOWLEDGE
, l3dss1_connect_ack
},
1711 MT_SUSPEND_ACKNOWLEDGE
, l3dss1_suspend_ack
},
1713 MT_SUSPEND_REJECT
, l3dss1_suspend_rej
},
1715 MT_RESUME_ACKNOWLEDGE
, l3dss1_resume_ack
},
1717 MT_RESUME_REJECT
, l3dss1_resume_rej
},
1718 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(19),
1719 MT_INVALID
, l3dss1_status_req
},
1723 (sizeof(datastatelist) / sizeof(struct stateentry))
1725 static struct stateentry globalmes_list
[] =
1728 MT_STATUS
, l3dss1_status
},
1730 MT_RESTART
, l3dss1_global_restart
},
1732 MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
1735 #define GLOBALM_LEN \
1736 (sizeof(globalmes_list) / sizeof(struct stateentry))
1741 global_handler(struct PStack
*st
, int mt
, struct sk_buff
*skb
)
1744 struct l3_process
*proc
= st
->l3
.global
;
1746 for (i
= 0; i
< GLOBALM_LEN
; i
++)
1747 if ((mt
== globalmes_list
[i
].primitive
) &&
1748 ((1 << proc
->state
) & globalmes_list
[i
].state
))
1750 if (i
== GLOBALM_LEN
) {
1752 if (st
->l3
.debug
& L3_DEB_STATE
) {
1753 l3_debug(st
, "dss1 global state %d mt %x unhandled",
1758 if (st
->l3
.debug
& L3_DEB_STATE
) {
1759 l3_debug(st
, "dss1 global %d mt %x",
1762 globalmes_list
[i
].rout(proc
, mt
, skb
);
1767 dss1up(struct PStack
*st
, int pr
, void *arg
)
1769 int i
, mt
, cr
, cause
, callState
;
1771 struct sk_buff
*skb
= arg
;
1772 struct l3_process
*proc
;
1775 case (DL_DATA
| INDICATION
):
1776 case (DL_UNIT_DATA
| INDICATION
):
1778 case (DL_ESTABLISH
| CONFIRM
):
1779 case (DL_ESTABLISH
| INDICATION
):
1780 case (DL_RELEASE
| INDICATION
):
1781 case (DL_RELEASE
| CONFIRM
):
1782 l3_msg(st
, pr
, arg
);
1786 if (skb
->data
[0] != PROTO_DIS_EURO
) {
1787 if (st
->l3
.debug
& L3_DEB_PROTERR
) {
1788 l3_debug(st
, "dss1up%sunexpected discriminator %x message len %d",
1789 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
1790 skb
->data
[0], skb
->len
);
1795 cr
= getcallref(skb
->data
);
1796 mt
= skb
->data
[skb
->data
[1] + 2];
1797 if (!cr
) { /* Global CallRef */
1798 global_handler(st
, mt
, skb
);
1800 } else if (cr
== -1) { /* Dummy Callref */
1803 } else if (!(proc
= getl3proc(st
, cr
))) {
1804 /* No transaction process exist, that means no call with
1805 * this callreference is active
1807 if (mt
== MT_SETUP
) {
1808 /* Setup creates a new transaction process */
1809 if (!(proc
= new_l3_process(st
, cr
))) {
1810 /* May be to answer with RELEASE_COMPLETE and
1811 * CAUSE 0x2f "Resource unavailable", but this
1812 * need a new_l3_process too ... arghh
1817 } else if (mt
== MT_STATUS
) {
1819 if ((ptr
= findie(skb
->data
, skb
->len
, IE_CAUSE
, 0)) != NULL
) {
1823 cause
= *ptr
& 0x7f;
1826 if ((ptr
= findie(skb
->data
, skb
->len
, IE_CALL_STATE
, 0)) != NULL
) {
1832 if (callState
== 0) {
1833 /* ETS 300-104 part 2.4.1
1834 * if setup has not been made and a message type
1835 * MT_STATUS is received with call state == 0,
1836 * we must send nothing
1841 /* ETS 300-104 part 2.4.2
1842 * if setup has not been made and a message type
1843 * MT_STATUS is received with call state != 0,
1844 * we must send MT_RELEASE_COMPLETE cause 101
1847 if ((proc
= new_l3_process(st
, cr
))) {
1848 proc
->para
.cause
= 0x65; /* 101 */
1849 l3dss1_msg_without_setup(proc
, 0, NULL
);
1853 } else if (mt
== MT_RELEASE_COMPLETE
) {
1857 /* ETS 300-104 part 2
1858 * if setup has not been made and a message type
1859 * (except MT_SETUP and RELEASE_COMPLETE) is received,
1860 * we must send MT_RELEASE_COMPLETE cause 81 */
1862 if ((proc
= new_l3_process(st
, cr
))) {
1863 proc
->para
.cause
= 0x51; /* 81 */
1864 l3dss1_msg_without_setup(proc
, 0, NULL
);
1868 } else if (!l3dss1_check_messagetype_validity(mt
)) {
1869 /* ETS 300-104 7.4.2, 8.4.2, 10.3.2, 11.4.2, 12.4.2, 13.4.2,
1871 * if setup has been made and invalid message type is received,
1872 * we must send MT_STATUS cause 0x62
1874 mt
= MT_INVALID
; /* sorry, not clean, but do the right thing ;-) */
1876 for (i
= 0; i
< DATASLLEN
; i
++)
1877 if ((mt
== datastatelist
[i
].primitive
) &&
1878 ((1 << proc
->state
) & datastatelist
[i
].state
))
1880 if (i
== DATASLLEN
) {
1882 if (st
->l3
.debug
& L3_DEB_STATE
) {
1883 l3_debug(st
, "dss1up%sstate %d mt %x unhandled",
1884 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
1889 if (st
->l3
.debug
& L3_DEB_STATE
) {
1890 l3_debug(st
, "dss1up%sstate %d mt %x",
1891 (pr
== (DL_DATA
| INDICATION
)) ? " " : "(broadcast) ",
1894 datastatelist
[i
].rout(proc
, pr
, skb
);
1899 dss1down(struct PStack
*st
, int pr
, void *arg
)
1902 struct l3_process
*proc
;
1903 struct Channel
*chan
;
1905 if (((DL_ESTABLISH
| REQUEST
) == pr
) || ((DL_RELEASE
| REQUEST
) == pr
)) {
1906 l3_msg(st
, pr
, NULL
);
1908 } else if (((CC_SETUP
| REQUEST
) == pr
) || ((CC_RESUME
| REQUEST
) == pr
)) {
1912 if ((proc
= new_l3_process(st
, cr
))) {
1915 proc
->para
.setup
= chan
->setup
;
1922 printk(KERN_ERR
"HiSax dss1down without proc pr=%04x\n", pr
);
1925 for (i
= 0; i
< DOWNSLLEN
; i
++)
1926 if ((pr
== downstatelist
[i
].primitive
) &&
1927 ((1 << proc
->state
) & downstatelist
[i
].state
))
1929 if (i
== DOWNSLLEN
) {
1930 if (st
->l3
.debug
& L3_DEB_STATE
) {
1931 l3_debug(st
, "dss1down state %d prim %d unhandled",
1935 if (st
->l3
.debug
& L3_DEB_STATE
) {
1936 l3_debug(st
, "dss1down state %d prim %d",
1939 downstatelist
[i
].rout(proc
, pr
, arg
);
1944 setstack_dss1(struct PStack
*st
)
1948 st
->lli
.l4l3
= dss1down
;
1949 st
->l2
.l2l3
= dss1up
;
1951 if (!(st
->l3
.global
= kmalloc(sizeof(struct l3_process
), GFP_ATOMIC
))) {
1952 printk(KERN_ERR
"HiSax can't get memory for dss1 global CR\n");
1954 st
->l3
.global
->state
= 0;
1955 st
->l3
.global
->callref
= 0;
1956 st
->l3
.global
->next
= NULL
;
1957 st
->l3
.global
->debug
= L3_DEB_WARN
;
1958 st
->l3
.global
->st
= st
;
1959 st
->l3
.global
->N303
= 1;
1960 L3InitTimer(st
->l3
.global
, &st
->l3
.global
->timer
);
1962 strcpy(tmp
, dss1_revision
);
1963 printk(KERN_INFO
"HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp
));