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 sizeof(mtlist)/sizeof(struct MessageType)
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 (sizeof(mt_n0) / sizeof(struct MessageType))
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 (sizeof(mt_n1) / sizeof(struct MessageType))
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 sizeof(cvlist)/sizeof(struct CauseValue)
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
= (sizeof(cause_1tr6
) / sizeof(struct MessageType
));
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 sizeof(dtaglist)/sizeof(struct DTag)
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 sizeof(ielist)/sizeof(struct InformationElement)
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 sizeof(ielist_ni1)/sizeof(struct InformationElement)
1108 struct InformationElement ielist_ni1_cs5
[] = {
1109 { 0x1d, "Operator system access", general_ni1
},
1110 { 0x2a, "Display text", disptext_ni1
},
1113 #define IESIZE_NI1_CS5 sizeof(ielist_ni1_cs5)/sizeof(struct InformationElement)
1116 struct InformationElement ielist_ni1_cs6
[] = {
1117 { 0x7b, "Call appearance", general_ni1
},
1120 #define IESIZE_NI1_CS6 sizeof(ielist_ni1_cs6)/sizeof(struct InformationElement)
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 (sizeof(we_0) / sizeof(struct InformationElement))
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 (sizeof(we_6) / sizeof(struct InformationElement))
1151 QuickHex(char *txt
, u_char
* p
, int cnt
)
1154 register char *t
= txt
;
1157 for (i
= 0; i
< cnt
; i
++) {
1159 w
= (p
[i
] >> 4) & 0x0f;
1163 *t
++ = 'A' - 10 + w
;
1168 *t
++ = 'A' - 10 + w
;
1175 LogFrame(struct IsdnCardState
*cs
, u_char
* buf
, int size
)
1182 if (size
< MAX_DLOG_SPACE
/ 3 - 10) {
1187 dp
+= QuickHex(dp
, buf
, size
);
1191 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
1193 HiSax_putstatus(cs
, "LogFrame: ", "warning Frame too big (%d)", size
);
1197 dlogframe(struct IsdnCardState
*cs
, struct sk_buff
*skb
, int dir
)
1201 unsigned char pd
, cr_l
, cr
, mt
;
1202 unsigned char sapi
, tei
, ftyp
;
1203 int i
, cset
= 0, cs_old
= 0, cs_fest
= 0;
1204 int size
, finish
= 0;
1208 /* display header */
1210 dp
+= jiftime(dp
, jiffies
);
1212 sapi
= skb
->data
[0] >> 2;
1213 tei
= skb
->data
[1] >> 1;
1214 ftyp
= skb
->data
[2];
1216 dp
+= sprintf(dp
, "frame %s ", dir
? "network->user" : "user->network");
1219 if (tei
== GROUP_TEI
) {
1220 if (sapi
== CTRL_SAPI
) { /* sapi 0 */
1222 dp
+= sprintf(dp
, "broadcast\n");
1226 dp
+= sprintf(dp
, "no UI broadcast\n");
1229 } else if (sapi
== TEI_SAPI
) {
1230 dp
+= sprintf(dp
, "tei management\n");
1233 dp
+= sprintf(dp
, "unknown sapi %d broadcast\n", sapi
);
1237 if (sapi
== CTRL_SAPI
) {
1238 if (!(ftyp
& 1)) { /* IFrame */
1239 dp
+= sprintf(dp
, "with tei %d\n", tei
);
1243 dp
+= sprintf(dp
, "SFrame with tei %d\n", tei
);
1247 dp
+= sprintf(dp
, "unknown sapi %d tei %d\n", sapi
, tei
);
1251 bend
= skb
->data
+ skb
->len
;
1253 dp
+= sprintf(dp
, "frame too short\n");
1258 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
1261 if ((0xfe & buf
[0]) == PROTO_DIS_N0
) { /* 1TR6 */
1262 /* locate message type */
1270 if (pd
== PROTO_DIS_N0
) { /* N0 */
1271 for (i
= 0; i
< MT_N0_LEN
; i
++)
1272 if (mt_n0
[i
].nr
== mt
)
1274 /* display message type if it exists */
1276 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type N0 %x!\n",
1277 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1280 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1281 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1282 size
, mt_n0
[i
].descr
);
1284 for (i
= 0; i
< MT_N1_LEN
; i
++)
1285 if (mt_n1
[i
].nr
== mt
)
1287 /* display message type if it exists */
1289 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type N1 %x!\n",
1290 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1293 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1294 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1295 size
, mt_n1
[i
].descr
);
1298 /* display each information element */
1299 while (buf
< bend
) {
1300 /* Is it a single octet information element? */
1302 switch ((*buf
>> 4) & 7) {
1304 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1310 dp
+= sprintf(dp
, " Congestion level %x\n", *buf
& 0xf);
1314 dp
+= sprintf(dp
, " More data\n");
1318 dp
+= sprintf(dp
, " Sending complete\n");
1323 dp
+= sprintf(dp
, " Reserved %x\n", *buf
);
1329 /* No, locate it in the table */
1331 for (i
= 0; i
< WE_0_LEN
; i
++)
1332 if (*buf
== we_0
[i
].nr
)
1335 /* When found, give appropriate msg */
1336 if (i
!= WE_0_LEN
) {
1337 dp
+= sprintf(dp
, " %s\n", we_0
[i
].descr
);
1338 dp
+= we_0
[i
].f(dp
, buf
);
1340 dp
+= sprintf(dp
, " Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1341 } else if (cset
== 6) {
1342 for (i
= 0; i
< WE_6_LEN
; i
++)
1343 if (*buf
== we_6
[i
].nr
)
1346 /* When found, give appropriate msg */
1347 if (i
!= WE_6_LEN
) {
1348 dp
+= sprintf(dp
, " %s\n", we_6
[i
].descr
);
1349 dp
+= we_6
[i
].f(dp
, buf
);
1351 dp
+= sprintf(dp
, " Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1353 dp
+= sprintf(dp
, " Unknown Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1354 /* Skip to next element */
1362 } else if ((buf
[0] == 8) && (cs
->protocol
== ISDN_PTYPE_NI1
)) { /* NI-1 */
1363 /* locate message type */
1371 for (i
= 0; i
< MTSIZE
; i
++)
1372 if (mtlist
[i
].nr
== mt
)
1375 /* display message type if it exists */
1377 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type %x!\n",
1378 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1381 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1382 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1383 size
, mtlist
[i
].descr
);
1385 /* display each information element */
1386 while (buf
< bend
) {
1387 /* Is it a single octet information element? */
1389 switch ((*buf
>> 4) & 7) {
1391 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1397 dp
+= sprintf(dp
, " Unknown single-octet IE %x\n", *buf
);
1403 /* No, locate it in the table */
1405 for (i
= 0; i
< IESIZE_NI1
; i
++)
1406 if (*buf
== ielist_ni1
[i
].nr
)
1409 /* When not found, give appropriate msg */
1410 if (i
!= IESIZE_NI1
) {
1411 dp
+= sprintf(dp
, " %s\n", ielist_ni1
[i
].descr
);
1412 dp
+= ielist_ni1
[i
].f(dp
, buf
);
1414 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1415 } else if (cset
== 5) {
1416 for (i
= 0; i
< IESIZE_NI1_CS5
; i
++)
1417 if (*buf
== ielist_ni1_cs5
[i
].nr
)
1420 /* When not found, give appropriate msg */
1421 if (i
!= IESIZE_NI1_CS5
) {
1422 dp
+= sprintf(dp
, " %s\n", ielist_ni1_cs5
[i
].descr
);
1423 dp
+= ielist_ni1_cs5
[i
].f(dp
, buf
);
1425 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1426 } else if (cset
== 6) {
1427 for (i
= 0; i
< IESIZE_NI1_CS6
; i
++)
1428 if (*buf
== ielist_ni1_cs6
[i
].nr
)
1431 /* When not found, give appropriate msg */
1432 if (i
!= IESIZE_NI1_CS6
) {
1433 dp
+= sprintf(dp
, " %s\n", ielist_ni1_cs6
[i
].descr
);
1434 dp
+= ielist_ni1_cs6
[i
].f(dp
, buf
);
1436 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1438 dp
+= sprintf(dp
, " Unknown Codeset %d attribute %x attribute size %d\n", cset
, *buf
, buf
[1]);
1440 /* Skip to next element */
1448 } else if ((buf
[0] == 8) && (cs
->protocol
== ISDN_PTYPE_EURO
)) { /* EURO */
1449 /* locate message type */
1457 for (i
= 0; i
< MTSIZE
; i
++)
1458 if (mtlist
[i
].nr
== mt
)
1461 /* display message type if it exists */
1463 dp
+= sprintf(dp
, "callref %d %s size %d unknown message type %x!\n",
1464 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1467 dp
+= sprintf(dp
, "callref %d %s size %d message type %s\n",
1468 cr
& 0x7f, (cr
& 0x80) ? "called" : "caller",
1469 size
, mtlist
[i
].descr
);
1471 /* display each information element */
1472 while (buf
< bend
) {
1473 /* Is it a single octet information element? */
1475 switch ((*buf
>> 4) & 7) {
1477 dp
+= sprintf(dp
, " Shift %x\n", *buf
& 0xf);
1480 dp
+= sprintf(dp
, " Congestion level %x\n", *buf
& 0xf);
1483 dp
+= sprintf(dp
, " Repeat indicator %x\n", *buf
& 0xf);
1487 dp
+= sprintf(dp
, " More data\n");
1491 dp
+= sprintf(dp
, " Sending complete\n");
1496 dp
+= sprintf(dp
, " Reserved %x\n", *buf
);
1502 /* No, locate it in the table */
1503 for (i
= 0; i
< IESIZE
; i
++)
1504 if (*buf
== ielist
[i
].nr
)
1507 /* When not found, give appropriate msg */
1509 dp
+= sprintf(dp
, " %s\n", ielist
[i
].descr
);
1510 dp
+= ielist
[i
].f(dp
, buf
);
1512 dp
+= sprintf(dp
, " attribute %x attribute size %d\n", *buf
, buf
[1]);
1514 /* Skip to next element */
1518 dp
+= sprintf(dp
, "Unknown protocol %x!", buf
[0]);
1521 HiSax_putstatus(cs
, NULL
, cs
->dlog
);