📄 q931.c
字号:
prefix, ie->data[2] >> 7, redirection_reason2str(ie->data[2] & 0x7f), ie->data[2] & 0x7f); break; } } while(!(ie->data[i++]& 0x80)); q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i); pri_message(" '%s' ]\n", cnum);}static FUNC_DUMP(dump_connected_number){ char cnum[256]; int i = 0; /* To follow Q.931 (4.5.1), we must search for start of octet 4 by walking through all bytes until one with ext bit (8) set to 1 */ do { switch(i) { case 0: /* Octet 3 */ pri_message("%c Connected Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d)", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f); break; case 1: /* Octet 3a */ pri_message("\n%c Ext: %d Presentation: %s (%d)", prefix, ie->data[1] >> 7, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f); break; } } while(!(ie->data[i++]& 0x80)); q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i); pri_message(" '%s' ]\n", cnum);}static FUNC_RECV(receive_redirecting_number){ int i = 0; /* To follow Q.931 (4.5.1), we must search for start of octet 4 by walking through all bytes until one with ext bit (8) set to 1 */ do { switch(i) { case 0: call->redirectingplan = ie->data[i] & 0x7f; break; case 1: call->redirectingpres = ie->data[i] & 0x7f; break; case 2: call->redirectingreason = ie->data[i] & 0x0f; break; } } while(!(ie->data[i++] & 0x80)); q931_get_number(call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i); return 0;}static FUNC_DUMP(dump_redirecting_subaddr){ char cnum[256]; q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4); pri_message("%c Redirecting Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n", prefix, len, ie->data[0] >> 7, subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4, (ie->data[0] & 0x08) >> 3, cnum);}static FUNC_RECV(receive_calling_party_subaddr){ /* copy digits to call->callingsubaddr */ q931_get_number(call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 2, len - 4); return 0;}static FUNC_RECV(receive_called_party_number){ /* copy digits to call->callednum */ q931_get_number(call->callednum, sizeof(call->callednum), ie->data + 1, len - 3); call->calledplan = ie->data[0] & 0x7f; return 0;}static FUNC_SEND(transmit_called_party_number){ ie->data[0] = 0x80 | call->calledplan; if (strlen(call->callednum)) memcpy(ie->data + 1, call->callednum, strlen(call->callednum)); return strlen(call->callednum) + 3;}static FUNC_RECV(receive_calling_party_number){ int extbit; call->callerplan = ie->data[0] & 0x7f; extbit = (ie->data[0] >> 7) & 0x01; if (extbit) { q931_get_number(call->callernum, sizeof(call->callernum), ie->data + 1, len - 3); call->callerpres = 0; /* PI presentation allowed SI user-provided, not screened */ } else { q931_get_number(call->callernum, sizeof(call->callernum), ie->data + 2, len - 4); call->callerpres = ie->data[1] & 0x7f; } return 0;}static FUNC_SEND(transmit_calling_party_number){ ie->data[0] = call->callerplan; ie->data[1] = 0x80 | call->callerpres; if (strlen(call->callernum)) memcpy(ie->data + 2, call->callernum, strlen(call->callernum)); return strlen(call->callernum) + 4;}static FUNC_DUMP(dump_user_user){ int x; pri_message("%c User-User Information (len=%2d) [", prefix, len); for (x=0;x<ie->len;x++) pri_message(" %02x", ie->data[x] & 0x7f); pri_message(" ]\n");}static FUNC_RECV(receive_user_user){ call->useruserprotocoldisc = ie->data[0] & 0xff; if (call->useruserprotocoldisc == 4) /* IA5 */ q931_get_number(call->useruserinfo, sizeof(call->useruserinfo), ie->data + 1, len - 3); return 0;}static char *prog2str(int prog){ static struct msgtype progs[] = { { Q931_PROG_CALL_NOT_E2E_ISDN, "Call is not end-to-end ISDN; further call progress information may be available inband." }, { Q931_PROG_CALLED_NOT_ISDN, "Called equipment is non-ISDN." }, { Q931_PROG_CALLER_NOT_ISDN, "Calling equipment is non-ISDN." }, { Q931_PROG_INBAND_AVAILABLE, "Inband information or appropriate pattern now available." }, { Q931_PROG_DELAY_AT_INTERF, "Delay in response at called Interface." }, { Q931_PROG_INTERWORKING_WITH_PUBLIC, "Interworking with a public network." }, { Q931_PROG_INTERWORKING_NO_RELEASE, "Interworking with a network unable to supply a release signal." }, { Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER, "Interworking with a network unable to supply a release signal before answer." }, { Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER, "Interworking with a network unable to supply a release signal after answer." }, }; return code2str(prog, progs, sizeof(progs) / sizeof(progs[0]));}static char *coding2str(int cod){ static struct msgtype cods[] = { { CODE_CCITT, "CCITT (ITU) standard" }, { CODE_INTERNATIONAL, "Non-ITU international standard" }, { CODE_NATIONAL, "National standard" }, { CODE_NETWORK_SPECIFIC, "Network specific standard" }, }; return code2str(cod, cods, sizeof(cods) / sizeof(cods[0]));}static char *loc2str(int loc){ static struct msgtype locs[] = { { LOC_USER, "User" }, { LOC_PRIV_NET_LOCAL_USER, "Private network serving the local user" }, { LOC_PUB_NET_LOCAL_USER, "Public network serving the local user" }, { LOC_TRANSIT_NET, "Transit network" }, { LOC_PUB_NET_REMOTE_USER, "Public network serving the remote user" }, { LOC_PRIV_NET_REMOTE_USER, "Private network serving the remote user" }, { LOC_INTERNATIONAL_NETWORK, "International network" }, { LOC_NETWORK_BEYOND_INTERWORKING, "Network beyond the interworking point" }, }; return code2str(loc, locs, sizeof(locs) / sizeof(locs[0]));}static FUNC_DUMP(dump_progress_indicator){ pri_message("%c Progress Indicator (len=%2d) [ Ext: %d Coding: %s (%d) 0: %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("%c Ext: %d Progress Description: %s (%d) ]\n", prefix, ie->data[1] >> 7, prog2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f);}static FUNC_RECV(receive_display){ unsigned char *data; data = ie->data; if (data[0] & 0x80) { /* Skip over character set */ data++; len--; } q931_get_number(call->callername, sizeof(call->callername), data, len - 2); return 0;}static FUNC_SEND(transmit_display){ int i; if ((pri->switchtype != PRI_SWITCH_NI1) && strlen(call->callername)) { i = 0; if(pri->switchtype != PRI_SWITCH_EUROISDN_E1) { ie->data[0] = 0xb1; ++i; } memcpy(ie->data + i, call->callername, strlen(call->callername)); return 2 + i + strlen(call->callername); } return 0;}static FUNC_RECV(receive_progress_indicator){ call->progloc = ie->data[0] & 0xf; call->progcode = (ie->data[0] & 0x60) >> 5; call->progress = (ie->data[1] & 0x7f); return 0;}static FUNC_RECV(receive_facility){ if (ie->len < 14) { pri_error("!! Facility message shorter than 14 bytes\n"); return 0; } if (ie->data[13] + 14 == ie->len) { q931_get_number(call->callername, sizeof(call->callername) - 1, ie->data + 14, ie->len - 14); } return 0;}static FUNC_SEND(transmit_progress_indicator){ /* Can't send progress indicator on GR-303 -- EVER! */ if (!pri->subchannel && (call->progress > 0)) { ie->data[0] = 0x80 | (call->progcode << 5) | (call->progloc); ie->data[1] = 0x80 | (call->progress); return 4; } else { /* Leave off */ return 0; }}static FUNC_SEND(transmit_call_state){ if (call->ourcallstate > -1 ) { ie->data[0] = call->ourcallstate; return 3; } return 0;}static FUNC_RECV(receive_call_state){ call->sugcallstate = ie->data[0] & 0x3f; return 0;}static char *callstate2str(int callstate){ static struct msgtype callstates[] = { { 0, "Null" }, { 1, "Call Initiated" }, { 2, "Overlap sending" }, { 3, "Outgoing call Proceeding" }, { 4, "Call Delivered" }, { 6, "Call Present" }, { 7, "Call Received" }, { 8, "Connect Request" }, { 9, "Incoming Call Proceeding" }, { 10, "Active" }, { 11, "Disconnect Request" }, { 12, "Disconnect Indication" }, { 15, "Suspend Request" }, { 17, "Resume Request" }, { 19, "Release Request" }, { 22, "Call Abort" }, { 25, "Overlap Receiving" }, { 61, "Restart Request" }, { 62, "Restart" }, }; return code2str(callstate, callstates, sizeof(callstates) / sizeof(callstates[0]));}static FUNC_DUMP(dump_call_state){ pri_message("%c Call State (len=%2d) [ Ext: %d Coding: %s (%d) Call state: %s (%d)\n", prefix, len, ie->data[0] >> 7, coding2str((ie->data[0] & 0xC0) >> 6), (ie->data[0] & 0xC0) >> 6, callstate2str(ie->data[0] & 0x3f), ie->data[0] & 0x3f);}static FUNC_DUMP(dump_call_identity){ int x; pri_message("%c Call Identity (len=%2d) [ ", prefix, len); for (x=0;x<ie->len;x++) pri_message("0x%02X ", ie->data[x]); pri_message(" ]\n");}static FUNC_DUMP(dump_time_date){ pri_message("%c Time Date (len=%2d) [ ", prefix, len); if (ie->len > 0) pri_message("%02d", ie->data[0]); if (ie->len > 1) pri_message("-%02d", ie->data[1]); if (ie->len > 2) pri_message("-%02d", ie->data[2]); if (ie->len > 3) pri_message(" %02d", ie->data[3]); if (ie->len > 4) pri_message(":%02d", ie->data[4]); if (ie->len > 5) pri_message(":%02d", ie->data[5]); pri_message(" ]\n");}static FUNC_DUMP(dump_display){ int x, y; char *buf = malloc(len + 1); char tmp[80]=""; if (buf) { x=y=0; if ((x < ie->len) && (ie->data[x] & 0x80)) { sprintf(tmp, "Charset: %02x ", ie->data[x] & 0x7f); ++x; } for (y=x; x<ie->len; x++) buf[x] = ie->data[x] & 0x7f; buf[x] = '\0'; pri_message("%c Display (len=%2d) %s[ %s ]\n", prefix, ie->len, tmp, &buf[y]); free(buf); }}static void dump_ie_data(unsigned char *c, int len){ char tmp[1024] = ""; int x=0; int lastascii = 0; while(len) { if (((*c >= 'A') && (*c <= 'Z')) || ((*c >= 'a') && (*c <= 'z')) || ((*c >= '0') && (*c <= '9'))) { if (!lastascii) { if (strlen(tmp)) { tmp[x++] = ','; tmp[x++] = ' '; } tmp[x++] = '\''; } tmp[x++] = *c; lastascii = 1; } else { if (lastascii) { tmp[x++] = '\''; } if (strlen(tmp)) { tmp[x++] = ','; tmp[x++] = ' '; } sprintf (tmp + x, "0x%02x", *c); x += 4; lastascii = 0; } c++; len--; } if (lastascii) tmp[x++] = '\''; pri_message(tmp);}static FUNC_DUMP(dump_facility){ pri_message("%c Facility (len=%2d, codeset=%d) [ ", prefix, len, Q931_IE_CODESET(full_ie)); dump_ie_data(ie->data, ie->len); pri_message(" ]\n");}static FUNC_DUMP(dump_network_spec_fac){ pri_message("%c Network-Specific Facilities (len=%2d) [ ", prefix, ie->len); if (ie->data[0] == 0x00) { pri_message (code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0]))); } else dump_ie_data(ie->data, ie->len); pri_message(" ]\n");}static FUNC_RECV(receive_network_spec_fac){ return 0;}static FUNC_SEND(transmit_network_spec_fac){ if (pri->nsf != PRI_NSF_NONE) { ie->data[0] = 0x00; ie->data[1] = pri->nsf; return 4; } else { /* Leave off */ return 0; }}char *pri_cause2str(int cause){ return code2str(cause, causes, sizeof(causes) / sizeof(causes[0]));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -