📄 pri_facility.c
字号:
if ((comp->len > buflen) && (comp->len != ASN1_LEN_INDEF)) return -1; if (comp->len == ASN1_LEN_INDEF) { datalen = strlen((char*)comp->data); res = datalen + 2; } else res = datalen = comp->len; memcpy(buf, comp->data, datalen); buf[datalen] = 0; return res;}static int rose_number_digits_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value){ int i = 0; struct rose_component *comp = NULL; unsigned char *vdata = data; int datalen = 0; int res = 0; do { GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_NUMERICSTRING, "Don't know what to do with PublicPartyNumber ROSE component type 0x%x\n"); if(comp->len > 20 && comp->len != ASN1_LEN_INDEF) { pri_message(pri, "!! Oversized NumberDigits component (%d)\n", comp->len); return -1; } if (comp->len == ASN1_LEN_INDEF) { datalen = strlen((char *)comp->data); res = datalen + 2; } else res = datalen = comp->len; memcpy(value->partyaddress, comp->data, datalen); value->partyaddress[datalen] = '\0'; return res + 2; } while(0); return -1;}static int rose_public_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value){ int i = 0; struct rose_component *comp = NULL; unsigned char *vdata = data; int ton; int res = 0; if (len < 2) return -1; do { GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PublicPartyNumber ROSE component type 0x%x\n"); ASN1_GET_INTEGER(comp, ton); NEXT_COMPONENT(comp, i); ton = typeofnumber_for_q931(pri, ton); res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value); if (res < 0) return -1; value->ton = ton; return res + 3; } while(0); return -1;}static int rose_private_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value){ int i = 0; struct rose_component *comp = NULL; unsigned char *vdata = data; int ton; int res = 0; if (len < 2) return -1; do { GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PrivatePartyNumber ROSE component type 0x%x\n"); ASN1_GET_INTEGER(comp, ton); NEXT_COMPONENT(comp, i); ton = typeofnumber_for_q931(pri, ton); res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value); if (res < 0) return -1; value->ton = ton; return res + 3; } while(0); return -1;}static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value){ int i = 0; struct rose_component *comp = NULL; unsigned char *vdata = data; int res = 0; do { GET_COMPONENT(comp, i, vdata, len); switch(comp->type) { case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] unknownPartyNumber */ res = rose_number_digits_decode(pri, call, comp->data, comp->len, value); if (res < 0) return -1; value->npi = PRI_NPI_UNKNOWN; value->ton = PRI_TON_UNKNOWN; break; case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0): /* [0] unknownPartyNumber */ res = asn1_copy_string(value->partyaddress, sizeof(value->partyaddress), comp); if (res < 0) return -1; value->npi = PRI_NPI_UNKNOWN; value->ton = PRI_TON_UNKNOWN; break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1): /* [1] publicPartyNumber */ res = rose_public_party_number_decode(pri, call, comp->data, comp->len, value); if (res < 0) return -1; value->npi = PRI_NPI_E163_E164; break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2): /* [2] nsapEncodedNumber */ pri_message(pri, "!! NsapEncodedNumber isn't handled\n"); return -1; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] dataPartyNumber */ if(rose_number_digits_decode(pri, call, comp->data, comp->len, value)) return -1; value->npi = PRI_NPI_X121 /* ??? */; value->ton = PRI_TON_UNKNOWN /* ??? */; pri_message(pri, "!! dataPartyNumber isn't handled\n"); return -1; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4): /* [4] telexPartyNumber */ res = rose_number_digits_decode(pri, call, comp->data, comp->len, value); if (res < 0) return -1; value->npi = PRI_NPI_F69 /* ??? */; value->ton = PRI_TON_UNKNOWN /* ??? */; pri_message(pri, "!! telexPartyNumber isn't handled\n"); return -1; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5): /* [5] priavePartyNumber */ res = rose_private_party_number_decode(pri, call, comp->data, comp->len, value); if (res < 0) return -1; value->npi = PRI_NPI_PRIVATE; break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8): /* [8] nationalStandardPartyNumber */ res = rose_number_digits_decode(pri, call, comp->data, comp->len, value); if (res < 0) return -1; value->npi = PRI_NPI_NATIONAL; value->ton = PRI_TON_NATIONAL; break; default: pri_message(pri, "!! Unknown Party number component received 0x%X\n", comp->type); return -1; } ASN1_FIXUP_LEN(comp, res); NEXT_COMPONENT(comp, i); if(i < len) pri_message(pri, "!! not all information is handled from Address component\n"); return res + 2; } while (0); return -1;}static int rose_presented_number_unscreened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value){ int i = 0; int size = 0; struct rose_component *comp = NULL; unsigned char *vdata = data; /* Fill in default values */ value->ton = PRI_TON_UNKNOWN; value->npi = PRI_NPI_E163_E164; value->pres = -1; /* Data is not available */ do { GET_COMPONENT(comp, i, vdata, len); switch(comp->type) { case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] presentationAllowedNumber */ value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; size = rose_address_decode(pri, call, comp->data, comp->len, value); ASN1_FIXUP_LEN(comp, size); return size + 2; case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* [1] IMPLICIT presentationRestricted */ if (comp->len != 0) { /* must be NULL */ pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n"); return -1; } value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; return 2; case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2): /* [2] IMPLICIT numberNotAvailableDueToInterworking */ if (comp->len != 0) { /* must be NULL */ pri_error(pri, "!! Invalid NumberNotAvailableDueToInterworking component received (len != 0)\n"); return -1; } value->pres = PRES_NUMBER_NOT_AVAILABLE; return 2; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] presentationRestrictedNumber */ value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; size = rose_address_decode(pri, call, comp->data, comp->len, value) + 2; ASN1_FIXUP_LEN(comp, size); return size + 2; default: pri_message(pri, "Invalid PresentedNumberUnscreened component 0x%X\n", comp->type); } return -1; } while (0); return -1;}static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len){ int i = 0; int diversion_counter; int diversion_reason; char origcalledname[50] = "", redirectingname[50] = ""; struct addressingdataelements_presentednumberunscreened divertingnr; struct addressingdataelements_presentednumberunscreened originalcallednr; struct rose_component *comp = NULL; unsigned char *vdata = sequence->data; int res = 0; memset(&divertingnr, 0, sizeof(divertingnr)); memset(&originalcallednr, 0, sizeof(originalcallednr)); /* Data checks */ if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */ pri_message(pri, "Invalid DivertingLegInformation2Type argument\n"); return -1; } if (sequence->len == ASN1_LEN_INDEF) { len -= 4; /* For the 2 extra characters at the end * and two characters of header */ } else len -= 2; do { /* diversionCounter stuff */ GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do it diversionCounter is of type 0x%x\n"); ASN1_GET_INTEGER(comp, diversion_counter); NEXT_COMPONENT(comp, i); /* diversionReason stuff */ GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid diversionReason type 0x%X of ROSE divertingLegInformation2 component received\n"); ASN1_GET_INTEGER(comp, diversion_reason); NEXT_COMPONENT(comp, i); diversion_reason = redirectingreason_for_q931(pri, diversion_reason); if(pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Redirection reason: %d, total diversions: %d\n", diversion_reason, diversion_counter); pri_message(NULL, "Length of message is %d\n", len); for(; i < len; NEXT_COMPONENT(comp, i)) { GET_COMPONENT(comp, i, vdata, len); switch(comp->type) { case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0): call->origredirectingreason = redirectingreason_for_q931(pri, comp->data[0]); if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Received reason for original redirection %d\n", call->origredirectingreason); break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1): res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &divertingnr); /* TODO: Fix indefinite length form hacks */ ASN1_FIXUP_LEN(comp, res); comp->len = res; if (res < 0) return -1; if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, " Received divertingNr '%s'\n", divertingnr.partyaddress); pri_message(pri, " ton = %d, pres = %d, npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi); } break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2): res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &originalcallednr); if (res < 0) return -1; ASN1_FIXUP_LEN(comp, res); comp->len = res; if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, " Received originalcallednr '%s'\n", originalcallednr.partyaddress); pri_message(pri, " ton = %d, pres = %d, npi = %d\n", originalcallednr.ton, originalcallednr.pres, originalcallednr.npi); } break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): res = asn1_name_decode(comp->data, comp->len, redirectingname, sizeof(redirectingname)); if (res < 0) return -1; ASN1_FIXUP_LEN(comp, res); comp->len = res; if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Received RedirectingName '%s'\n", redirectingname); break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4): res = asn1_name_decode(comp->data, comp->len, origcalledname, sizeof(origcalledname)); if (res < 0) return -1; ASN1_FIXUP_LEN(comp, res); comp->len = res; if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Received Originally Called Name '%s'\n", origcalledname); break; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5): pri_message(pri, "!! Ignoring DivertingLegInformation2 component 0x%X\n", comp->type); break; default: if (comp->type == 0 && comp->len == 0) { break; /* Found termination characters */ } pri_message(pri, "!! Invalid DivertingLegInformation2 component received 0x%X\n", comp->type); return -1; } } if (divertingnr.pres >= 0) { call->redirectingplan = divertingnr.npi; call->redirectingpres = divertingnr.pres; call->redirectingreason = diversion_reason; libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum)); pri_message(pri, " Received redirectingnum '%s' (%d)\n", call->redirectingnum, (int)call->redirectingnum[0]); } if (originalcallednr.pres >= 0) { call->origcalledplan = originalcallednr.npi; call->origcalledpres = originalcallednr.pres; libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum)); pri_message(pri, " Received origcallednum '%s' (%d)\n", call->origcallednum, (int)call->origcallednum[0]); } libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname)); libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname)); return 0; } while (0); return -1;} static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *call){ int i = 0, j, compsp = 0; struct rose_component *comp, *compstk[10]; unsigned char buffer[256]; int len = 253; #if 0 /* This is not required by specifications */ if (!strlen(call->callername)) { return -1; }#endif buffer[i] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS); i++; /* Interpretation component */ ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 0x00 /* Discard unrecognized invokes */); ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i); ASN1_PUSH(compstk, compsp, comp); /* Invoke component contents */ /* Invoke ID */ ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri)); /* Operation Tag */ /* ROSE operationId component */ ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_DIVERTING_LEG_INFORMATION2); /* ROSE ARGUMENT component */ ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* ROSE DivertingLegInformation2.diversionCounter component */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -