1 /* $Id: q931.c,v 1.7 1998/11/15 23:55:17 keil Exp $
3 * q931.c code to decode ITU Q.931 call control messages
9 * Pauline Middelink general improvements
11 * Beat Doebeli cause texts, display information element
13 * Karsten Keil cause texts, display information element for 1TR6
17 * Revision 1.7 1998/11/15 23:55:17 keil
20 * Revision 1.6 1997/07/27 21:09:44 keil
21 * move functions to isdnl3.c
23 * Revision 1.5 1997/04/06 22:56:43 keil
24 * Some cosmetic changes
26 * Revision 1.4 1997/02/09 00:29:11 keil
27 * new interface handling, one interface per card
29 * Revision 1.3 1997/01/21 22:24:59 keil
32 * Revision 1.2 1996/10/27 22:12:45 keil
33 * reporting unknown level 3 protocol ids
35 * Revision 1.1 1996/10/13 20:04:56 keil
42 #define __NO_VERSION__
47 iecpy(u_char
* dest
, u_char
* iestart
, int ieoffset
)
52 p
= iestart
+ ieoffset
+ 2;
53 l
= iestart
[1] - ieoffset
;
60 * According to Table 4-2/Q.931
72 0x2, "CALL PROCEEDING"
78 0xf, "CONNECT ACKNOWLEDGE"
87 0xd, "SETUP ACKNOWLEDGE"
93 0x2e, "RESUME ACKNOWLEDGE"
102 0x2d, "SUSPEND ACKNOWLEDGE"
105 0x21, "SUSPEND REJECT"
108 0x20, "USER INFORMATION"
117 0x5a, "RELEASE COMPLETE"
123 0x4e, "RESTART ACKNOWLEDGE"
129 0x79, "CONGESTION CONTROL"
144 0x75, "STATUS ENQUIRY"
148 #define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
151 struct MessageType mt_n0
[] =
153 {MT_N0_REG_IND
, "REGister INDication"},
154 {MT_N0_CANC_IND
, "CANCel INDication"},
155 {MT_N0_FAC_STA
, "FACility STAtus"},
156 {MT_N0_STA_ACK
, "STAtus ACKnowledge"},
157 {MT_N0_STA_REJ
, "STAtus REJect"},
158 {MT_N0_FAC_INF
, "FACility INFormation"},
159 {MT_N0_INF_ACK
, "INFormation ACKnowledge"},
160 {MT_N0_INF_REJ
, "INFormation REJect"},
161 {MT_N0_CLOSE
, "CLOSE"},
162 {MT_N0_CLO_ACK
, "CLOse ACKnowledge"}
165 #define MT_N0_LEN (sizeof(mt_n0) / sizeof(struct MessageType))
168 struct MessageType mt_n1
[] =
170 {MT_N1_ESC
, "ESCape"},
171 {MT_N1_ALERT
, "ALERT"},
172 {MT_N1_CALL_SENT
, "CALL SENT"},
173 {MT_N1_CONN
, "CONNect"},
174 {MT_N1_CONN_ACK
, "CONNect ACKnowledge"},
175 {MT_N1_SETUP
, "SETUP"},
176 {MT_N1_SETUP_ACK
, "SETUP ACKnowledge"},
177 {MT_N1_RES
, "RESume"},
178 {MT_N1_RES_ACK
, "RESume ACKnowledge"},
179 {MT_N1_RES_REJ
, "RESume REJect"},
180 {MT_N1_SUSP
, "SUSPend"},
181 {MT_N1_SUSP_ACK
, "SUSPend ACKnowledge"},
182 {MT_N1_SUSP_REJ
, "SUSPend REJect"},
183 {MT_N1_USER_INFO
, "USER INFO"},
184 {MT_N1_DET
, "DETach"},
185 {MT_N1_DISC
, "DISConnect"},
186 {MT_N1_REL
, "RELease"},
187 {MT_N1_REL_ACK
, "RELease ACKnowledge"},
188 {MT_N1_CANC_ACK
, "CANCel ACKnowledge"},
189 {MT_N1_CANC_REJ
, "CANCel REJect"},
190 {MT_N1_CON_CON
, "CONgestion CONtrol"},
191 {MT_N1_FAC
, "FACility"},
192 {MT_N1_FAC_ACK
, "FACility ACKnowledge"},
193 {MT_N1_FAC_CAN
, "FACility CANcel"},
194 {MT_N1_FAC_REG
, "FACility REGister"},
195 {MT_N1_FAC_REJ
, "FACility REJect"},
196 {MT_N1_INFO
, "INFOrmation"},
197 {MT_N1_REG_ACK
, "REGister ACKnowledge"},
198 {MT_N1_REG_REJ
, "REGister REJect"},
199 {MT_N1_STAT
, "STATus"}
202 #define MT_N1_LEN (sizeof(mt_n1) / sizeof(struct MessageType))
204 static struct MessageType fac_1tr6
[] =
206 {FAC_Sperre
, "Sperre"},
207 {FAC_Forward1
, "Forward 1"},
208 {FAC_Forward2
, "Forward 2"},
209 {FAC_Konferenz
, "Konferenz"},
210 {FAC_GrabBchan
, "Grab Bchannel"},
211 {FAC_Reactivate
, "Reactivate"},
212 {FAC_Konferenz3
, "Dreier Konferenz"},
213 {FAC_Dienstwechsel1
, "Einseitiger Dienstwechsel"},
214 {FAC_Dienstwechsel2
, "Zweiseitiger Dienstwechsel"},
215 {FAC_NummernIdent
, "Rufnummer-Identifizierung"},
217 {FAC_DisplayUebergeben
, "Display Uebergeben"},
218 {FAC_DisplayUmgeleitet
, "Display Umgeleitet"},
219 {FAC_Unterdruecke
, "Unterdruecke Rufnummer"},
220 {FAC_Deactivate
, "Deactivate"},
221 {FAC_Activate
, "Activate"},
223 {FAC_Rueckwechsel
, "Rueckwechsel"},
224 {FAC_Umleitung
, "Umleitung"}
226 #define FAC_1TR6_LEN (sizeof(fac_1tr6) / sizeof(struct MessageType))
229 prbits(char *dest
, u_char b
, int start
, int len
)
233 b
= b
<< (8 - start
);
248 while (!(*p
++ & 0x80));
253 * Cause Values According to Q.850
254 * edescr: English description
255 * ddescr: German description used by Swissnet II (Swiss Telecom
267 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
270 0x02, "No route to specified transit network", ""
273 0x03, "No route to destination", ""
276 0x04, "Send special information tone", ""
279 0x05, "Misdialled trunk prefix", ""
282 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
285 0x07, "Channel awarded and being delivered in an established channel", ""
288 0x08, "Preemption", ""
291 0x09, "Preemption - circuit reserved for reuse", ""
294 0x10, "Normal call clearing", "Normale Ausloesung"
297 0x11, "User busy", "TNB besetzt"
300 0x12, "No user responding", ""
303 0x13, "No answer from user (user alerted)", ""
306 0x14, "Subscriber absent", ""
309 0x15, "Call rejected", ""
312 0x16, "Number changed", ""
315 0x1a, "non-selected user clearing", ""
318 0x1b, "Destination out of order", ""
321 0x1c, "Invalid number format (address incomplete)", ""
324 0x1d, "Facility rejected", ""
327 0x1e, "Response to Status enquiry", ""
330 0x1f, "Normal, unspecified", ""
333 0x22, "No circuit/channel available", ""
336 0x26, "Network out of order", ""
339 0x27, "Permanent frame mode connection out-of-service", ""
342 0x28, "Permanent frame mode connection operational", ""
345 0x29, "Temporary failure", ""
348 0x2a, "Switching equipment congestion", ""
351 0x2b, "Access information discarded", ""
354 0x2c, "Requested circuit/channel not available", ""
357 0x2e, "Precedence call blocked", ""
360 0x2f, "Resource unavailable, unspecified", ""
363 0x31, "Quality of service unavailable", ""
366 0x32, "Requested facility not subscribed", ""
369 0x35, "Outgoing calls barred within CUG", ""
372 0x37, "Incoming calls barred within CUG", ""
375 0x39, "Bearer capability not authorized", ""
378 0x3a, "Bearer capability not presently available", ""
381 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
384 0x3f, "Service or option not available, unspecified", ""
387 0x41, "Bearer capability not implemented", ""
390 0x42, "Channel type not implemented", ""
393 0x43, "Requested facility not implemented", ""
396 0x44, "Only restricted digital information bearer capability is available", ""
399 0x4f, "Service or option not implemented", ""
402 0x51, "Invalid call reference value", ""
405 0x52, "Identified channel does not exist", ""
408 0x53, "A suspended call exists, but this call identity does not", ""
411 0x54, "Call identity in use", ""
414 0x55, "No call suspended", ""
417 0x56, "Call having the requested call identity has been cleared", ""
420 0x57, "User not member of CUG", ""
423 0x58, "Incompatible destination", ""
426 0x5a, "Non-existent CUG", ""
429 0x5b, "Invalid transit network selection", ""
432 0x5f, "Invalid message, unspecified", ""
435 0x60, "Mandatory information element is missing", ""
438 0x61, "Message type non-existent or not implemented", ""
441 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
444 0x63, "Information element/parameter non-existent or not implemented", ""
447 0x64, "Invalid information element contents", ""
450 0x65, "Message not compatible with call state", ""
453 0x66, "Recovery on timer expiry", ""
456 0x67, "Parameter non-existent or not implemented - passed on", ""
459 0x6e, "Message with unrecognized parameter discarded", ""
462 0x6f, "Protocol error, unspecified", ""
465 0x7f, "Interworking, unspecified", ""
469 #define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
473 prcause(char *dest
, u_char
* p
)
481 dp
+= sprintf(dp
, " coding ");
482 dp
+= prbits(dp
, *p
, 7, 2);
483 dp
+= sprintf(dp
, " location ");
484 dp
+= prbits(dp
, *p
, 4, 4);
490 /* locate cause value */
491 for (i
= 0; i
< CVSIZE
; i
++)
492 if (cvlist
[i
].nr
== cause
)
495 /* display cause value if it exists */
497 dp
+= sprintf(dp
, "Unknown cause type %x!\n", cause
);
499 dp
+= sprintf(dp
, " cause value %x : %s \n", cause
, cvlist
[i
].edescr
);
504 dp
+= sprintf(dp
, " diag attribute %d ", *p
++ & 0x7f);
505 dp
+= sprintf(dp
, " rej %d ", *p
& 0x7f);
510 dp
+= sprintf(dp
, " av %d\n", (*++p
) & 0x7f);
517 struct MessageType cause_1tr6
[] =
519 {CAUSE_InvCRef
, "Invalid Call Reference"},
520 {CAUSE_BearerNotImpl
, "Bearer Service Not Implemented"},
521 {CAUSE_CIDunknown
, "Caller Identity unknown"},
522 {CAUSE_CIDinUse
, "Caller Identity in Use"},
523 {CAUSE_NoChans
, "No Channels available"},
524 {CAUSE_FacNotImpl
, "Facility Not Implemented"},
525 {CAUSE_FacNotSubscr
, "Facility Not Subscribed"},
526 {CAUSE_OutgoingBarred
, "Outgoing calls barred"},
527 {CAUSE_UserAccessBusy
, "User Access Busy"},
528 {CAUSE_NegativeGBG
, "Negative GBG"},
529 {CAUSE_UnknownGBG
, "Unknown GBG"},
530 {CAUSE_NoSPVknown
, "No SPV known"},
531 {CAUSE_DestNotObtain
, "Destination not obtainable"},
532 {CAUSE_NumberChanged
, "Number changed"},
533 {CAUSE_OutOfOrder
, "Out Of Order"},
534 {CAUSE_NoUserResponse
, "No User Response"},
535 {CAUSE_UserBusy
, "User Busy"},
536 {CAUSE_IncomingBarred
, "Incoming Barred"},
537 {CAUSE_CallRejected
, "Call Rejected"},
538 {CAUSE_NetworkCongestion
, "Network Congestion"},
539 {CAUSE_RemoteUser
, "Remote User initiated"},
540 {CAUSE_LocalProcErr
, "Local Procedure Error"},
541 {CAUSE_RemoteProcErr
, "Remote Procedure Error"},
542 {CAUSE_RemoteUserSuspend
, "Remote User Suspend"},
543 {CAUSE_RemoteUserResumed
, "Remote User Resumed"},
544 {CAUSE_UserInfoDiscarded
, "User Info Discarded"}
547 int cause_1tr6_len
= (sizeof(cause_1tr6
) / sizeof(struct MessageType
));
550 prcause_1tr6(char *dest
, u_char
* p
)
557 dp
+= sprintf(dp
, " OK (cause length=0)\n");
560 dp
+= sprintf(dp
, " coding ");
561 dp
+= prbits(dp
, p
[2], 7, 2);
562 dp
+= sprintf(dp
, " location ");
563 dp
+= prbits(dp
, p
[2], 4, 4);
569 /* locate cause value */
570 for (i
= 0; i
< cause_1tr6_len
; i
++)
571 if (cause_1tr6
[i
].nr
== cause
)
574 /* display cause value if it exists */
575 if (i
== cause_1tr6_len
)
576 dp
+= sprintf(dp
, "Unknown cause type %x!\n", cause
);
578 dp
+= sprintf(dp
, " cause value %x : %s \n", cause
, cause_1tr6
[i
].descr
);
585 prchident(char *dest
, u_char
* p
)
590 dp
+= sprintf(dp
, " octet 3 ");
591 dp
+= prbits(dp
, *p
, 8, 8);
597 prcalled(char *dest
, u_char
* p
)
604 dp
+= sprintf(dp
, " octet 3 ");
605 dp
+= prbits(dp
, *p
++, 8, 8);
607 dp
+= sprintf(dp
, " number digits ");
614 prcalling(char *dest
, u_char
* p
)
621 dp
+= sprintf(dp
, " octet 3 ");
622 dp
+= prbits(dp
, *p
, 8, 8);
625 dp
+= sprintf(dp
, " octet 3a ");
626 dp
+= prbits(dp
, *++p
, 8, 8);
632 dp
+= sprintf(dp
, " number digits ");
641 prbearer(char *dest
, u_char
* p
)
646 dp
+= sprintf(dp
, " octet 3 ");
647 dp
+= prbits(dp
, *p
++, 8, 8);
649 dp
+= sprintf(dp
, " octet 4 ");
650 dp
+= prbits(dp
, *p
, 8, 8);
652 if ((*p
++ & 0x1f) == 0x18) {
653 dp
+= sprintf(dp
, " octet 4.1 ");
654 dp
+= prbits(dp
, *p
++, 8, 8);
657 /* check for user information layer 1 */
658 if ((*p
& 0x60) == 0x20) {
661 dp
+= sprintf(dp
, " octet 5%c ", ch
);
662 dp
+= prbits(dp
, *p
, 8, 8);
669 while (!(*p
++ & 0x80));
671 /* check for user information layer 2 */
672 if ((*p
& 0x60) == 0x40) {
673 dp
+= sprintf(dp
, " octet 6 ");
674 dp
+= prbits(dp
, *p
++, 8, 8);
677 /* check for user information layer 3 */
678 if ((*p
& 0x60) == 0x60) {
679 dp
+= sprintf(dp
, " octet 7 ");
680 dp
+= prbits(dp
, *p
++, 8, 8);
687 general(char *dest
, u_char
* p
)
695 /* Iterate over all octets in the information element */
697 dp
+= sprintf(dp
, " octet %d%c ", octet
, ch
);
698 dp
+= prbits(dp
, *p
++, 8, 8);
701 /* last octet in group? */
705 } else if (ch
== ' ')
714 prcharge(char *dest
, u_char
* p
)
721 dp
+= sprintf(dp
, " GEA ");
722 dp
+= prbits(dp
, *p
++, 8, 8);
723 dp
+= sprintf(dp
, " Anzahl: ");
724 /* Iterate over all octets in the * information element */
731 prtext(char *dest
, u_char
* p
)
738 dp
+= sprintf(dp
, " ");
739 /* Iterate over all octets in the * information element */
746 display(char *dest
, u_char
* p
)
754 /* Iterate over all octets in the * display-information element */
755 dp
+= sprintf(dp
, " \"");
757 dp
+= sprintf(dp
, "%c", *p
++);
759 /* last octet in group? */
763 } else if (ch
== ' ')
775 prfacility(char *dest
, u_char
* p
)
782 dp
+= sprintf(dp
, " octet 3 ");
783 dp
+= prbits(dp
, *p
++, 8, 8);
784 dp
+= sprintf(dp
, "\n");
788 dp
+= sprintf(dp
, " octet 4 ");
789 dp
+= prbits(dp
, *p
++, 8, 8);
790 dp
+= sprintf(dp
, "\n");
791 dp
+= sprintf(dp
, " octet 5 %d\n", l2
= *p
++ & 0x7f);
793 dp
+= sprintf(dp
, " contents ");
795 dp
+= sprintf(dp
, "%2x ", *p
++);
798 dp
+= sprintf(dp
, "\n");
805 struct InformationElement
{
808 int (*f
) (char *, u_char
*);
812 0x00, "Segmented message", general
815 0x04, "Bearer capability", prbearer
818 0x08, "Cause", prcause
821 0x10, "Call identity", general
824 0x14, "Call state", general
827 0x18, "Channel identification", prchident
830 0x1c, "Facility", prfacility
833 0x1e, "Progress indicator", general
836 0x20, "Network-specific facilities", general
839 0x27, "Notification indicator", general
842 0x28, "Display", display
845 0x29, "Date/Time", general
848 0x2c, "Keypad facility", general
851 0x34, "Signal", general
854 0x40, "Information rate", general
857 0x42, "End-to-end delay", general
860 0x43, "Transit delay selection and indication", general
863 0x44, "Packet layer binary parameters", general
866 0x45, "Packet layer window size", general
869 0x46, "Packet size", general
872 0x47, "Closed user group", general
875 0x4a, "Reverse charge indication", general
878 0x6c, "Calling party number", prcalling
881 0x6d, "Calling party subaddress", general
884 0x70, "Called party number", prcalled
887 0x71, "Called party subaddress", general
890 0x74, "Redirecting number", general
893 0x78, "Transit network selection", general
896 0x79, "Restart indicator", general
899 0x7c, "Low layer compatibility", general
902 0x7d, "High layer compatibility", general
905 0x7e, "User-user", general
908 0x7f, "Escape for extension", general
913 #define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
915 static struct InformationElement we_0
[] =
917 {WE0_cause
, "Cause", prcause_1tr6
},
918 {WE0_connAddr
, "Connecting Address", prcalled
},
919 {WE0_callID
, "Call IDentity", general
},
920 {WE0_chanID
, "Channel IDentity", general
},
921 {WE0_netSpecFac
, "Network Specific Facility", general
},
922 {WE0_display
, "Display", general
},
923 {WE0_keypad
, "Keypad", general
},
924 {WE0_origAddr
, "Origination Address", prcalled
},
925 {WE0_destAddr
, "Destination Address", prcalled
},
926 {WE0_userInfo
, "User Info", general
}
929 #define WE_0_LEN (sizeof(we_0) / sizeof(struct InformationElement))
931 static struct InformationElement we_6
[] =
933 {WE6_serviceInd
, "Service Indicator", general
},
934 {WE6_chargingInfo
, "Charging Information", prcharge
},
935 {WE6_date
, "Date", prtext
},
936 {WE6_facSelect
, "Facility Select", general
},
937 {WE6_facStatus
, "Facility Status", general
},
938 {WE6_statusCalled
, "Status Called", general
},
939 {WE6_addTransAttr
, "Additional Transmission Attributes", general
}
941 #define WE_6_LEN (sizeof(we_6) / sizeof(struct InformationElement))
944 QuickHex(char *txt
, u_char
* p
, int cnt
)
947 register char *t
= txt
;
950 for (i
= 0; i
< cnt
; i
++) {
952 w
= (p
[i
] >> 4) & 0x0f;
968 LogFrame(struct IsdnCardState
*cs
, u_char
* buf
, int size
)
975 if (size
< MAX_DLOG_SPACE
/ 3 - 10) {
980 dp
+= QuickHex(dp
, buf
, size
);
984 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
986 HiSax_putstatus(cs
, "LogFrame: ", "warning Frame too big (%d)", size
);
990 dlogframe(struct IsdnCardState
*cs
, struct sk_buff
*skb
, int dir
)
994 unsigned char pd
, cr_l
, cr
, mt
;
995 unsigned char sapi
, tei
, ftyp
;
996 int i
, cset
= 0, cs_old
= 0, cs_fest
= 0;
997 int size
, finish
= 0;
1001 /* display header */
1003 dp
+= jiftime(dp
, jiffies
);
1005 sapi
= skb
->data
[0] >> 2;
1006 tei
= skb
->data
[1] >> 1;
1007 ftyp
= skb
->data
[2];
1009 dp
+= sprintf(dp
, "frame %s ", dir
? "network->user" : "user->network");
1012 if (tei
== GROUP_TEI
) {
1013 if (sapi
== CTRL_SAPI
) { /* sapi 0 */
1015 dp
+= sprintf(dp
, "broadcast\n");
1019 dp
+= sprintf(dp
, "no UI broadcast\n");
1022 } else if (sapi
== TEI_SAPI
) {
1023 dp
+= sprintf(dp
, "tei managment\n");
1026 dp
+= sprintf(dp
, "unknown sapi %d broadcast\n", sapi
);
1030 if (sapi
== CTRL_SAPI
) {
1031 if (!(ftyp
& 1)) { /* IFrame */
1032 dp
+= sprintf(dp
, "with tei %d\n", tei
);
1036 dp
+= sprintf(dp
, "SFrame with tei %d\n", tei
);
1040 dp
+= sprintf(dp
, "unknown sapi %d tei %d\n", sapi
, tei
);
1044 bend
= skb
->data
+ skb
->len
;
1046 dp
+= sprintf(dp
, "frame too short\n");
1051 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
1054 if ((0xfe & buf
[0]) == PROTO_DIS_N0
) { /* 1TR6 */
1055 /* locate message type */
1063 if (pd
== PROTO_DIS_N0
) { /* N0 */
1064 for (i
= 0; i
< MT_N0_LEN
; i
++)
1065 if (mt_n0
[i
].nr
== mt
)
1067 /* display message type if it exists */
1069 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type N0 %x!\n",
1070 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1073 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1074 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1075 size
, mt_n0
[i
].descr
);
1077 for (i
= 0; i
< MT_N1_LEN
; i
++)
1078 if (mt_n1
[i
].nr
== mt
)
1080 /* display message type if it exists */
1082 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type N1 %x!\n",
1083 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1086 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1087 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1088 size
, mt_n1
[i
].descr
);
1091 /* display each information element */
1092 while (buf
< bend
) {
1093 /* Is it a single octet information element? */
1095 switch ((*buf
>> 4) & 7) {
1097 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1103 dp
+= sprintf(dp
, " Congestion level %x\n", *buf
& 0xf);
1107 dp
+= sprintf(dp
, " More data\n");
1111 dp
+= sprintf(dp
, " Sending complete\n");
1116 dp
+= sprintf(dp
, " Reserved %x\n", *buf
);
1122 /* No, locate it in the table */
1124 for (i
= 0; i
< WE_0_LEN
; i
++)
1125 if (*buf
== we_0
[i
].nr
)
1128 /* When found, give appropriate msg */
1129 if (i
!= WE_0_LEN
) {
1130 dp
+= sprintf(dp
, " %s\n", we_0
[i
].descr
);
1131 dp
+= we_0
[i
].f(dp
, buf
);
1133 dp
+= sprintf(dp
, " Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1134 } else if (cset
== 6) {
1135 for (i
= 0; i
< WE_6_LEN
; i
++)
1136 if (*buf
== we_6
[i
].nr
)
1139 /* When found, give appropriate msg */
1140 if (i
!= WE_6_LEN
) {
1141 dp
+= sprintf(dp
, " %s\n", we_6
[i
].descr
);
1142 dp
+= we_6
[i
].f(dp
, buf
);
1144 dp
+= sprintf(dp
, " Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1146 dp
+= sprintf(dp
, " Unknown Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1147 /* Skip to next element */
1155 } else if (buf
[0] == 8) { /* EURO */
1156 /* locate message type */
1164 for (i
= 0; i
< MTSIZE
; i
++)
1165 if (mtlist
[i
].nr
== mt
)
1168 /* display message type if it exists */
1170 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type %x!\n",
1171 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1174 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1175 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1176 size
, mtlist
[i
].descr
);
1178 /* display each information element */
1179 while (buf
< bend
) {
1180 /* Is it a single octet information element? */
1182 switch ((*buf
>> 4) & 7) {
1184 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1187 dp
+= sprintf(dp
, " Congestion level %x\n", *buf
& 0xf);
1190 dp
+= sprintf(dp
, " Repeat indicator %x\n", *buf
& 0xf);
1194 dp
+= sprintf(dp
, " More data\n");
1198 dp
+= sprintf(dp
, " Sending complete\n");
1203 dp
+= sprintf(dp
, " Reserved %x\n", *buf
);
1209 /* No, locate it in the table */
1210 for (i
= 0; i
< IESIZE
; i
++)
1211 if (*buf
== ielist
[i
].nr
)
1214 /* When not found, give appropriate msg */
1216 dp
+= sprintf(dp
, " %s\n", ielist
[i
].descr
);
1217 dp
+= ielist
[i
].f(dp
, buf
);
1219 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1221 /* Skip to next element */
1225 dp
+= sprintf(dp
, "Unknown protocol %x!", buf
[0]);
1228 HiSax_putstatus(cs
, NULL
, cs
->dlog
);