📄 q931.c
字号:
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; case Q931_PROG_CALLER_RETURNED_TO_ISDN: call->progressmask |= PRI_PROG_CALLER_RETURNED_TO_ISDN; break; case Q931_PROG_INBAND_AVAILABLE: call->progressmask |= PRI_PROG_INBAND_AVAILABLE; break; case Q931_PROG_DELAY_AT_INTERF: call->progressmask |= PRI_PROG_DELAY_AT_INTERF; break; case Q931_PROG_INTERWORKING_WITH_PUBLIC: call->progressmask |= PRI_PROG_INTERWORKING_WITH_PUBLIC; break; case Q931_PROG_INTERWORKING_NO_RELEASE: call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE; break; case Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER: call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER; break; case Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER: call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER; break; default: pri_error(pri, "XXX Invalid Progress indicator value received: %02x\n",(ie->data[1] & 0x7f)); break; } return 0;}static FUNC_SEND(transmit_facility){ struct apdu_event *tmp; int i = 0; for (tmp = call->apdus; tmp; tmp = tmp->next) { if ((tmp->message == msgtype) && !tmp->sent) break; } if (!tmp) /* No APDU found */ return 0; if (tmp->apdu_len > 235) { /* TODO: find out how much space we can use */ pri_message(pri, "Requested APDU (%d bytes) is too long\n", tmp->apdu_len); return 0; } memcpy(&ie->data[i], tmp->apdu, tmp->apdu_len); i += tmp->apdu_len; tmp->sent = 1; return i + 2;}static FUNC_RECV(receive_facility){ int i = 0; int protocol, next_protocol; struct rose_component *comp = NULL; enum { Q932_STATE_NFE, /* Network facility extension */ Q932_STATE_NPP, /* Network protocol profile */ Q932_STATE_INTERPRETATION, /* Interpretation component */ Q932_STATE_SERVICE /* Service component(s) */ } state = Q932_STATE_SERVICE;#define Q932_HANDLE_PROC(component, my_state, name, handler) \ case component: \ if(state > my_state) { \ pri_error(pri, "!! %s component received in wrong place\n"); \ break; \ } \ state = my_state; \ if (pri->debug) \ pri_message(pri, "Handle Q.932 %s component\n", name); \ (handler)(pri, call, comp->data, comp->len); \ break;#define Q932_HANDLE_NULL(component, my_state, name, handle) \ case component: \ if(state > my_state) { \ pri_error(pri, "!! %s component received in wrong place\n"); \ break; \ } \ state = my_state; \ if (pri->debug & PRI_DEBUG_APDU) \ pri_message(pri, "Q.932 %s component is not handled\n", name); \ break; if (ie->len < 1) return -1; switch(next_protocol = protocol = (ie->data[i] & 0x1f)) { case Q932_PROTOCOL_CMIP: case Q932_PROTOCOL_ACSE: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "!! Don't know how to handle Q.932 Protocol Profile of type 0x%X\n", protocol); return -1; case Q932_PROTOCOL_EXTENSIONS: state = Q932_STATE_NFE; next_protocol = Q932_PROTOCOL_ROSE; break; case Q932_PROTOCOL_ROSE: break; default: pri_error(pri, "!! Invalid Q.932 Protocol Profile of type 0x%X received\n", protocol); return -1; } /* Service indicator octet - Just ignore for now */ if (!(ie->data[i] & 0x80)) i++; i++; if (ie->len < 3) return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -