📄 q931.c
字号:
if (order > 1) return 0; if (pri->nsf != PRI_NSF_NONE) { ie->data[0] = 0x00; ie->data[1] = pri->nsf; return 4; } /* Leave off */ return 0;}char *pri_cause2str(int cause){ return code2str(cause, causes, sizeof(causes) / sizeof(causes[0]));}static char *pri_causeclass2str(int cause){ static struct msgtype causeclasses[] = { { 0, "Normal Event" }, { 1, "Normal Event" }, { 2, "Network Congestion (resource unavailable)" }, { 3, "Service or Option not Available" }, { 4, "Service or Option not Implemented" }, { 5, "Invalid message (e.g. parameter out of range)" }, { 6, "Protocol Error (e.g. unknown message)" }, { 7, "Interworking" }, }; return code2str(cause, causeclasses, sizeof(causeclasses) / sizeof(causeclasses[0]));}static FUNC_DUMP(dump_cause){ int x; pri_message(pri, "%c Cause (len=%2d) [ Ext: %d Coding: %s (%d) Spare: %d Location: %s (%d)\n", prefix, len, ie->data[0] >> 7, coding2str((ie->data[0] & 0x60) >> 5), (ie->data[0] & 0x60) >> 5, (ie->data[0] & 0x10) >> 4, loc2str(ie->data[0] & 0xf), ie->data[0] & 0xf); pri_message(pri, "%c Ext: %d Cause: %s (%d), class = %s (%d) ]\n", prefix, (ie->data[1] >> 7), pri_cause2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, pri_causeclass2str((ie->data[1] & 0x7f) >> 4), (ie->data[1] & 0x7f) >> 4); if (ie->len < 3) return; /* Dump cause data in readable form */ switch(ie->data[1] & 0x7f) { case PRI_CAUSE_IE_NONEXIST: for (x=2;x<ie->len;x++) pri_message(pri, "%c Cause data %d: %02x (%d, %s IE)\n", prefix, x-1, ie->data[x], ie->data[x], ie2str(ie->data[x])); break; case PRI_CAUSE_WRONG_CALL_STATE: for (x=2;x<ie->len;x++) pri_message(pri, "%c Cause data %d: %02x (%d, %s message)\n", prefix, x-1, ie->data[x], ie->data[x], msg2str(ie->data[x])); break; case PRI_CAUSE_RECOVERY_ON_TIMER_EXPIRE: pri_message(pri, "%c Cause data:", prefix); for (x=2;x<ie->len;x++) pri_message(pri, " %02x", ie->data[x]); pri_message(pri, " (Timer T"); for (x=2;x<ie->len;x++) pri_message(pri, "%c", ((ie->data[x] >= ' ') && (ie->data[x] < 0x7f)) ? ie->data[x] : '.'); pri_message(pri, ")\n"); break; default: for (x=2;x<ie->len;x++) pri_message(pri, "%c Cause data %d: %02x (%d)\n", prefix, x-1, ie->data[x], ie->data[x]); break; }}static FUNC_RECV(receive_cause){ call->causeloc = ie->data[0] & 0xf; call->causecode = (ie->data[0] & 0x60) >> 5; call->cause = (ie->data[1] & 0x7f); return 0;}static FUNC_SEND(transmit_cause){ /* We are ready to transmit single IE only */ if (order > 1) return 0; if (call->cause > 0) { ie->data[0] = 0x80 | (call->causecode << 5) | (call->causeloc); ie->data[1] = 0x80 | (call->cause); return 4; } else { /* Leave off */ return 0; }}static FUNC_DUMP(dump_sending_complete){ pri_message(pri, "%c Sending Complete (len=%2d)\n", prefix, len);}static FUNC_RECV(receive_sending_complete){ /* We've got a "Complete" message: Exect no further digits. */ call->complete = 1; return 0;}static FUNC_SEND(transmit_sending_complete){ if ((pri->overlapdial && call->complete) || /* Explicit */ (!pri->overlapdial && ((pri->switchtype == PRI_SWITCH_EUROISDN_E1) || /* Implicit */ (pri->switchtype == PRI_SWITCH_EUROISDN_T1)))) { /* Include this single-byte IE */ return 1; } return 0;}static char *notify2str(int info){ /* ITU-T Q.763 */ static struct msgtype notifies[] = { { PRI_NOTIFY_USER_SUSPENDED, "User suspended" }, { PRI_NOTIFY_USER_RESUMED, "User resumed" }, { PRI_NOTIFY_BEARER_CHANGE, "Bearer service change (DSS1)" }, { PRI_NOTIFY_ASN1_COMPONENT, "ASN.1 encoded component (DSS1)" }, { PRI_NOTIFY_COMPLETION_DELAY, "Call completion delay" }, { PRI_NOTIFY_CONF_ESTABLISHED, "Conference established" }, { PRI_NOTIFY_CONF_DISCONNECTED, "Conference disconnected" }, { PRI_NOTIFY_CONF_PARTY_ADDED, "Other party added" }, { PRI_NOTIFY_CONF_ISOLATED, "Isolated" }, { PRI_NOTIFY_CONF_REATTACHED, "Reattached" }, { PRI_NOTIFY_CONF_OTHER_ISOLATED, "Other party isolated" }, { PRI_NOTIFY_CONF_OTHER_REATTACHED, "Other party reattached" }, { PRI_NOTIFY_CONF_OTHER_SPLIT, "Other party split" }, { PRI_NOTIFY_CONF_OTHER_DISCONNECTED, "Other party disconnected" }, { PRI_NOTIFY_CONF_FLOATING, "Conference floating" }, { PRI_NOTIFY_WAITING_CALL, "Call is waiting call" }, { PRI_NOTIFY_DIVERSION_ACTIVATED, "Diversion activated (DSS1)" }, { PRI_NOTIFY_TRANSFER_ALERTING, "Call transfer, alerting" }, { PRI_NOTIFY_TRANSFER_ACTIVE, "Call transfer, active" }, { PRI_NOTIFY_REMOTE_HOLD, "Remote hold" }, { PRI_NOTIFY_REMOTE_RETRIEVAL, "Remote retrieval" }, { PRI_NOTIFY_CALL_DIVERTING, "Call is diverting" }, }; return code2str(info, notifies, sizeof(notifies) / sizeof(notifies[0]));}static FUNC_DUMP(dump_notify){ pri_message(pri, "%c Notification indicator (len=%2d): Ext: %d %s (%d)\n", prefix, len, ie->data[0] >> 7, notify2str(ie->data[0] & 0x7f), ie->data[0] & 0x7f);}static FUNC_RECV(receive_notify){ call->notify = ie->data[0] & 0x7F; return 0;}static FUNC_SEND(transmit_notify){ if (call->notify >= 0) { ie->data[0] = 0x80 | call->notify; return 3; } return 0;}static FUNC_DUMP(dump_shift){ pri_message(pri, "%c %sLocking Shift (len=%02d): Requested codeset %d\n", prefix, (full_ie & 8) ? "Non-" : "", len, full_ie & 7);}static char *lineinfo2str(int info){ /* NAPNA ANI II digits */ static struct msgtype lineinfo[] = { { 0, "Plain Old Telephone Service (POTS)" }, { 1, "Multiparty line (more than 2)" }, { 2, "ANI failure" }, { 6, "Station Level Rating" }, { 7, "Special Operator Handling Required" }, { 20, "Automatic Identified Outward Dialing (AIOD)" }, { 23, "Coing or Non-Coin" }, { 24, "Toll free translated to POTS originated for non-pay station" }, { 25, "Toll free translated to POTS originated from pay station" }, { 27, "Pay station with coin control signalling" }, { 29, "Prison/Inmate Service" }, { 30, "Intercept (blank)" }, { 31, "Intercept (trouble)" }, { 32, "Intercept (regular)" }, { 34, "Telco Operator Handled Call" }, { 52, "Outward Wide Area Telecommunications Service (OUTWATS)" }, { 60, "TRS call from unrestricted line" }, { 61, "Cellular/Wireless PCS (Type 1)" }, { 62, "Cellular/Wireless PCS (Type 2)" }, { 63, "Cellular/Wireless PCS (Roaming)" }, { 66, "TRS call from hotel/motel" }, { 67, "TRS call from restricted line" }, { 70, "Line connected to pay station" }, { 93, "Private virtual network call" }, }; return code2str(info, lineinfo, sizeof(lineinfo) / sizeof(lineinfo[0]));}static FUNC_DUMP(dump_line_information){ pri_message(pri, "%c Originating Line Information (len=%02d): %s (%d)\n", prefix, len, lineinfo2str(ie->data[0]), ie->data[0]);}static FUNC_RECV(receive_line_information){ call->ani2 = ie->data[0]; return 0;}static FUNC_SEND(transmit_line_information){#if 0 /* XXX Is this IE possible for 4ESS only? XXX */ if(pri->switchtype == PRI_SWITCH_ATT4ESS) { ie->data[0] = 0; return 3; }#endif return 0;}static char *gdencoding2str(int encoding){ static struct msgtype gdencoding[] = { { 0, "BCD even" }, { 1, "BCD odd" }, { 2, "IA5" }, { 3, "Binary" }, }; return code2str(encoding, gdencoding, sizeof(gdencoding) / sizeof(gdencoding[0]));}static char *gdtype2str(int type){ static struct msgtype gdtype[] = { { 0, "Account Code" }, { 1, "Auth Code" }, { 2, "Customer ID" }, { 3, "Universal Access" }, { 4, "Info Digits" }, { 5, "Callid" }, { 6, "Opart" }, { 7, "TCN" }, { 9, "Adin" }, }; return code2str(type, gdtype, sizeof(gdtype) / sizeof(gdtype[0]));}static FUNC_DUMP(dump_generic_digits){ int encoding; int type; int idx; int value; if (len < 3) { pri_message(pri, "%c Generic Digits (len=%02d): Invalid length\n", prefix, len); return; } encoding = (ie->data[0] >> 5) & 7; type = ie->data[0] & 0x1F; pri_message(pri, "%c Generic Digits (len=%02d): Encoding %s Type %s\n", prefix, len, gdencoding2str(encoding), gdtype2str(type)); if (encoding == 3) { /* Binary */ pri_message(pri, "%c Don't know how to handle binary encoding\n"); return; } if (len == 3) /* No number information */ return; pri_message(pri, "%c Digits: "); value = 0; for(idx = 3; idx < len; ++idx) { switch(encoding) { case 0: /* BCD even */ case 1: /* BCD odd */ pri_message(pri, "%d", ie->data[idx-2] & 0x0f); value = value * 10 + (ie->data[idx-2] & 0x0f); if(!encoding || (idx+1 < len)) { /* Special handling for BCD odd */ pri_message(pri, "%d", (ie->data[idx-2] >> 4) & 0x0f); value = value * 10 + ((ie->data[idx-2] >> 4) & 0x0f); } break; case 2: /* IA5 */ pri_message(pri, "%c", ie->data[idx-2]); value = value * 10 + ie->data[idx-2] - '0'; break; } } switch(type) { case 4: /* Info Digits */ pri_message(pri, " - %s", lineinfo2str(value)); break; } pri_message(pri, "\n");}static FUNC_RECV(receive_generic_digits){ int encoding; int type; int idx; int value; int num_idx; char number[260]; if (len < 3) { pri_error(pri, "Invalid length of Generic Digits IE\n"); return -1; } encoding = (ie->data[0] >> 5) & 7; type = ie->data[0] & 0x1F; if (encoding == 3) { /* Binary */ pri_message(pri, "!! Unable to handle binary encoded Generic Digits IE\n"); return 0; } if (len == 3) /* No number information */ return 0; value = 0; switch(type) { /* Integer value handling */ case 4: /* Info Digits */ for(idx = 3; idx < len; ++idx) { switch(encoding) { case 0: /* BCD even */ case 1: /* BCD odd */ value = value * 10 + (ie->data[idx-2] & 0x0f); if(!encoding || (idx+1 < len)) /* Special handling for BCD odd */ value = value * 10 + ((ie->data[idx-2] >> 4) & 0x0f); break; case 2: /* IA5 */ value = value * 10 + (ie->data[idx-2] - '0'); break; } } break; /* String value handling */ case 5: /* Callid */ num_idx = 0; for(idx = 3; (idx < len) && (num_idx < sizeof(number) - 4); ++idx) { switch(encoding) { case 0: /* BCD even */ case 1: /* BCD odd */ number[num_idx++] = '0' + (ie->data[idx-2] & 0x0f); if(!encoding || (idx+1 < len)) /* Special handling for BCD odd */ number[num_idx++] = '0' + ((ie->data[idx-2] >> 4) & 0x0f); break; case 2: number[num_idx++] = ie->data[idx-2]; break; } } number[num_idx] = '\0'; break; } switch(type) { case 4: /* Info Digits */ call->ani2 = value; break;#if 0 case 5: /* Callid */ if (!call->callernum[0]) { memcpy(call->callernum, number, sizeof(call->callernum)-1); call->callerpres = 0; call->callerplan = 0; } break;#endif } return 0;}static FUNC_SEND(transmit_generic_digits){#if 0 /* XXX Is this IE possible for other switches? XXX */ if (order > 1) return 0; if(pri->switchtype == PRI_SWITCH_NI1) { ie->data[0] = 0x04; /* BCD even, Info Digits */ ie->data[1] = 0x00; /* POTS */ return 4; }#endif return 0;}static char *signal2str(int signal){ /* From Q.931 4.5.8 Table 4-24 */ static struct msgtype mtsignal[] = { { 0, "Dial tone" }, { 1, "Ring back tone" }, { 2, "Intercept tone" }, { 3, "Network congestion tone" }, { 4, "Busy tone" }, { 5, "Confirm tone" }, { 6, "Answer tone" }, { 7, "Call waiting tone" }, { 8, "Off-hook warning tone" }, { 9, "Pre-emption tone" }, { 63, "Tones off" }, { 64, "Alerting on - pattern 0" }, { 65, "Alerting on - pattern 1" }, { 66, "Alerting on - pattern 2" }, { 67, "Alerting on - pattern 3" }, { 68, "Alerting on - pattern 4" }, { 69, "Alerting on - pattern 5" }, { 70, "Alerting on - pattern 6" }, { 71, "Alerting on - pattern 7" }, { 79, "Alerting off" }, }; return code2str(signal, mtsignal, sizeof(mtsignal) / sizeof(mtsignal[0]));}static FUNC_DUMP(dump_signal){ pri_message(pri, "%c Signal (len=%02d): ", pre
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -