📄 pri_facility.c
字号:
if (res) { pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr); return -1; } return 0;}/* End EECT *//* QSIG CF CallRerouting */int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const char* original, const char* reason){/*CallRerouting ::= OPERATION -- Sent from the Served User PINX to the Rerouting PINX ARGUMENT SEQUENCE { reroutingReason DiversionReason, originalReroutingReason [0] IMPLICIT DiversionReason OPTIONAL, calledAddress Address, diversionCounter INTEGER (1..15), pSS1InfoElement PSS1InformationElement, -- The basic call information elements Bearer capability, High layer compatibility, Low -- layer compatibity, Progress indicator and Party category can be embedded in the -- pSS1InfoElement in accordance with 6.5.3.1.5 lastReroutingNr [1] PresentedNumberUnscreened, subscriptionOption [2] IMPLICIT SubscriptionOption, callingPartySubaddress [3] PartySubaddress OPTIONAL, callingNumber [4] PresentedNumberScreened, callingName [5] Name OPTIONAL, originalCalledNr [6] PresentedNumberUnscreened OPTIONAL, redirectingName [7] Name OPTIONAL, originalCalledName [8] Name OPTIONAL, extension CHOICE { [9] IMPLICIT Extension , [10] IMPLICIT SEQUENCE OF Extension } OPTIONAL }*/ int i = 0, j; int res = 0; unsigned char buffer[255] = ""; int len = 253; struct rose_component *comp = NULL, *compstk[10]; int compsp = 0; static unsigned char op_tag[] = { 0x13, }; buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS); /* Interpretation component */ ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i); ASN1_PUSH(compstk, compsp, comp); ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0); ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0); ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 2); /* reject - to get feedback from QSIG switch */ ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i); ASN1_PUSH(compstk, compsp, comp); ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri)); res = asn1_string_encode(ASN1_INTEGER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag)); if (res < 0) return -1; i += res; /* call rerouting argument */ ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* reroutingReason DiversionReason */ if (reason) { if (!strcasecmp(reason, "cfu")) ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1); /* cfu */ else if (!strcasecmp(reason, "cfb")) ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 2); /* cfb */ else if (!strcasecmp(reason, "cfnr")) ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 3); /* cfnr */ } else { ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0); /* unknown */ } /* calledAddress Address */ /* explicit sequence tag for Address */ ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* implicit choice public party number tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* type of public party number = unknown */ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0); /* NumberDigits of public party number */ j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, (char*)dest, strlen(dest)); if (j < 0) return -1; i += j; ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); /* diversionCounter INTEGER (1..15) */ ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1); /* pSS1InfoElement */ ASN1_ADD_SIMPLE(comp, (ASN1_APPLICATION | ASN1_TAG_0 ), buffer, i); ASN1_PUSH(compstk, compsp, comp); buffer[i++] = (0x04); /* add BC */ buffer[i++] = (0x03); buffer[i++] = (0x80); buffer[i++] = (0x90); buffer[i++] = (0xa3); buffer[i++] = (0x95); buffer[i++] = (0x32); buffer[i++] = (0x01); buffer[i++] = (0x81); ASN1_FIXUP(compstk, compsp, buffer, i); /* lastReroutingNr [1]*/ /* implicit optional lastReroutingNr tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* implicit choice presented number unscreened tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* implicit choice public party number tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* type of public party number = unknown */ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0); j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, original?(char*)original:c->callednum, original?strlen(original):strlen(c->callednum)); if (j < 0) return -1; i += j; ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); /* subscriptionOption [2]*/ /* implicit optional lastReroutingNr tag */ ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0); /* noNotification */ /* callingNumber [4]*/ /* implicit optional callingNumber tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* implicit choice presented number screened tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* implicit choice presentationAllowedAddress tag */ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i); ASN1_PUSH(compstk, compsp, comp); /* type of public party number = subscriber number */ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 4); j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, c->callernum, strlen(c->callernum)); if (j < 0) return -1; i += j; ASN1_FIXUP(compstk, compsp, buffer, i); /* Screeening Indicator network provided */ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 3); ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); /**/ ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL); if (res) { pri_message(pri, "Could not queue ADPU in facility message\n"); return -1; } /* Remember that if we queue a facility IE for a facility message we * have to explicitly send the facility message ourselves */ res = q931_facility(c->pri, c); if (res) { pri_message(pri, "Could not schedule facility message for call %d\n", c->cr); return -1; } return 0;}/* End QSIG CC-CallRerouting */static int anfpr_pathreplacement_respond(struct pri *pri, q931_call *call, q931_ie *ie){ int res; res = pri_call_apdu_queue_cleanup(call->bridged_call); if (res) { pri_message(pri, "Could not Clear queue ADPU\n"); return -1; } /* Send message */ res = pri_call_apdu_queue(call->bridged_call, Q931_FACILITY, ie->data, ie->len, NULL, NULL); if (res) { pri_message(pri, "Could not queue ADPU in facility message\n"); return -1; } /* Remember that if we queue a facility IE for a facility message we * have to explicitly send the facility message ourselves */ res = q931_facility(call->bridged_call->pri, call->bridged_call); if (res) { pri_message(pri, "Could not schedule facility message for call %d\n", call->bridged_call->cr); return -1; } return 0;}/* AFN-PR */int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2){ /* Did all the tests to see if we're on the same PRI and * are on a compatible switchtype */ /* TODO */ int i = 0; int res = 0; unsigned char buffer[255] = ""; unsigned short call_reference = c2->cr; struct rose_component *comp = NULL, *compstk[10]; unsigned char buffer2[255] = ""; int compsp = 0; static unsigned char op_tag[] = { 0x0C, }; /* Channel 1 */ buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS); /* Interpretation component */ ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i); ASN1_PUSH(compstk, compsp, comp); ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0); ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0); ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 2); /* reject - to get feedback from QSIG switch */ ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i); ASN1_PUSH(compstk, compsp, comp); ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri)); res = asn1_string_encode(ASN1_INTEGER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag)); if (res < 0) return -1; i += res; ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer, i); ASN1_PUSH(compstk, compsp, comp); buffer[i++] = (0x0a); buffer[i++] = (0x01); buffer[i++] = (0x00); buffer[i++] = (0x81); buffer[i++] = (0x00); buffer[i++] = (0x0a); buffer[i++] = (0x01); buffer[i++] = (0x01); ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer, i, call_reference); ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); res = pri_call_apdu_queue(c1, Q931_FACILITY, buffer, i, NULL, NULL); if (res) { pri_message(pri, "Could not queue ADPU in facility message\n"); return -1; } /* Remember that if we queue a facility IE for a facility message we * have to explicitly send the facility message ourselves */ res = q931_facility(c1->pri, c1); if (res) { pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr); return -1; } /* Channel 2 */ i = 0; res = 0; compsp = 0; buffer2[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS); /* Interpretation component */ ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer2, i); ASN1_PUSH(compstk, compsp, comp); ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer2, i, 0); ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer2, i, 0); ASN1_FIXUP(compstk, compsp, buffer2, i); ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer2, i, 2); /* reject */ ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer2, i); ASN1_PUSH(compstk, compsp, comp); ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer2, i, get_invokeid(pri)); res = asn1_string_encode(ASN1_INTEGER, &buffer2[i], sizeof(buffer2)-i, sizeof(op_tag), op_tag, sizeof(op_tag)); if (res < 0) return -1; i += res; ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer2, i); ASN1_PUSH(compstk, compsp, comp); buffer2[i++] = (0x0a); buffer2[i++] = (0x01); buffer2[i++] = (0x01); buffer2[i++] = (0x81); buffer2[i++] = (0x00); buffer2[i++] = (0x0a); buffer2[i++] = (0x01); buffer2[i++] = (0x01); ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer2, i, call_reference); ASN1_FIXUP(compstk, compsp, buffer2, i); ASN1_FIXUP(compstk, compsp, buffer2, i); res = pri_call_apdu_queue(c2, Q931_FACILITY, buffer2, i, NULL, NULL); if (res) { pri_message(pri, "Could not queue ADPU in facility message\n"); return -1; } /* Remember that if we queue a facility IE for a facility message we * have to explicitly send the facility message ourselves */ res = q931_facility(c2->pri, c2); if (res) { pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr); return -1; } return 0;}/* End AFN-PR *//* AOC */static int aoc_aoce_charging_request_decode(struct pri *pri, q931_call *call, unsigned char *data, int len) { int chargingcase = -1; unsigned char *vdata = data; struct rose_component *comp = NULL; int pos1 = 0; if (pri->debug & PRI_DEBUG_AOC) dump_apdu (pri, data, len); do { GET_COMPONENT(comp, pos1, vdata, len); CHECK_COMPONENT(comp, ASN1_ENUMERATED, "!! Invalid AOC Charging Request argument. Expected Enumerated (0x0A) but Received 0x%02X\n"); ASN1_GET_INTEGER(comp, chargingcase); if (chargingcase >= 0 && chargingcase <= 2) { if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Channel %d/%d, Call %d - received AOC charging request - charging case: %i\n", call->ds1no, call->channelno, call->cr, chargingcase); } else { pri_message(pri, "!! unkown AOC ChargingCase: 0x%02X", chargingcase); chargingcase = -1; } NEXT_COMPONENT(comp, pos1); } while (pos1 < len); if (pos1 < len) { pri_message(pri, "!! Only reached position %i in %i bytes long AOC-E structure:", pos1, len ); dump_apdu (pri, data, len); return -1; /* Aborted before */ } return 0;} static int aoc_aoce_charging_unit_decode(struct pri *pri, q931_call *call, unsigned char *data, int len) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -