📄 q931.c
字号:
if (call->userl3 != -1) ie->data[pos++] = 0xe0 | (call->userl3 & 0x1f); return pos + 2;}char *pri_plan2str(int plan){ static struct msgtype plans[] = { { PRI_INTERNATIONAL_ISDN, "International number in ISDN" }, { PRI_NATIONAL_ISDN, "National number in ISDN" }, { PRI_LOCAL_ISDN, "Local number in ISDN" }, { PRI_PRIVATE, "Private numbering plan" }, { PRI_UNKNOWN, "Unknown numbering plan" }, }; return code2str(plan, plans, sizeof(plans) / sizeof(plans[0]));}static char *npi2str(int plan){ static struct msgtype plans[] = { { PRI_NPI_UNKNOWN, "Unknown Number Plan" }, { PRI_NPI_E163_E164, "ISDN/Telephony Numbering Plan (E.164/E.163)" }, { PRI_NPI_X121, "Data Numbering Plan (X.121)" }, { PRI_NPI_F69, "Telex Numbering Plan (F.69)" }, { PRI_NPI_NATIONAL, "National Standard Numbering Plan" }, { PRI_NPI_PRIVATE, "Private Numbering Plan" }, { PRI_NPI_RESERVED, "Reserved Number Plan" }, }; return code2str(plan, plans, sizeof(plans) / sizeof(plans[0]));}static char *ton2str(int plan){ static struct msgtype plans[] = { { PRI_TON_UNKNOWN, "Unknown Number Type" }, { PRI_TON_INTERNATIONAL, "International Number" }, { PRI_TON_NATIONAL, "National Number" }, { PRI_TON_NET_SPECIFIC, "Network Specific Number" }, { PRI_TON_SUBSCRIBER, "Subscriber Number" }, { PRI_TON_ABBREVIATED, "Abbreviated number" }, { PRI_TON_RESERVED, "Reserved Number" }, }; return code2str(plan, plans, sizeof(plans) / sizeof(plans[0]));}static char *subaddrtype2str(int plan){ static struct msgtype plans[] = { { 0, "NSAP (X.213/ISO 8348 AD2)" }, { 2, "User Specified" }, }; return code2str(plan, plans, sizeof(plans) / sizeof(plans[0]));}char *pri_pres2str(int pres){ static struct msgtype press[] = { { PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "Presentation permitted, user number not screened" }, { PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "Presentation permitted, user number passed network screening" }, { PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "Presentation permitted, user number failed network screening" }, { PRES_ALLOWED_NETWORK_NUMBER, "Presentation allowed of network provided number" }, { PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "Presentation prohibited, user number not screened" }, { PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "Presentation prohibited, user number passed network screening" }, { PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "Presentation prohibited, user number failed network screening" }, { PRES_PROHIB_NETWORK_NUMBER, "Presentation prohibited of network provided number" }, { PRES_NUMBER_NOT_AVAILABLE, "Number not available" }, }; return code2str(pres, press, sizeof(press) / sizeof(press[0]));}static void q931_get_number(unsigned char *num, int maxlen, unsigned char *src, int len){ if ((len < 0) || (len > maxlen - 1)) { num[0] = 0; return; } memcpy(num, src, len); num[len] = 0;}static FUNC_DUMP(dump_called_party_number){ unsigned char cnum[256]; q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3); pri_message(pri, "%c Called Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d) '%s' ]\n", 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, cnum);}static FUNC_DUMP(dump_called_party_subaddr){ unsigned char cnum[256]; q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3); pri_message(pri, "%c Called 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_DUMP(dump_calling_party_number){ unsigned char cnum[256]; if (ie->data[0] & 0x80) q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3); else q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4); pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d)\n", 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); if (ie->data[0] & 0x80) pri_message(pri, "%c Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(0), 0, cnum); else pri_message(pri, "%c Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);}static FUNC_DUMP(dump_calling_party_subaddr){ unsigned char cnum[256]; q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3); pri_message(pri, "%c Calling 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_DUMP(dump_redirecting_number){ unsigned 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(pri, "%c Redirecting 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(pri, "\n%c Ext: %d Presentation: %s (%d)", prefix, ie->data[1] >> 7, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f); break; case 2: /* Octet 3b */ pri_message(pri, "\n%c Ext: %d Reason: %s (%d)", 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(pri, " '%s' ]\n", cnum);}static FUNC_DUMP(dump_connected_number){ unsigned 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(pri, "%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(pri, "\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(pri, " '%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((unsigned char *) call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i); return 0;}static FUNC_SEND(transmit_redirecting_number){ if (order > 1) return 0; if (call->redirectingnum && *call->redirectingnum) { ie->data[0] = call->redirectingplan; ie->data[1] = call->redirectingpres; ie->data[2] = (call->redirectingreason & 0x0f) | 0x80; memcpy(ie->data + 3, call->redirectingnum, strlen(call->redirectingnum)); return strlen(call->redirectingnum) + 3 + 2; } return 0;}static FUNC_DUMP(dump_redirecting_subaddr){ unsigned char cnum[256]; q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4); pri_message(pri, "%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((unsigned char *) call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3); return 0;}static FUNC_RECV(receive_called_party_number){ /* copy digits to call->callednum */ q931_get_number((unsigned char *) 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 (*call->callednum) memcpy(ie->data + 1, call->callednum, strlen(call->callednum)); return strlen(call->callednum) + 3;}static FUNC_RECV(receive_calling_party_number){ u_int8_t *data; size_t length; if (ie->data[0] & 0x80) { data = ie->data + 1; length = len - 3; call->callerpres = 0; /* PI presentation allowed SI user-provided, not screened */ } else { data = ie->data + 2; length = len - 4; call->callerpres = ie->data[1] & 0x7f; } if (call->callerpres == PRES_ALLOWED_NETWORK_NUMBER || call->callerpres == PRES_PROHIB_NETWORK_NUMBER) { q931_get_number((u_int8_t *)call->callerani, sizeof(call->callerani), data, length); call->callerplanani = ie->data[0] & 0x7f; if (!*call->callernum) { /*Copy ANI to CallerID if CallerID is not already set */ libpri_copy_string(call->callernum, call->callerani, sizeof(call->callernum)); call->callerplan = call->callerplanani; } } else { q931_get_number((u_int8_t *)call->callernum, sizeof(call->callernum), data, length); call->callerplan = ie->data[0] & 0x7f; } return 0;}static FUNC_SEND(transmit_calling_party_number){ ie->data[0] = call->callerplan; ie->data[1] = 0x80 | call->callerpres; if (*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(pri, "%c User-User Information (len=%2d) [", prefix, len); for (x=0;x<ie->len;x++) pri_message(pri, " %02x", ie->data[x] & 0x7f); pri_message(pri, " ]\n");}static FUNC_RECV(receive_user_user){ call->useruserprotocoldisc = ie->data[0] & 0xff; if (call->useruserprotocoldisc == 4) /* IA5 */ q931_get_number((unsigned char *) call->useruserinfo, sizeof(call->useruserinfo), ie->data + 1, len - 3); return 0;}static FUNC_SEND(transmit_user_user){ int datalen = strlen(call->useruserinfo); if (datalen > 0) { /* Restricted to 35 characters */ if (msgtype == Q931_USER_INFORMATION) { if (datalen > 260) datalen = 260; } else { if (datalen > 35) datalen = 35; } ie->data[0] = 4; /* IA5 characters */ memcpy(&ie->data[1], call->useruserinfo, datalen); call->useruserinfo[0] = '\0'; return datalen + 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(pri, "%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(pri, "%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((unsigned char *) call->callername, sizeof(call->callername), data, len - 2); return 0;}static FUNC_SEND(transmit_display){ int i; if ((pri->switchtype == PRI_SWITCH_QSIG) || ((pri->switchtype == PRI_SWITCH_EUROISDN_E1) && (pri->localtype == PRI_CPE)) || !call->callername[0]) return 0; 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);}static FUNC_RECV(receive_progress_indicator){ call->progloc = ie->data[0] & 0xf; call->progcode = (ie->data[0] & 0x60) >> 5; switch (call->progress = (ie->data[1] & 0x7f)) { case Q931_PROG_CALL_NOT_E2E_ISDN: call->progressmask |= PRI_PROG_CALL_NOT_E2E_ISDN; break; case Q931_PROG_CALLED_NOT_ISDN: call->progressmask |= PRI_PROG_CALLED_NOT_ISDN; break; case Q931_PROG_CALLER_NOT_ISDN: call->progressmask |= PRI_PROG_CALLER_NOT_ISDN; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -