q931.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:31k
- /* $Id: q931.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
- *
- * code to decode ITU Q.931 call control messages
- *
- * Author Jan den Ouden
- * Copyright by Jan den Ouden
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Changelog:
- *
- * Pauline Middelink general improvements
- * Beat Doebeli cause texts, display information element
- * Karsten Keil cause texts, display information element for 1TR6
- *
- */
- #define __NO_VERSION__
- #include "hisax.h"
- #include "l3_1tr6.h"
- void
- iecpy(u_char * dest, u_char * iestart, int ieoffset)
- {
- u_char *p;
- int l;
- p = iestart + ieoffset + 2;
- l = iestart[1] - ieoffset;
- while (l--)
- *dest++ = *p++;
- *dest++ = ' ';
- }
- /*
- * According to Table 4-2/Q.931
- */
- static
- struct MessageType {
- u_char nr;
- char *descr;
- } mtlist[] = {
- {
- 0x1, "ALERTING"
- },
- {
- 0x2, "CALL PROCEEDING"
- },
- {
- 0x7, "CONNECT"
- },
- {
- 0xf, "CONNECT ACKNOWLEDGE"
- },
- {
- 0x3, "PROGRESS"
- },
- {
- 0x5, "SETUP"
- },
- {
- 0xd, "SETUP ACKNOWLEDGE"
- },
- {
- 0x24, "HOLD"
- },
- {
- 0x28, "HOLD ACKNOWLEDGE"
- },
- {
- 0x30, "HOLD REJECT"
- },
- {
- 0x31, "RETRIEVE"
- },
- {
- 0x33, "RETRIEVE ACKNOWLEDGE"
- },
- {
- 0x37, "RETRIEVE REJECT"
- },
- {
- 0x26, "RESUME"
- },
- {
- 0x2e, "RESUME ACKNOWLEDGE"
- },
- {
- 0x22, "RESUME REJECT"
- },
- {
- 0x25, "SUSPEND"
- },
- {
- 0x2d, "SUSPEND ACKNOWLEDGE"
- },
- {
- 0x21, "SUSPEND REJECT"
- },
- {
- 0x20, "USER INFORMATION"
- },
- {
- 0x45, "DISCONNECT"
- },
- {
- 0x4d, "RELEASE"
- },
- {
- 0x5a, "RELEASE COMPLETE"
- },
- {
- 0x46, "RESTART"
- },
- {
- 0x4e, "RESTART ACKNOWLEDGE"
- },
- {
- 0x60, "SEGMENT"
- },
- {
- 0x79, "CONGESTION CONTROL"
- },
- {
- 0x7b, "INFORMATION"
- },
- {
- 0x62, "FACILITY"
- },
- {
- 0x6e, "NOTIFY"
- },
- {
- 0x7d, "STATUS"
- },
- {
- 0x75, "STATUS ENQUIRY"
- }
- };
- #define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
- static
- struct MessageType mt_n0[] =
- {
- {MT_N0_REG_IND, "REGister INDication"},
- {MT_N0_CANC_IND, "CANCel INDication"},
- {MT_N0_FAC_STA, "FACility STAtus"},
- {MT_N0_STA_ACK, "STAtus ACKnowledge"},
- {MT_N0_STA_REJ, "STAtus REJect"},
- {MT_N0_FAC_INF, "FACility INFormation"},
- {MT_N0_INF_ACK, "INFormation ACKnowledge"},
- {MT_N0_INF_REJ, "INFormation REJect"},
- {MT_N0_CLOSE, "CLOSE"},
- {MT_N0_CLO_ACK, "CLOse ACKnowledge"}
- };
- #define MT_N0_LEN (sizeof(mt_n0) / sizeof(struct MessageType))
- static
- struct MessageType mt_n1[] =
- {
- {MT_N1_ESC, "ESCape"},
- {MT_N1_ALERT, "ALERT"},
- {MT_N1_CALL_SENT, "CALL SENT"},
- {MT_N1_CONN, "CONNect"},
- {MT_N1_CONN_ACK, "CONNect ACKnowledge"},
- {MT_N1_SETUP, "SETUP"},
- {MT_N1_SETUP_ACK, "SETUP ACKnowledge"},
- {MT_N1_RES, "RESume"},
- {MT_N1_RES_ACK, "RESume ACKnowledge"},
- {MT_N1_RES_REJ, "RESume REJect"},
- {MT_N1_SUSP, "SUSPend"},
- {MT_N1_SUSP_ACK, "SUSPend ACKnowledge"},
- {MT_N1_SUSP_REJ, "SUSPend REJect"},
- {MT_N1_USER_INFO, "USER INFO"},
- {MT_N1_DET, "DETach"},
- {MT_N1_DISC, "DISConnect"},
- {MT_N1_REL, "RELease"},
- {MT_N1_REL_ACK, "RELease ACKnowledge"},
- {MT_N1_CANC_ACK, "CANCel ACKnowledge"},
- {MT_N1_CANC_REJ, "CANCel REJect"},
- {MT_N1_CON_CON, "CONgestion CONtrol"},
- {MT_N1_FAC, "FACility"},
- {MT_N1_FAC_ACK, "FACility ACKnowledge"},
- {MT_N1_FAC_CAN, "FACility CANcel"},
- {MT_N1_FAC_REG, "FACility REGister"},
- {MT_N1_FAC_REJ, "FACility REJect"},
- {MT_N1_INFO, "INFOrmation"},
- {MT_N1_REG_ACK, "REGister ACKnowledge"},
- {MT_N1_REG_REJ, "REGister REJect"},
- {MT_N1_STAT, "STATus"}
- };
- #define MT_N1_LEN (sizeof(mt_n1) / sizeof(struct MessageType))
- static int
- prbits(char *dest, u_char b, int start, int len)
- {
- char *dp = dest;
- b = b << (8 - start);
- while (len--) {
- if (b & 0x80)
- *dp++ = '1';
- else
- *dp++ = '0';
- b = b << 1;
- }
- return (dp - dest);
- }
- static
- u_char *
- skipext(u_char * p)
- {
- while (!(*p++ & 0x80));
- return (p);
- }
- /*
- * Cause Values According to Q.850
- * edescr: English description
- * ddescr: German description used by Swissnet II (Swiss Telecom
- * not yet written...
- */
- static
- struct CauseValue {
- u_char nr;
- char *edescr;
- char *ddescr;
- } cvlist[] = {
- {
- 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
- },
- {
- 0x02, "No route to specified transit network", ""
- },
- {
- 0x03, "No route to destination", ""
- },
- {
- 0x04, "Send special information tone", ""
- },
- {
- 0x05, "Misdialled trunk prefix", ""
- },
- {
- 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
- },
- {
- 0x07, "Channel awarded and being delivered in an established channel", ""
- },
- {
- 0x08, "Preemption", ""
- },
- {
- 0x09, "Preemption - circuit reserved for reuse", ""
- },
- {
- 0x10, "Normal call clearing", "Normale Ausloesung"
- },
- {
- 0x11, "User busy", "TNB besetzt"
- },
- {
- 0x12, "No user responding", ""
- },
- {
- 0x13, "No answer from user (user alerted)", ""
- },
- {
- 0x14, "Subscriber absent", ""
- },
- {
- 0x15, "Call rejected", ""
- },
- {
- 0x16, "Number changed", ""
- },
- {
- 0x1a, "non-selected user clearing", ""
- },
- {
- 0x1b, "Destination out of order", ""
- },
- {
- 0x1c, "Invalid number format (address incomplete)", ""
- },
- {
- 0x1d, "Facility rejected", ""
- },
- {
- 0x1e, "Response to Status enquiry", ""
- },
- {
- 0x1f, "Normal, unspecified", ""
- },
- {
- 0x22, "No circuit/channel available", ""
- },
- {
- 0x26, "Network out of order", ""
- },
- {
- 0x27, "Permanent frame mode connection out-of-service", ""
- },
- {
- 0x28, "Permanent frame mode connection operational", ""
- },
- {
- 0x29, "Temporary failure", ""
- },
- {
- 0x2a, "Switching equipment congestion", ""
- },
- {
- 0x2b, "Access information discarded", ""
- },
- {
- 0x2c, "Requested circuit/channel not available", ""
- },
- {
- 0x2e, "Precedence call blocked", ""
- },
- {
- 0x2f, "Resource unavailable, unspecified", ""
- },
- {
- 0x31, "Quality of service unavailable", ""
- },
- {
- 0x32, "Requested facility not subscribed", ""
- },
- {
- 0x35, "Outgoing calls barred within CUG", ""
- },
- {
- 0x37, "Incoming calls barred within CUG", ""
- },
- {
- 0x39, "Bearer capability not authorized", ""
- },
- {
- 0x3a, "Bearer capability not presently available", ""
- },
- {
- 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
- },
- {
- 0x3f, "Service or option not available, unspecified", ""
- },
- {
- 0x41, "Bearer capability not implemented", ""
- },
- {
- 0x42, "Channel type not implemented", ""
- },
- {
- 0x43, "Requested facility not implemented", ""
- },
- {
- 0x44, "Only restricted digital information bearer capability is available", ""
- },
- {
- 0x4f, "Service or option not implemented", ""
- },
- {
- 0x51, "Invalid call reference value", ""
- },
- {
- 0x52, "Identified channel does not exist", ""
- },
- {
- 0x53, "A suspended call exists, but this call identity does not", ""
- },
- {
- 0x54, "Call identity in use", ""
- },
- {
- 0x55, "No call suspended", ""
- },
- {
- 0x56, "Call having the requested call identity has been cleared", ""
- },
- {
- 0x57, "User not member of CUG", ""
- },
- {
- 0x58, "Incompatible destination", ""
- },
- {
- 0x5a, "Non-existent CUG", ""
- },
- {
- 0x5b, "Invalid transit network selection", ""
- },
- {
- 0x5f, "Invalid message, unspecified", ""
- },
- {
- 0x60, "Mandatory information element is missing", ""
- },
- {
- 0x61, "Message type non-existent or not implemented", ""
- },
- {
- 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
- },
- {
- 0x63, "Information element/parameter non-existent or not implemented", ""
- },
- {
- 0x64, "Invalid information element contents", ""
- },
- {
- 0x65, "Message not compatible with call state", ""
- },
- {
- 0x66, "Recovery on timer expiry", ""
- },
- {
- 0x67, "Parameter non-existent or not implemented - passed on", ""
- },
- {
- 0x6e, "Message with unrecognized parameter discarded", ""
- },
- {
- 0x6f, "Protocol error, unspecified", ""
- },
- {
- 0x7f, "Interworking, unspecified", ""
- },
- };
- #define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
- static
- int
- prcause(char *dest, u_char * p)
- {
- u_char *end;
- char *dp = dest;
- int i, cause;
- end = p + p[1] + 1;
- p += 2;
- dp += sprintf(dp, " coding ");
- dp += prbits(dp, *p, 7, 2);
- dp += sprintf(dp, " location ");
- dp += prbits(dp, *p, 4, 4);
- *dp++ = 'n';
- p = skipext(p);
- cause = 0x7f & *p++;
- /* locate cause value */
- for (i = 0; i < CVSIZE; i++)
- if (cvlist[i].nr == cause)
- break;
- /* display cause value if it exists */
- if (i == CVSIZE)
- dp += sprintf(dp, "Unknown cause type %x!n", cause);
- else
- dp += sprintf(dp, " cause value %x : %s n", cause, cvlist[i].edescr);
- while (!0) {
- if (p > end)
- break;
- dp += sprintf(dp, " diag attribute %d ", *p++ & 0x7f);
- dp += sprintf(dp, " rej %d ", *p & 0x7f);
- if (*p & 0x80) {
- *dp++ = 'n';
- break;
- } else
- dp += sprintf(dp, " av %dn", (*++p) & 0x7f);
- }
- return (dp - dest);
- }
- static
- struct MessageType cause_1tr6[] =
- {
- {CAUSE_InvCRef, "Invalid Call Reference"},
- {CAUSE_BearerNotImpl, "Bearer Service Not Implemented"},
- {CAUSE_CIDunknown, "Caller Identity unknown"},
- {CAUSE_CIDinUse, "Caller Identity in Use"},
- {CAUSE_NoChans, "No Channels available"},
- {CAUSE_FacNotImpl, "Facility Not Implemented"},
- {CAUSE_FacNotSubscr, "Facility Not Subscribed"},
- {CAUSE_OutgoingBarred, "Outgoing calls barred"},
- {CAUSE_UserAccessBusy, "User Access Busy"},
- {CAUSE_NegativeGBG, "Negative GBG"},
- {CAUSE_UnknownGBG, "Unknown GBG"},
- {CAUSE_NoSPVknown, "No SPV known"},
- {CAUSE_DestNotObtain, "Destination not obtainable"},
- {CAUSE_NumberChanged, "Number changed"},
- {CAUSE_OutOfOrder, "Out Of Order"},
- {CAUSE_NoUserResponse, "No User Response"},
- {CAUSE_UserBusy, "User Busy"},
- {CAUSE_IncomingBarred, "Incoming Barred"},
- {CAUSE_CallRejected, "Call Rejected"},
- {CAUSE_NetworkCongestion, "Network Congestion"},
- {CAUSE_RemoteUser, "Remote User initiated"},
- {CAUSE_LocalProcErr, "Local Procedure Error"},
- {CAUSE_RemoteProcErr, "Remote Procedure Error"},
- {CAUSE_RemoteUserSuspend, "Remote User Suspend"},
- {CAUSE_RemoteUserResumed, "Remote User Resumed"},
- {CAUSE_UserInfoDiscarded, "User Info Discarded"}
- };
- int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
- static int
- prcause_1tr6(char *dest, u_char * p)
- {
- char *dp = dest;
- int i, cause;
- p++;
- if (0 == *p) {
- dp += sprintf(dp, " OK (cause length=0)n");
- return (dp - dest);
- } else if (*p > 1) {
- dp += sprintf(dp, " coding ");
- dp += prbits(dp, p[2], 7, 2);
- dp += sprintf(dp, " location ");
- dp += prbits(dp, p[2], 4, 4);
- *dp++ = 'n';
- }
- p++;
- cause = 0x7f & *p;
- /* locate cause value */
- for (i = 0; i < cause_1tr6_len; i++)
- if (cause_1tr6[i].nr == cause)
- break;
- /* display cause value if it exists */
- if (i == cause_1tr6_len)
- dp += sprintf(dp, "Unknown cause type %x!n", cause);
- else
- dp += sprintf(dp, " cause value %x : %s n", cause, cause_1tr6[i].descr);
- return (dp - dest);
- }
- static int
- prchident(char *dest, u_char * p)
- {
- char *dp = dest;
- p += 2;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = 'n';
- return (dp - dest);
- }
- static int
- prcalled(char *dest, u_char * p)
- {
- int l;
- char *dp = dest;
- p++;
- l = *p++ - 1;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- dp += sprintf(dp, " number digits ");
- while (l--)
- *dp++ = *p++;
- *dp++ = 'n';
- return (dp - dest);
- }
- static int
- prcalling(char *dest, u_char * p)
- {
- int l;
- char *dp = dest;
- p++;
- l = *p++ - 1;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = 'n';
- if (!(*p & 0x80)) {
- dp += sprintf(dp, " octet 3a ");
- dp += prbits(dp, *++p, 8, 8);
- *dp++ = 'n';
- l--;
- };
- p++;
- dp += sprintf(dp, " number digits ");
- while (l--)
- *dp++ = *p++;
- *dp++ = 'n';
- return (dp - dest);
- }
- static
- int
- prbearer(char *dest, u_char * p)
- {
- char *dp = dest, ch;
- p += 2;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- dp += sprintf(dp, " octet 4 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = 'n';
- if ((*p++ & 0x1f) == 0x18) {
- dp += sprintf(dp, " octet 4.1 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- }
- /* check for user information layer 1 */
- if ((*p & 0x60) == 0x20) {
- ch = ' ';
- do {
- dp += sprintf(dp, " octet 5%c ", ch);
- dp += prbits(dp, *p, 8, 8);
- *dp++ = 'n';
- if (ch == ' ')
- ch = 'a';
- else
- ch++;
- }
- while (!(*p++ & 0x80));
- }
- /* check for user information layer 2 */
- if ((*p & 0x60) == 0x40) {
- dp += sprintf(dp, " octet 6 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- }
- /* check for user information layer 3 */
- if ((*p & 0x60) == 0x60) {
- dp += sprintf(dp, " octet 7 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- }
- return (dp - dest);
- }
- static
- int
- prbearer_ni1(char *dest, u_char * p)
- {
- char *dp = dest;
- u_char len;
- p++;
- len = *p++;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p, 8, 8);
- switch (*p++) {
- case 0x80:
- dp += sprintf(dp, " Speech");
- break;
- case 0x88:
- dp += sprintf(dp, " Unrestricted digital information");
- break;
- case 0x90:
- dp += sprintf(dp, " 3.1 kHz audio");
- break;
- default:
- dp += sprintf(dp, " Unknown information-transfer capability");
- }
- *dp++ = 'n';
- dp += sprintf(dp, " octet 4 ");
- dp += prbits(dp, *p, 8, 8);
- switch (*p++) {
- case 0x90:
- dp += sprintf(dp, " 64 kbps, circuit mode");
- break;
- case 0xc0:
- dp += sprintf(dp, " Packet mode");
- break;
- default:
- dp += sprintf(dp, " Unknown transfer mode");
- }
- *dp++ = 'n';
- if (len > 2) {
- dp += sprintf(dp, " octet 5 ");
- dp += prbits(dp, *p, 8, 8);
- switch (*p++) {
- case 0x21:
- dp += sprintf(dp, " Rate adaptionn");
- dp += sprintf(dp, " octet 5a ");
- dp += prbits(dp, *p, 8, 8);
- break;
- case 0xa2:
- dp += sprintf(dp, " u-law");
- break;
- default:
- dp += sprintf(dp, " Unknown UI layer 1 protocol");
- }
- *dp++ = 'n';
- }
- return (dp - dest);
- }
- static int
- general(char *dest, u_char * p)
- {
- char *dp = dest;
- char ch = ' ';
- int l, octet = 3;
- p++;
- l = *p++;
- /* Iterate over all octets in the information element */
- while (l--) {
- dp += sprintf(dp, " octet %d%c ", octet, ch);
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- /* last octet in group? */
- if (*p & 0x80) {
- octet++;
- ch = ' ';
- } else if (ch == ' ')
- ch = 'a';
- else
- ch++;
- }
- return (dp - dest);
- }
- static int
- general_ni1(char *dest, u_char * p)
- {
- char *dp = dest;
- char ch = ' ';
- int l, octet = 3;
- p++;
- l = *p++;
- /* Iterate over all octets in the information element */
- while (l--) {
- dp += sprintf(dp, " octet %d%c ", octet, ch);
- dp += prbits(dp, *p, 8, 8);
- *dp++ = 'n';
- /* last octet in group? */
- if (*p++ & 0x80) {
- octet++;
- ch = ' ';
- } else if (ch == ' ')
- ch = 'a';
- else
- ch++;
- }
- return (dp - dest);
- }
- static int
- prcharge(char *dest, u_char * p)
- {
- char *dp = dest;
- int l;
- p++;
- l = *p++ - 1;
- dp += sprintf(dp, " GEA ");
- dp += prbits(dp, *p++, 8, 8);
- dp += sprintf(dp, " Anzahl: ");
- /* Iterate over all octets in the * information element */
- while (l--)
- *dp++ = *p++;
- *dp++ = 'n';
- return (dp - dest);
- }
- static int
- prtext(char *dest, u_char * p)
- {
- char *dp = dest;
- int l;
- p++;
- l = *p++;
- dp += sprintf(dp, " ");
- /* Iterate over all octets in the * information element */
- while (l--)
- *dp++ = *p++;
- *dp++ = 'n';
- return (dp - dest);
- }
- static int
- prfeatureind(char *dest, u_char * p)
- {
- char *dp = dest;
- p += 2; /* skip id, len */
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = 'n';
- if (!(*p++ & 80)) {
- dp += sprintf(dp, " octet 4 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = 'n';
- }
- dp += sprintf(dp, " Status: ");
- switch (*p) {
- case 0:
- dp += sprintf(dp, "Idle");
- break;
- case 1:
- dp += sprintf(dp, "Active");
- break;
- case 2:
- dp += sprintf(dp, "Prompt");
- break;
- case 3:
- dp += sprintf(dp, "Pending");
- break;
- default:
- dp += sprintf(dp, "(Reserved)");
- break;
- }
- *dp++ = 'n';
- return (dp - dest);
- }
- static
- struct DTag { /* Display tags */
- u_char nr;
- char *descr;
- } dtaglist[] = {
- { 0x82, "Continuation" },
- { 0x83, "Called address" },
- { 0x84, "Cause" },
- { 0x85, "Progress indicator" },
- { 0x86, "Notification indicator" },
- { 0x87, "Prompt" },
- { 0x88, "Accumlated digits" },
- { 0x89, "Status" },
- { 0x8a, "Inband" },
- { 0x8b, "Calling address" },
- { 0x8c, "Reason" },
- { 0x8d, "Calling party name" },
- { 0x8e, "Called party name" },
- { 0x8f, "Orignal called name" },
- { 0x90, "Redirecting name" },
- { 0x91, "Connected name" },
- { 0x92, "Originating restrictions" },
- { 0x93, "Date & time of day" },
- { 0x94, "Call Appearance ID" },
- { 0x95, "Feature address" },
- { 0x96, "Redirection name" },
- { 0x9e, "Text" },
- };
- #define DTAGSIZE sizeof(dtaglist)/sizeof(struct DTag)
- static int
- disptext_ni1(char *dest, u_char * p)
- {
- char *dp = dest;
- int l, tag, len, i;
- p++;
- l = *p++ - 1;
- if (*p++ != 0x80) {
- dp += sprintf(dp, " Unknown display typen");
- return (dp - dest);
- }
- /* Iterate over all tag,length,text fields */
- while (l > 0) {
- tag = *p++;
- len = *p++;
- l -= len + 2;
- /* Don't space or skip */
- if ((tag == 0x80) || (tag == 0x81)) p++;
- else {
- for (i = 0; i < DTAGSIZE; i++)
- if (tag == dtaglist[i].nr)
- break;
- /* When not found, give appropriate msg */
- if (i != DTAGSIZE) {
- dp += sprintf(dp, " %s: ", dtaglist[i].descr);
- while (len--)
- *dp++ = *p++;
- } else {
- dp += sprintf(dp, " (unknown display tag %2x): ", tag);
- while (len--)
- *dp++ = *p++;
- }
- dp += sprintf(dp, "n");
- }
- }
- return (dp - dest);
- }
- static int
- display(char *dest, u_char * p)
- {
- char *dp = dest;
- char ch = ' ';
- int l, octet = 3;
- p++;
- l = *p++;
- /* Iterate over all octets in the * display-information element */
- dp += sprintf(dp, " "");
- while (l--) {
- dp += sprintf(dp, "%c", *p++);
- /* last octet in group? */
- if (*p & 0x80) {
- octet++;
- ch = ' ';
- } else if (ch == ' ')
- ch = 'a';
- else
- ch++;
- }
- *dp++ = '"';
- *dp++ = 'n';
- return (dp - dest);
- }
- int
- prfacility(char *dest, u_char * p)
- {
- char *dp = dest;
- int l, l2;
- p++;
- l = *p++;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p++, 8, 8);
- dp += sprintf(dp, "n");
- l -= 1;
- while (l > 0) {
- dp += sprintf(dp, " octet 4 ");
- dp += prbits(dp, *p++, 8, 8);
- dp += sprintf(dp, "n");
- dp += sprintf(dp, " octet 5 %dn", l2 = *p++ & 0x7f);
- l -= 2;
- dp += sprintf(dp, " contents ");
- while (l2--) {
- dp += sprintf(dp, "%2x ", *p++);
- l--;
- }
- dp += sprintf(dp, "n");
- }
- return (dp - dest);
- }
- static
- struct InformationElement {
- u_char nr;
- char *descr;
- int (*f) (char *, u_char *);
- } ielist[] = {
- {
- 0x00, "Segmented message", general
- },
- {
- 0x04, "Bearer capability", prbearer
- },
- {
- 0x08, "Cause", prcause
- },
- {
- 0x10, "Call identity", general
- },
- {
- 0x14, "Call state", general
- },
- {
- 0x18, "Channel identification", prchident
- },
- {
- 0x1c, "Facility", prfacility
- },
- {
- 0x1e, "Progress indicator", general
- },
- {
- 0x20, "Network-specific facilities", general
- },
- {
- 0x27, "Notification indicator", general
- },
- {
- 0x28, "Display", display
- },
- {
- 0x29, "Date/Time", general
- },
- {
- 0x2c, "Keypad facility", general
- },
- {
- 0x34, "Signal", general
- },
- {
- 0x40, "Information rate", general
- },
- {
- 0x42, "End-to-end delay", general
- },
- {
- 0x43, "Transit delay selection and indication", general
- },
- {
- 0x44, "Packet layer binary parameters", general
- },
- {
- 0x45, "Packet layer window size", general
- },
- {
- 0x46, "Packet size", general
- },
- {
- 0x47, "Closed user group", general
- },
- {
- 0x4a, "Reverse charge indication", general
- },
- {
- 0x6c, "Calling party number", prcalling
- },
- {
- 0x6d, "Calling party subaddress", general
- },
- {
- 0x70, "Called party number", prcalled
- },
- {
- 0x71, "Called party subaddress", general
- },
- {
- 0x74, "Redirecting number", general
- },
- {
- 0x78, "Transit network selection", general
- },
- {
- 0x79, "Restart indicator", general
- },
- {
- 0x7c, "Low layer compatibility", general
- },
- {
- 0x7d, "High layer compatibility", general
- },
- {
- 0x7e, "User-user", general
- },
- {
- 0x7f, "Escape for extension", general
- },
- };
- #define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
- static
- struct InformationElement ielist_ni1[] = {
- { 0x04, "Bearer Capability", prbearer_ni1 },
- { 0x08, "Cause", prcause },
- { 0x14, "Call State", general_ni1 },
- { 0x18, "Channel Identification", prchident },
- { 0x1e, "Progress Indicator", general_ni1 },
- { 0x27, "Notification Indicator", general_ni1 },
- { 0x2c, "Keypad Facility", prtext },
- { 0x32, "Information Request", general_ni1 },
- { 0x34, "Signal", general_ni1 },
- { 0x38, "Feature Activation", general_ni1 },
- { 0x39, "Feature Indication", prfeatureind },
- { 0x3a, "Service Profile Identification (SPID)", prtext },
- { 0x3b, "Endpoint Identifier", general_ni1 },
- { 0x6c, "Calling Party Number", prcalling },
- { 0x6d, "Calling Party Subaddress", general_ni1 },
- { 0x70, "Called Party Number", prcalled },
- { 0x71, "Called Party Subaddress", general_ni1 },
- { 0x74, "Redirecting Number", general_ni1 },
- { 0x78, "Transit Network Selection", general_ni1 },
- { 0x7c, "Low Layer Compatibility", general_ni1 },
- { 0x7d, "High Layer Compatibility", general_ni1 },
- };
- #define IESIZE_NI1 sizeof(ielist_ni1)/sizeof(struct InformationElement)
- static
- struct InformationElement ielist_ni1_cs5[] = {
- { 0x1d, "Operator system access", general_ni1 },
- { 0x2a, "Display text", disptext_ni1 },
- };
- #define IESIZE_NI1_CS5 sizeof(ielist_ni1_cs5)/sizeof(struct InformationElement)
- static
- struct InformationElement ielist_ni1_cs6[] = {
- { 0x7b, "Call appearance", general_ni1 },
- };
- #define IESIZE_NI1_CS6 sizeof(ielist_ni1_cs6)/sizeof(struct InformationElement)
- static struct InformationElement we_0[] =
- {
- {WE0_cause, "Cause", prcause_1tr6},
- {WE0_connAddr, "Connecting Address", prcalled},
- {WE0_callID, "Call IDentity", general},
- {WE0_chanID, "Channel IDentity", general},
- {WE0_netSpecFac, "Network Specific Facility", general},
- {WE0_display, "Display", general},
- {WE0_keypad, "Keypad", general},
- {WE0_origAddr, "Origination Address", prcalled},
- {WE0_destAddr, "Destination Address", prcalled},
- {WE0_userInfo, "User Info", general}
- };
- #define WE_0_LEN (sizeof(we_0) / sizeof(struct InformationElement))
- static struct InformationElement we_6[] =
- {
- {WE6_serviceInd, "Service Indicator", general},
- {WE6_chargingInfo, "Charging Information", prcharge},
- {WE6_date, "Date", prtext},
- {WE6_facSelect, "Facility Select", general},
- {WE6_facStatus, "Facility Status", general},
- {WE6_statusCalled, "Status Called", general},
- {WE6_addTransAttr, "Additional Transmission Attributes", general}
- };
- #define WE_6_LEN (sizeof(we_6) / sizeof(struct InformationElement))
- int
- QuickHex(char *txt, u_char * p, int cnt)
- {
- register int i;
- register char *t = txt;
- register u_char w;
- for (i = 0; i < cnt; i++) {
- *t++ = ' ';
- w = (p[i] >> 4) & 0x0f;
- if (w < 10)
- *t++ = '0' + w;
- else
- *t++ = 'A' - 10 + w;
- w = p[i] & 0x0f;
- if (w < 10)
- *t++ = '0' + w;
- else
- *t++ = 'A' - 10 + w;
- }
- *t++ = 0;
- return (t - txt);
- }
- void
- LogFrame(struct IsdnCardState *cs, u_char * buf, int size)
- {
- char *dp;
- if (size < 1)
- return;
- dp = cs->dlog;
- if (size < MAX_DLOG_SPACE / 3 - 10) {
- *dp++ = 'H';
- *dp++ = 'E';
- *dp++ = 'X';
- *dp++ = ':';
- dp += QuickHex(dp, buf, size);
- dp--;
- *dp++ = 'n';
- *dp = 0;
- HiSax_putstatus(cs, NULL, cs->dlog);
- } else
- HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size);
- }
- void
- dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
- {
- u_char *bend, *buf;
- char *dp;
- unsigned char pd, cr_l, cr, mt;
- unsigned char sapi, tei, ftyp;
- int i, cset = 0, cs_old = 0, cs_fest = 0;
- int size, finish = 0;
- if (skb->len < 3)
- return;
- /* display header */
- dp = cs->dlog;
- dp += jiftime(dp, jiffies);
- *dp++ = ' ';
- sapi = skb->data[0] >> 2;
- tei = skb->data[1] >> 1;
- ftyp = skb->data[2];
- buf = skb->data;
- dp += sprintf(dp, "frame %s ", dir ? "network->user" : "user->network");
- size = skb->len;
-
- if (tei == GROUP_TEI) {
- if (sapi == CTRL_SAPI) { /* sapi 0 */
- if (ftyp == 3) {
- dp += sprintf(dp, "broadcastn");
- buf += 3;
- size -= 3;
- } else {
- dp += sprintf(dp, "no UI broadcastn");
- finish = 1;
- }
- } else if (sapi == TEI_SAPI) {
- dp += sprintf(dp, "tei managementn");
- finish = 1;
- } else {
- dp += sprintf(dp, "unknown sapi %d broadcastn", sapi);
- finish = 1;
- }
- } else {
- if (sapi == CTRL_SAPI) {
- if (!(ftyp & 1)) { /* IFrame */
- dp += sprintf(dp, "with tei %dn", tei);
- buf += 4;
- size -= 4;
- } else {
- dp += sprintf(dp, "SFrame with tei %dn", tei);
- finish = 1;
- }
- } else {
- dp += sprintf(dp, "unknown sapi %d tei %dn", sapi, tei);
- finish = 1;
- }
- }
- bend = skb->data + skb->len;
- if (buf >= bend) {
- dp += sprintf(dp, "frame too shortn");
- finish = 1;
- }
- if (finish) {
- *dp = 0;
- HiSax_putstatus(cs, NULL, cs->dlog);
- return;
- }
- if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */
- /* locate message type */
- pd = *buf++;
- cr_l = *buf++;
- if (cr_l)
- cr = *buf++;
- else
- cr = 0;
- mt = *buf++;
- if (pd == PROTO_DIS_N0) { /* N0 */
- for (i = 0; i < MT_N0_LEN; i++)
- if (mt_n0[i].nr == mt)
- break;
- /* display message type if it exists */
- if (i == MT_N0_LEN)
- dp += sprintf(dp, "callref %d %s size %d unknown message type N0 %x!n",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mt);
- else
- dp += sprintf(dp, "callref %d %s size %d message type %sn",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mt_n0[i].descr);
- } else { /* N1 */
- for (i = 0; i < MT_N1_LEN; i++)
- if (mt_n1[i].nr == mt)
- break;
- /* display message type if it exists */
- if (i == MT_N1_LEN)
- dp += sprintf(dp, "callref %d %s size %d unknown message type N1 %x!n",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mt);
- else
- dp += sprintf(dp, "callref %d %s size %d message type %sn",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mt_n1[i].descr);
- }
- /* display each information element */
- while (buf < bend) {
- /* Is it a single octet information element? */
- if (*buf & 0x80) {
- switch ((*buf >> 4) & 7) {
- case 1:
- dp += sprintf(dp, " Shift %xn", *buf & 0xf);
- cs_old = cset;
- cset = *buf & 7;
- cs_fest = *buf & 8;
- break;
- case 3:
- dp += sprintf(dp, " Congestion level %xn", *buf & 0xf);
- break;
- case 2:
- if (*buf == 0xa0) {
- dp += sprintf(dp, " More datan");
- break;
- }
- if (*buf == 0xa1) {
- dp += sprintf(dp, " Sending completen");
- }
- break;
- /* fall through */
- default:
- dp += sprintf(dp, " Reserved %xn", *buf);
- break;
- }
- buf++;
- continue;
- }
- /* No, locate it in the table */
- if (cset == 0) {
- for (i = 0; i < WE_0_LEN; i++)
- if (*buf == we_0[i].nr)
- break;
- /* When found, give appropriate msg */
- if (i != WE_0_LEN) {
- dp += sprintf(dp, " %sn", we_0[i].descr);
- dp += we_0[i].f(dp, buf);
- } else
- dp += sprintf(dp, " Codeset %d attribute %x attribute size %dn", cset, *buf, buf[1]);
- } else if (cset == 6) {
- for (i = 0; i < WE_6_LEN; i++)
- if (*buf == we_6[i].nr)
- break;
- /* When found, give appropriate msg */
- if (i != WE_6_LEN) {
- dp += sprintf(dp, " %sn", we_6[i].descr);
- dp += we_6[i].f(dp, buf);
- } else
- dp += sprintf(dp, " Codeset %d attribute %x attribute size %dn", cset, *buf, buf[1]);
- } else
- dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %dn", cset, *buf, buf[1]);
- /* Skip to next element */
- if (cs_fest == 8) {
- cset = cs_old;
- cs_old = 0;
- cs_fest = 0;
- }
- buf += buf[1] + 2;
- }
- } else if ((buf[0] == 8) && (cs->protocol == ISDN_PTYPE_NI1)) { /* NI-1 */
- /* locate message type */
- buf++;
- cr_l = *buf++;
- if (cr_l)
- cr = *buf++;
- else
- cr = 0;
- mt = *buf++;
- for (i = 0; i < MTSIZE; i++)
- if (mtlist[i].nr == mt)
- break;
- /* display message type if it exists */
- if (i == MTSIZE)
- dp += sprintf(dp, "callref %d %s size %d unknown message type %x!n",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mt);
- else
- dp += sprintf(dp, "callref %d %s size %d message type %sn",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mtlist[i].descr);
- /* display each information element */
- while (buf < bend) {
- /* Is it a single octet information element? */
- if (*buf & 0x80) {
- switch ((*buf >> 4) & 7) {
- case 1:
- dp += sprintf(dp, " Shift %xn", *buf & 0xf);
- cs_old = cset;
- cset = *buf & 7;
- cs_fest = *buf & 8;
- break;
- default:
- dp += sprintf(dp, " Unknown single-octet IE %xn", *buf);
- break;
- }
- buf++;
- continue;
- }
- /* No, locate it in the table */
- if (cset == 0) {
- for (i = 0; i < IESIZE; i++)
- if (*buf == ielist_ni1[i].nr)
- break;
- /* When not found, give appropriate msg */
- if (i != IESIZE) {
- dp += sprintf(dp, " %sn", ielist_ni1[i].descr);
- dp += ielist_ni1[i].f(dp, buf);
- } else
- dp += sprintf(dp, " attribute %x attribute size %dn", *buf, buf[1]);
- } else if (cset == 5) {
- for (i = 0; i < IESIZE_NI1_CS5; i++)
- if (*buf == ielist_ni1_cs5[i].nr)
- break;
- /* When not found, give appropriate msg */
- if (i != IESIZE_NI1_CS5) {
- dp += sprintf(dp, " %sn", ielist_ni1_cs5[i].descr);
- dp += ielist_ni1_cs5[i].f(dp, buf);
- } else
- dp += sprintf(dp, " attribute %x attribute size %dn", *buf, buf[1]);
- } else if (cset == 6) {
- for (i = 0; i < IESIZE_NI1_CS6; i++)
- if (*buf == ielist_ni1_cs6[i].nr)
- break;
- /* When not found, give appropriate msg */
- if (i != IESIZE_NI1_CS6) {
- dp += sprintf(dp, " %sn", ielist_ni1_cs6[i].descr);
- dp += ielist_ni1_cs6[i].f(dp, buf);
- } else
- dp += sprintf(dp, " attribute %x attribute size %dn", *buf, buf[1]);
- } else
- dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %dn", cset, *buf, buf[1]);
- /* Skip to next element */
- if (cs_fest == 8) {
- cset = cs_old;
- cs_old = 0;
- cs_fest = 0;
- }
- buf += buf[1] + 2;
- }
- } else if ((buf[0] == 8) && (cs->protocol == ISDN_PTYPE_EURO)) { /* EURO */
- /* locate message type */
- buf++;
- cr_l = *buf++;
- if (cr_l)
- cr = *buf++;
- else
- cr = 0;
- mt = *buf++;
- for (i = 0; i < MTSIZE; i++)
- if (mtlist[i].nr == mt)
- break;
- /* display message type if it exists */
- if (i == MTSIZE)
- dp += sprintf(dp, "callref %d %s size %d unknown message type %x!n",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mt);
- else
- dp += sprintf(dp, "callref %d %s size %d message type %sn",
- cr & 0x7f, (cr & 0x80) ? "called" : "caller",
- size, mtlist[i].descr);
- /* display each information element */
- while (buf < bend) {
- /* Is it a single octet information element? */
- if (*buf & 0x80) {
- switch ((*buf >> 4) & 7) {
- case 1:
- dp += sprintf(dp, " Shift %xn", *buf & 0xf);
- break;
- case 3:
- dp += sprintf(dp, " Congestion level %xn", *buf & 0xf);
- break;
- case 5:
- dp += sprintf(dp, " Repeat indicator %xn", *buf & 0xf);
- break;
- case 2:
- if (*buf == 0xa0) {
- dp += sprintf(dp, " More datan");
- break;
- }
- if (*buf == 0xa1) {
- dp += sprintf(dp, " Sending completen");
- }
- break;
- /* fall through */
- default:
- dp += sprintf(dp, " Reserved %xn", *buf);
- break;
- }
- buf++;
- continue;
- }
- /* No, locate it in the table */
- for (i = 0; i < IESIZE; i++)
- if (*buf == ielist[i].nr)
- break;
- /* When not found, give appropriate msg */
- if (i != IESIZE) {
- dp += sprintf(dp, " %sn", ielist[i].descr);
- dp += ielist[i].f(dp, buf);
- } else
- dp += sprintf(dp, " attribute %x attribute size %dn", *buf, buf[1]);
- /* Skip to next element */
- buf += buf[1] + 2;
- }
- } else {
- dp += sprintf(dp, "Unknown protocol %x!", buf[0]);
- }
- *dp = 0;
- HiSax_putstatus(cs, NULL, cs->dlog);
- }