1 /* $Id: q931.c,v 1.12.2.3 2004/01/13 14:31:26 keil Exp $
3 * code to decode ITU Q.931 call control messages
6 * Copyright by Jan den Ouden
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 * Pauline Middelink general improvements
14 * Beat Doebeli cause texts, display information element
15 * Karsten Keil cause texts, display information element for 1TR6
24 iecpy(u_char
* dest
, u_char
* iestart
, int ieoffset
)
29 p
= iestart
+ ieoffset
+ 2;
30 l
= iestart
[1] - ieoffset
;
37 * According to Table 4-2/Q.931
49 0x2, "CALL PROCEEDING"
55 0xf, "CONNECT ACKNOWLEDGE"
64 0xd, "SETUP ACKNOWLEDGE"
70 0x28, "HOLD ACKNOWLEDGE"
79 0x33, "RETRIEVE ACKNOWLEDGE"
82 0x37, "RETRIEVE REJECT"
88 0x2e, "RESUME ACKNOWLEDGE"
97 0x2d, "SUSPEND ACKNOWLEDGE"
100 0x21, "SUSPEND REJECT"
103 0x20, "USER INFORMATION"
112 0x5a, "RELEASE COMPLETE"
118 0x4e, "RESTART ACKNOWLEDGE"
124 0x79, "CONGESTION CONTROL"
139 0x75, "STATUS ENQUIRY"
143 #define MTSIZE ARRAY_SIZE(mtlist)
146 struct MessageType mt_n0
[] =
148 {MT_N0_REG_IND
, "REGister INDication"},
149 {MT_N0_CANC_IND
, "CANCel INDication"},
150 {MT_N0_FAC_STA
, "FACility STAtus"},
151 {MT_N0_STA_ACK
, "STAtus ACKnowledge"},
152 {MT_N0_STA_REJ
, "STAtus REJect"},
153 {MT_N0_FAC_INF
, "FACility INFormation"},
154 {MT_N0_INF_ACK
, "INFormation ACKnowledge"},
155 {MT_N0_INF_REJ
, "INFormation REJect"},
156 {MT_N0_CLOSE
, "CLOSE"},
157 {MT_N0_CLO_ACK
, "CLOse ACKnowledge"}
160 #define MT_N0_LEN ARRAY_SIZE(mt_n0)
163 struct MessageType mt_n1
[] =
165 {MT_N1_ESC
, "ESCape"},
166 {MT_N1_ALERT
, "ALERT"},
167 {MT_N1_CALL_SENT
, "CALL SENT"},
168 {MT_N1_CONN
, "CONNect"},
169 {MT_N1_CONN_ACK
, "CONNect ACKnowledge"},
170 {MT_N1_SETUP
, "SETUP"},
171 {MT_N1_SETUP_ACK
, "SETUP ACKnowledge"},
172 {MT_N1_RES
, "RESume"},
173 {MT_N1_RES_ACK
, "RESume ACKnowledge"},
174 {MT_N1_RES_REJ
, "RESume REJect"},
175 {MT_N1_SUSP
, "SUSPend"},
176 {MT_N1_SUSP_ACK
, "SUSPend ACKnowledge"},
177 {MT_N1_SUSP_REJ
, "SUSPend REJect"},
178 {MT_N1_USER_INFO
, "USER INFO"},
179 {MT_N1_DET
, "DETach"},
180 {MT_N1_DISC
, "DISConnect"},
181 {MT_N1_REL
, "RELease"},
182 {MT_N1_REL_ACK
, "RELease ACKnowledge"},
183 {MT_N1_CANC_ACK
, "CANCel ACKnowledge"},
184 {MT_N1_CANC_REJ
, "CANCel REJect"},
185 {MT_N1_CON_CON
, "CONgestion CONtrol"},
186 {MT_N1_FAC
, "FACility"},
187 {MT_N1_FAC_ACK
, "FACility ACKnowledge"},
188 {MT_N1_FAC_CAN
, "FACility CANcel"},
189 {MT_N1_FAC_REG
, "FACility REGister"},
190 {MT_N1_FAC_REJ
, "FACility REJect"},
191 {MT_N1_INFO
, "INFOrmation"},
192 {MT_N1_REG_ACK
, "REGister ACKnowledge"},
193 {MT_N1_REG_REJ
, "REGister REJect"},
194 {MT_N1_STAT
, "STATus"}
197 #define MT_N1_LEN ARRAY_SIZE(mt_n1)
201 prbits(char *dest
, u_char b
, int start
, int len
)
205 b
= b
<< (8 - start
);
220 while (!(*p
++ & 0x80));
225 * Cause Values According to Q.850
226 * edescr: English description
227 * ddescr: German description used by Swissnet II (Swiss Telecom
239 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
242 0x02, "No route to specified transit network", ""
245 0x03, "No route to destination", ""
248 0x04, "Send special information tone", ""
251 0x05, "Misdialled trunk prefix", ""
254 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
257 0x07, "Channel awarded and being delivered in an established channel", ""
260 0x08, "Preemption", ""
263 0x09, "Preemption - circuit reserved for reuse", ""
266 0x10, "Normal call clearing", "Normale Ausloesung"
269 0x11, "User busy", "TNB besetzt"
272 0x12, "No user responding", ""
275 0x13, "No answer from user (user alerted)", ""
278 0x14, "Subscriber absent", ""
281 0x15, "Call rejected", ""
284 0x16, "Number changed", ""
287 0x1a, "non-selected user clearing", ""
290 0x1b, "Destination out of order", ""
293 0x1c, "Invalid number format (address incomplete)", ""
296 0x1d, "Facility rejected", ""
299 0x1e, "Response to Status enquiry", ""
302 0x1f, "Normal, unspecified", ""
305 0x22, "No circuit/channel available", ""
308 0x26, "Network out of order", ""
311 0x27, "Permanent frame mode connection out-of-service", ""
314 0x28, "Permanent frame mode connection operational", ""
317 0x29, "Temporary failure", ""
320 0x2a, "Switching equipment congestion", ""
323 0x2b, "Access information discarded", ""
326 0x2c, "Requested circuit/channel not available", ""
329 0x2e, "Precedence call blocked", ""
332 0x2f, "Resource unavailable, unspecified", ""
335 0x31, "Quality of service unavailable", ""
338 0x32, "Requested facility not subscribed", ""
341 0x35, "Outgoing calls barred within CUG", ""
344 0x37, "Incoming calls barred within CUG", ""
347 0x39, "Bearer capability not authorized", ""
350 0x3a, "Bearer capability not presently available", ""
353 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
356 0x3f, "Service or option not available, unspecified", ""
359 0x41, "Bearer capability not implemented", ""
362 0x42, "Channel type not implemented", ""
365 0x43, "Requested facility not implemented", ""
368 0x44, "Only restricted digital information bearer capability is available", ""
371 0x4f, "Service or option not implemented", ""
374 0x51, "Invalid call reference value", ""
377 0x52, "Identified channel does not exist", ""
380 0x53, "A suspended call exists, but this call identity does not", ""
383 0x54, "Call identity in use", ""
386 0x55, "No call suspended", ""
389 0x56, "Call having the requested call identity has been cleared", ""
392 0x57, "User not member of CUG", ""
395 0x58, "Incompatible destination", ""
398 0x5a, "Non-existent CUG", ""
401 0x5b, "Invalid transit network selection", ""
404 0x5f, "Invalid message, unspecified", ""
407 0x60, "Mandatory information element is missing", ""
410 0x61, "Message type non-existent or not implemented", ""
413 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
416 0x63, "Information element/parameter non-existent or not implemented", ""
419 0x64, "Invalid information element contents", ""
422 0x65, "Message not compatible with call state", ""
425 0x66, "Recovery on timer expiry", ""
428 0x67, "Parameter non-existent or not implemented - passed on", ""
431 0x6e, "Message with unrecognized parameter discarded", ""
434 0x6f, "Protocol error, unspecified", ""
437 0x7f, "Interworking, unspecified", ""
441 #define CVSIZE ARRAY_SIZE(cvlist)
445 prcause(char *dest
, u_char
* p
)
453 dp
+= sprintf(dp
, " coding ");
454 dp
+= prbits(dp
, *p
, 7, 2);
455 dp
+= sprintf(dp
, " location ");
456 dp
+= prbits(dp
, *p
, 4, 4);
462 /* locate cause value */
463 for (i
= 0; i
< CVSIZE
; i
++)
464 if (cvlist
[i
].nr
== cause
)
467 /* display cause value if it exists */
469 dp
+= sprintf(dp
, "Unknown cause type %x!\n", cause
);
471 dp
+= sprintf(dp
, " cause value %x : %s \n", cause
, cvlist
[i
].edescr
);
476 dp
+= sprintf(dp
, " diag attribute %d ", *p
++ & 0x7f);
477 dp
+= sprintf(dp
, " rej %d ", *p
& 0x7f);
482 dp
+= sprintf(dp
, " av %d\n", (*++p
) & 0x7f);
489 struct MessageType cause_1tr6
[] =
491 {CAUSE_InvCRef
, "Invalid Call Reference"},
492 {CAUSE_BearerNotImpl
, "Bearer Service Not Implemented"},
493 {CAUSE_CIDunknown
, "Caller Identity unknown"},
494 {CAUSE_CIDinUse
, "Caller Identity in Use"},
495 {CAUSE_NoChans
, "No Channels available"},
496 {CAUSE_FacNotImpl
, "Facility Not Implemented"},
497 {CAUSE_FacNotSubscr
, "Facility Not Subscribed"},
498 {CAUSE_OutgoingBarred
, "Outgoing calls barred"},
499 {CAUSE_UserAccessBusy
, "User Access Busy"},
500 {CAUSE_NegativeGBG
, "Negative GBG"},
501 {CAUSE_UnknownGBG
, "Unknown GBG"},
502 {CAUSE_NoSPVknown
, "No SPV known"},
503 {CAUSE_DestNotObtain
, "Destination not obtainable"},
504 {CAUSE_NumberChanged
, "Number changed"},
505 {CAUSE_OutOfOrder
, "Out Of Order"},
506 {CAUSE_NoUserResponse
, "No User Response"},
507 {CAUSE_UserBusy
, "User Busy"},
508 {CAUSE_IncomingBarred
, "Incoming Barred"},
509 {CAUSE_CallRejected
, "Call Rejected"},
510 {CAUSE_NetworkCongestion
, "Network Congestion"},
511 {CAUSE_RemoteUser
, "Remote User initiated"},
512 {CAUSE_LocalProcErr
, "Local Procedure Error"},
513 {CAUSE_RemoteProcErr
, "Remote Procedure Error"},
514 {CAUSE_RemoteUserSuspend
, "Remote User Suspend"},
515 {CAUSE_RemoteUserResumed
, "Remote User Resumed"},
516 {CAUSE_UserInfoDiscarded
, "User Info Discarded"}
519 static int cause_1tr6_len
= ARRAY_SIZE(cause_1tr6
);
522 prcause_1tr6(char *dest
, u_char
* p
)
529 dp
+= sprintf(dp
, " OK (cause length=0)\n");
532 dp
+= sprintf(dp
, " coding ");
533 dp
+= prbits(dp
, p
[2], 7, 2);
534 dp
+= sprintf(dp
, " location ");
535 dp
+= prbits(dp
, p
[2], 4, 4);
541 /* locate cause value */
542 for (i
= 0; i
< cause_1tr6_len
; i
++)
543 if (cause_1tr6
[i
].nr
== cause
)
546 /* display cause value if it exists */
547 if (i
== cause_1tr6_len
)
548 dp
+= sprintf(dp
, "Unknown cause type %x!\n", cause
);
550 dp
+= sprintf(dp
, " cause value %x : %s \n", cause
, cause_1tr6
[i
].descr
);
557 prchident(char *dest
, u_char
* p
)
562 dp
+= sprintf(dp
, " octet 3 ");
563 dp
+= prbits(dp
, *p
, 8, 8);
569 prcalled(char *dest
, u_char
* p
)
576 dp
+= sprintf(dp
, " octet 3 ");
577 dp
+= prbits(dp
, *p
++, 8, 8);
579 dp
+= sprintf(dp
, " number digits ");
586 prcalling(char *dest
, u_char
* p
)
593 dp
+= sprintf(dp
, " octet 3 ");
594 dp
+= prbits(dp
, *p
, 8, 8);
597 dp
+= sprintf(dp
, " octet 3a ");
598 dp
+= prbits(dp
, *++p
, 8, 8);
604 dp
+= sprintf(dp
, " number digits ");
613 prbearer(char *dest
, u_char
* p
)
618 dp
+= sprintf(dp
, " octet 3 ");
619 dp
+= prbits(dp
, *p
++, 8, 8);
621 dp
+= sprintf(dp
, " octet 4 ");
622 dp
+= prbits(dp
, *p
, 8, 8);
624 if ((*p
++ & 0x1f) == 0x18) {
625 dp
+= sprintf(dp
, " octet 4.1 ");
626 dp
+= prbits(dp
, *p
++, 8, 8);
629 /* check for user information layer 1 */
630 if ((*p
& 0x60) == 0x20) {
633 dp
+= sprintf(dp
, " octet 5%c ", ch
);
634 dp
+= prbits(dp
, *p
, 8, 8);
641 while (!(*p
++ & 0x80));
643 /* check for user information layer 2 */
644 if ((*p
& 0x60) == 0x40) {
645 dp
+= sprintf(dp
, " octet 6 ");
646 dp
+= prbits(dp
, *p
++, 8, 8);
649 /* check for user information layer 3 */
650 if ((*p
& 0x60) == 0x60) {
651 dp
+= sprintf(dp
, " octet 7 ");
652 dp
+= prbits(dp
, *p
++, 8, 8);
661 prbearer_ni1(char *dest
, u_char
* p
)
668 dp
+= sprintf(dp
, " octet 3 ");
669 dp
+= prbits(dp
, *p
, 8, 8);
672 dp
+= sprintf(dp
, " Speech");
675 dp
+= sprintf(dp
, " Unrestricted digital information");
678 dp
+= sprintf(dp
, " 3.1 kHz audio");
681 dp
+= sprintf(dp
, " Unknown information-transfer capability");
684 dp
+= sprintf(dp
, " octet 4 ");
685 dp
+= prbits(dp
, *p
, 8, 8);
688 dp
+= sprintf(dp
, " 64 kbps, circuit mode");
691 dp
+= sprintf(dp
, " Packet mode");
694 dp
+= sprintf(dp
, " Unknown transfer mode");
698 dp
+= sprintf(dp
, " octet 5 ");
699 dp
+= prbits(dp
, *p
, 8, 8);
702 dp
+= sprintf(dp
, " Rate adaption\n");
703 dp
+= sprintf(dp
, " octet 5a ");
704 dp
+= prbits(dp
, *p
, 8, 8);
707 dp
+= sprintf(dp
, " u-law");
710 dp
+= sprintf(dp
, " Unknown UI layer 1 protocol");
718 general(char *dest
, u_char
* p
)
726 /* Iterate over all octets in the information element */
728 dp
+= sprintf(dp
, " octet %d%c ", octet
, ch
);
729 dp
+= prbits(dp
, *p
++, 8, 8);
732 /* last octet in group? */
736 } else if (ch
== ' ')
745 general_ni1(char *dest
, u_char
* p
)
753 /* Iterate over all octets in the information element */
755 dp
+= sprintf(dp
, " octet %d%c ", octet
, ch
);
756 dp
+= prbits(dp
, *p
, 8, 8);
759 /* last octet in group? */
763 } else if (ch
== ' ')
772 prcharge(char *dest
, u_char
* p
)
779 dp
+= sprintf(dp
, " GEA ");
780 dp
+= prbits(dp
, *p
++, 8, 8);
781 dp
+= sprintf(dp
, " Anzahl: ");
782 /* Iterate over all octets in the * information element */
789 prtext(char *dest
, u_char
* p
)
796 dp
+= sprintf(dp
, " ");
797 /* Iterate over all octets in the * information element */
805 prfeatureind(char *dest
, u_char
* p
)
809 p
+= 2; /* skip id, len */
810 dp
+= sprintf(dp
, " octet 3 ");
811 dp
+= prbits(dp
, *p
, 8, 8);
814 dp
+= sprintf(dp
, " octet 4 ");
815 dp
+= prbits(dp
, *p
++, 8, 8);
818 dp
+= sprintf(dp
, " Status: ");
821 dp
+= sprintf(dp
, "Idle");
824 dp
+= sprintf(dp
, "Active");
827 dp
+= sprintf(dp
, "Prompt");
830 dp
+= sprintf(dp
, "Pending");
833 dp
+= sprintf(dp
, "(Reserved)");
841 struct DTag
{ /* Display tags */
845 { 0x82, "Continuation" },
846 { 0x83, "Called address" },
848 { 0x85, "Progress indicator" },
849 { 0x86, "Notification indicator" },
851 { 0x88, "Accumlated digits" },
854 { 0x8b, "Calling address" },
856 { 0x8d, "Calling party name" },
857 { 0x8e, "Called party name" },
858 { 0x8f, "Orignal called name" },
859 { 0x90, "Redirecting name" },
860 { 0x91, "Connected name" },
861 { 0x92, "Originating restrictions" },
862 { 0x93, "Date & time of day" },
863 { 0x94, "Call Appearance ID" },
864 { 0x95, "Feature address" },
865 { 0x96, "Redirection name" },
868 #define DTAGSIZE ARRAY_SIZE(dtaglist)
871 disptext_ni1(char *dest
, u_char
* p
)
879 dp
+= sprintf(dp
, " Unknown display type\n");
882 /* Iterate over all tag,length,text fields */
887 /* Don't space or skip */
888 if ((tag
== 0x80) || (tag
== 0x81)) p
++;
890 for (i
= 0; i
< DTAGSIZE
; i
++)
891 if (tag
== dtaglist
[i
].nr
)
894 /* When not found, give appropriate msg */
896 dp
+= sprintf(dp
, " %s: ", dtaglist
[i
].descr
);
900 dp
+= sprintf(dp
, " (unknown display tag %2x): ", tag
);
904 dp
+= sprintf(dp
, "\n");
910 display(char *dest
, u_char
* p
)
918 /* Iterate over all octets in the * display-information element */
919 dp
+= sprintf(dp
, " \"");
921 dp
+= sprintf(dp
, "%c", *p
++);
923 /* last octet in group? */
927 } else if (ch
== ' ')
939 prfacility(char *dest
, u_char
* p
)
946 dp
+= sprintf(dp
, " octet 3 ");
947 dp
+= prbits(dp
, *p
++, 8, 8);
948 dp
+= sprintf(dp
, "\n");
952 dp
+= sprintf(dp
, " octet 4 ");
953 dp
+= prbits(dp
, *p
++, 8, 8);
954 dp
+= sprintf(dp
, "\n");
955 dp
+= sprintf(dp
, " octet 5 %d\n", l2
= *p
++ & 0x7f);
957 dp
+= sprintf(dp
, " contents ");
959 dp
+= sprintf(dp
, "%2x ", *p
++);
962 dp
+= sprintf(dp
, "\n");
969 struct InformationElement
{
972 int (*f
) (char *, u_char
*);
976 0x00, "Segmented message", general
979 0x04, "Bearer capability", prbearer
982 0x08, "Cause", prcause
985 0x10, "Call identity", general
988 0x14, "Call state", general
991 0x18, "Channel identification", prchident
994 0x1c, "Facility", prfacility
997 0x1e, "Progress indicator", general
1000 0x20, "Network-specific facilities", general
1003 0x27, "Notification indicator", general
1006 0x28, "Display", display
1009 0x29, "Date/Time", general
1012 0x2c, "Keypad facility", general
1015 0x34, "Signal", general
1018 0x40, "Information rate", general
1021 0x42, "End-to-end delay", general
1024 0x43, "Transit delay selection and indication", general
1027 0x44, "Packet layer binary parameters", general
1030 0x45, "Packet layer window size", general
1033 0x46, "Packet size", general
1036 0x47, "Closed user group", general
1039 0x4a, "Reverse charge indication", general
1042 0x6c, "Calling party number", prcalling
1045 0x6d, "Calling party subaddress", general
1048 0x70, "Called party number", prcalled
1051 0x71, "Called party subaddress", general
1054 0x74, "Redirecting number", general
1057 0x78, "Transit network selection", general
1060 0x79, "Restart indicator", general
1063 0x7c, "Low layer compatibility", general
1066 0x7d, "High layer compatibility", general
1069 0x7e, "User-user", general
1072 0x7f, "Escape for extension", general
1077 #define IESIZE ARRAY_SIZE(ielist)
1080 struct InformationElement ielist_ni1
[] = {
1081 { 0x04, "Bearer Capability", prbearer_ni1
},
1082 { 0x08, "Cause", prcause
},
1083 { 0x14, "Call State", general_ni1
},
1084 { 0x18, "Channel Identification", prchident
},
1085 { 0x1e, "Progress Indicator", general_ni1
},
1086 { 0x27, "Notification Indicator", general_ni1
},
1087 { 0x2c, "Keypad Facility", prtext
},
1088 { 0x32, "Information Request", general_ni1
},
1089 { 0x34, "Signal", general_ni1
},
1090 { 0x38, "Feature Activation", general_ni1
},
1091 { 0x39, "Feature Indication", prfeatureind
},
1092 { 0x3a, "Service Profile Identification (SPID)", prtext
},
1093 { 0x3b, "Endpoint Identifier", general_ni1
},
1094 { 0x6c, "Calling Party Number", prcalling
},
1095 { 0x6d, "Calling Party Subaddress", general_ni1
},
1096 { 0x70, "Called Party Number", prcalled
},
1097 { 0x71, "Called Party Subaddress", general_ni1
},
1098 { 0x74, "Redirecting Number", general_ni1
},
1099 { 0x78, "Transit Network Selection", general_ni1
},
1100 { 0x7c, "Low Layer Compatibility", general_ni1
},
1101 { 0x7d, "High Layer Compatibility", general_ni1
},
1105 #define IESIZE_NI1 ARRAY_SIZE(ielist_ni1)
1108 struct InformationElement ielist_ni1_cs5
[] = {
1109 { 0x1d, "Operator system access", general_ni1
},
1110 { 0x2a, "Display text", disptext_ni1
},
1113 #define IESIZE_NI1_CS5 ARRAY_SIZE(ielist_ni1_cs5)
1116 struct InformationElement ielist_ni1_cs6
[] = {
1117 { 0x7b, "Call appearance", general_ni1
},
1120 #define IESIZE_NI1_CS6 ARRAY_SIZE(ielist_ni1_cs6)
1122 static struct InformationElement we_0
[] =
1124 {WE0_cause
, "Cause", prcause_1tr6
},
1125 {WE0_connAddr
, "Connecting Address", prcalled
},
1126 {WE0_callID
, "Call IDentity", general
},
1127 {WE0_chanID
, "Channel IDentity", general
},
1128 {WE0_netSpecFac
, "Network Specific Facility", general
},
1129 {WE0_display
, "Display", general
},
1130 {WE0_keypad
, "Keypad", general
},
1131 {WE0_origAddr
, "Origination Address", prcalled
},
1132 {WE0_destAddr
, "Destination Address", prcalled
},
1133 {WE0_userInfo
, "User Info", general
}
1136 #define WE_0_LEN ARRAY_SIZE(we_0)
1138 static struct InformationElement we_6
[] =
1140 {WE6_serviceInd
, "Service Indicator", general
},
1141 {WE6_chargingInfo
, "Charging Information", prcharge
},
1142 {WE6_date
, "Date", prtext
},
1143 {WE6_facSelect
, "Facility Select", general
},
1144 {WE6_facStatus
, "Facility Status", general
},
1145 {WE6_statusCalled
, "Status Called", general
},
1146 {WE6_addTransAttr
, "Additional Transmission Attributes", general
}
1148 #define WE_6_LEN ARRAY_SIZE(we_6)
1151 QuickHex(char *txt
, u_char
* p
, int cnt
)
1154 register char *t
= txt
;
1156 for (i
= 0; i
< cnt
; i
++) {
1158 *t
++ = hex_asc_hi(p
[i
]);
1159 *t
++ = hex_asc_lo(p
[i
]);
1166 LogFrame(struct IsdnCardState
*cs
, u_char
* buf
, int size
)
1173 if (size
< MAX_DLOG_SPACE
/ 3 - 10) {
1178 dp
+= QuickHex(dp
, buf
, size
);
1182 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
1184 HiSax_putstatus(cs
, "LogFrame: ", "warning Frame too big (%d)", size
);
1188 dlogframe(struct IsdnCardState
*cs
, struct sk_buff
*skb
, int dir
)
1192 unsigned char pd
, cr_l
, cr
, mt
;
1193 unsigned char sapi
, tei
, ftyp
;
1194 int i
, cset
= 0, cs_old
= 0, cs_fest
= 0;
1195 int size
, finish
= 0;
1199 /* display header */
1201 dp
+= jiftime(dp
, jiffies
);
1203 sapi
= skb
->data
[0] >> 2;
1204 tei
= skb
->data
[1] >> 1;
1205 ftyp
= skb
->data
[2];
1207 dp
+= sprintf(dp
, "frame %s ", dir
? "network->user" : "user->network");
1210 if (tei
== GROUP_TEI
) {
1211 if (sapi
== CTRL_SAPI
) { /* sapi 0 */
1213 dp
+= sprintf(dp
, "broadcast\n");
1217 dp
+= sprintf(dp
, "no UI broadcast\n");
1220 } else if (sapi
== TEI_SAPI
) {
1221 dp
+= sprintf(dp
, "tei management\n");
1224 dp
+= sprintf(dp
, "unknown sapi %d broadcast\n", sapi
);
1228 if (sapi
== CTRL_SAPI
) {
1229 if (!(ftyp
& 1)) { /* IFrame */
1230 dp
+= sprintf(dp
, "with tei %d\n", tei
);
1234 dp
+= sprintf(dp
, "SFrame with tei %d\n", tei
);
1238 dp
+= sprintf(dp
, "unknown sapi %d tei %d\n", sapi
, tei
);
1242 bend
= skb
->data
+ skb
->len
;
1244 dp
+= sprintf(dp
, "frame too short\n");
1249 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
1252 if ((0xfe & buf
[0]) == PROTO_DIS_N0
) { /* 1TR6 */
1253 /* locate message type */
1261 if (pd
== PROTO_DIS_N0
) { /* N0 */
1262 for (i
= 0; i
< MT_N0_LEN
; i
++)
1263 if (mt_n0
[i
].nr
== mt
)
1265 /* display message type if it exists */
1267 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type N0 %x!\n",
1268 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1271 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1272 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1273 size
, mt_n0
[i
].descr
);
1275 for (i
= 0; i
< MT_N1_LEN
; i
++)
1276 if (mt_n1
[i
].nr
== mt
)
1278 /* display message type if it exists */
1280 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type N1 %x!\n",
1281 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1284 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1285 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1286 size
, mt_n1
[i
].descr
);
1289 /* display each information element */
1290 while (buf
< bend
) {
1291 /* Is it a single octet information element? */
1293 switch ((*buf
>> 4) & 7) {
1295 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1301 dp
+= sprintf(dp
, " Congestion level %x\n", *buf
& 0xf);
1305 dp
+= sprintf(dp
, " More data\n");
1309 dp
+= sprintf(dp
, " Sending complete\n");
1314 dp
+= sprintf(dp
, " Reserved %x\n", *buf
);
1320 /* No, locate it in the table */
1322 for (i
= 0; i
< WE_0_LEN
; i
++)
1323 if (*buf
== we_0
[i
].nr
)
1326 /* When found, give appropriate msg */
1327 if (i
!= WE_0_LEN
) {
1328 dp
+= sprintf(dp
, " %s\n", we_0
[i
].descr
);
1329 dp
+= we_0
[i
].f(dp
, buf
);
1331 dp
+= sprintf(dp
, " Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1332 } else if (cset
== 6) {
1333 for (i
= 0; i
< WE_6_LEN
; i
++)
1334 if (*buf
== we_6
[i
].nr
)
1337 /* When found, give appropriate msg */
1338 if (i
!= WE_6_LEN
) {
1339 dp
+= sprintf(dp
, " %s\n", we_6
[i
].descr
);
1340 dp
+= we_6
[i
].f(dp
, buf
);
1342 dp
+= sprintf(dp
, " Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1344 dp
+= sprintf(dp
, " Unknown Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1345 /* Skip to next element */
1353 } else if ((buf
[0] == 8) && (cs
->protocol
== ISDN_PTYPE_NI1
)) { /* NI-1 */
1354 /* locate message type */
1362 for (i
= 0; i
< MTSIZE
; i
++)
1363 if (mtlist
[i
].nr
== mt
)
1366 /* display message type if it exists */
1368 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type %x!\n",
1369 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1372 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1373 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1374 size
, mtlist
[i
].descr
);
1376 /* display each information element */
1377 while (buf
< bend
) {
1378 /* Is it a single octet information element? */
1380 switch ((*buf
>> 4) & 7) {
1382 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1388 dp
+= sprintf(dp
, " Unknown single-octet IE %x\n", *buf
);
1394 /* No, locate it in the table */
1396 for (i
= 0; i
< IESIZE_NI1
; i
++)
1397 if (*buf
== ielist_ni1
[i
].nr
)
1400 /* When not found, give appropriate msg */
1401 if (i
!= IESIZE_NI1
) {
1402 dp
+= sprintf(dp
, " %s\n", ielist_ni1
[i
].descr
);
1403 dp
+= ielist_ni1
[i
].f(dp
, buf
);
1405 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1406 } else if (cset
== 5) {
1407 for (i
= 0; i
< IESIZE_NI1_CS5
; i
++)
1408 if (*buf
== ielist_ni1_cs5
[i
].nr
)
1411 /* When not found, give appropriate msg */
1412 if (i
!= IESIZE_NI1_CS5
) {
1413 dp
+= sprintf(dp
, " %s\n", ielist_ni1_cs5
[i
].descr
);
1414 dp
+= ielist_ni1_cs5
[i
].f(dp
, buf
);
1416 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1417 } else if (cset
== 6) {
1418 for (i
= 0; i
< IESIZE_NI1_CS6
; i
++)
1419 if (*buf
== ielist_ni1_cs6
[i
].nr
)
1422 /* When not found, give appropriate msg */
1423 if (i
!= IESIZE_NI1_CS6
) {
1424 dp
+= sprintf(dp
, " %s\n", ielist_ni1_cs6
[i
].descr
);
1425 dp
+= ielist_ni1_cs6
[i
].f(dp
, buf
);
1427 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1429 dp
+= sprintf(dp
, " Unknown Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1431 /* Skip to next element */
1439 } else if ((buf
[0] == 8) && (cs
->protocol
== ISDN_PTYPE_EURO
)) { /* EURO */
1440 /* locate message type */
1448 for (i
= 0; i
< MTSIZE
; i
++)
1449 if (mtlist
[i
].nr
== mt
)
1452 /* display message type if it exists */
1454 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type %x!\n",
1455 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1458 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1459 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1460 size
, mtlist
[i
].descr
);
1462 /* display each information element */
1463 while (buf
< bend
) {
1464 /* Is it a single octet information element? */
1466 switch ((*buf
>> 4) & 7) {
1468 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1471 dp
+= sprintf(dp
, " Congestion level %x\n", *buf
& 0xf);
1474 dp
+= sprintf(dp
, " Repeat indicator %x\n", *buf
& 0xf);
1478 dp
+= sprintf(dp
, " More data\n");
1482 dp
+= sprintf(dp
, " Sending complete\n");
1487 dp
+= sprintf(dp
, " Reserved %x\n", *buf
);
1493 /* No, locate it in the table */
1494 for (i
= 0; i
< IESIZE
; i
++)
1495 if (*buf
== ielist
[i
].nr
)
1498 /* When not found, give appropriate msg */
1500 dp
+= sprintf(dp
, " %s\n", ielist
[i
].descr
);
1501 dp
+= ielist
[i
].f(dp
, buf
);
1503 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1505 /* Skip to next element */
1509 dp
+= sprintf(dp
, "Unknown protocol %x!", buf
[0]);
1512 HiSax_putstatus(cs
, NULL
, cs
->dlog
);