📄 pri_facility.c
字号:
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i); } ASN1_FIXUP(compstk, compsp, buffer, i); ASN1_FIXUP(compstk, compsp, buffer, i); if (pri->debug & PRI_DEBUG_AOC) dump_apdu (pri, buffer, i); /* code below is untested */ res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL); if (res) { pri_message(pri, "Could not queue APDU 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 AOC */int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len){ int i = 0; int problemtag = -1; int problem = -1; int invokeidvalue = -1; unsigned char *vdata = data; struct rose_component *comp = NULL; char *problemtagstr, *problemstr; do { /* Invoke ID stuff */ GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n"); ASN1_GET_INTEGER(comp, invokeidvalue); NEXT_COMPONENT(comp, i); GET_COMPONENT(comp, i, vdata, len); problemtag = comp->type; problem = comp->data[0]; if (pri->switchtype == PRI_SWITCH_DMS100) { switch (problemtag) { case 0x80: problemtagstr = "General problem"; break; case 0x81: problemtagstr = "Invoke problem"; break; case 0x82: problemtagstr = "Return result problem"; break; case 0x83: problemtagstr = "Return error problem"; break; default: problemtagstr = "Unknown"; } switch (problem) { case 0x00: problemstr = "Unrecognized component"; break; case 0x01: problemstr = "Mistyped component"; break; case 0x02: problemstr = "Badly structured component"; break; default: problemstr = "Unknown"; } pri_error(pri, "ROSE REJECT:\n"); pri_error(pri, "\tINVOKE ID: 0x%X\n", invokeidvalue); pri_error(pri, "\tPROBLEM TYPE: %s (0x%x)\n", problemtagstr, problemtag); pri_error(pri, "\tPROBLEM: %s (0x%x)\n", problemstr, problem); return 0; } else { pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype); return -1; } } while(0); return -1;}int rose_return_error_decode(struct pri *pri, q931_call *call, unsigned char *data, int len){ int i = 0; int errorvalue = -1; int invokeidvalue = -1; unsigned char *vdata = data; struct rose_component *comp = NULL; char *invokeidstr, *errorstr; do { /* Invoke ID stuff */ GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n"); ASN1_GET_INTEGER(comp, invokeidvalue); NEXT_COMPONENT(comp, i); GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if second component in return error is 0x%x\n"); ASN1_GET_INTEGER(comp, errorvalue); if (pri->switchtype == PRI_SWITCH_DMS100) { switch (invokeidvalue) { case RLT_OPERATION_IND: invokeidstr = "RLT_OPERATION_IND"; break; case RLT_THIRD_PARTY: invokeidstr = "RLT_THIRD_PARTY"; break; default: invokeidstr = "Unknown"; } switch (errorvalue) { case 0x10: errorstr = "RLT Bridge Fail"; break; case 0x11: errorstr = "RLT Call ID Not Found"; break; case 0x12: errorstr = "RLT Not Allowed"; break; case 0x13: errorstr = "RLT Switch Equip Congs"; break; default: errorstr = "Unknown"; } pri_error(pri, "ROSE RETURN ERROR:\n"); pri_error(pri, "\tOPERATION: %s\n", invokeidstr); pri_error(pri, "\tERROR: %s\n", errorstr); return 0; } else { pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype); return -1; } } while(0); return -1;}int rose_return_result_decode(struct pri *pri, q931_call *call, unsigned char *data, int len){ int i = 0; int operationidvalue = -1; int invokeidvalue = -1; unsigned char *vdata = data; struct rose_component *comp = NULL; do { /* Invoke ID stuff */ GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n"); ASN1_GET_INTEGER(comp, invokeidvalue); NEXT_COMPONENT(comp, i); if (pri->switchtype == PRI_SWITCH_DMS100) { switch (invokeidvalue) { case RLT_THIRD_PARTY: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Successfully completed RLT transfer!\n"); return 0; case RLT_OPERATION_IND: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Received RLT_OPERATION_IND\n"); /* Have to take out the rlt_call_id */ GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_SEQUENCE, "Protocol error detected in parsing RLT_OPERATION_IND return result!\n"); /* Traverse the contents of this sequence */ /* First is the Operation Value */ SUB_COMPONENT(comp, i); GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_INTEGER, "RLT_OPERATION_IND should be of type ASN1_INTEGER!\n"); ASN1_GET_INTEGER(comp, operationidvalue); if (operationidvalue != RLT_OPERATION_IND) { pri_message(pri, "Invalid Operation ID value (0x%x) in return result!\n", operationidvalue); return -1; } /* Next is the Call ID */ NEXT_COMPONENT(comp, i); GET_COMPONENT(comp, i, vdata, len); CHECK_COMPONENT(comp, ASN1_TAG_0, "Error check failed on Call ID!\n"); ASN1_GET_INTEGER(comp, call->rlt_call_id); /* We have enough data to transfer the call */ call->transferable = 1; return 0; default: pri_message(pri, "Could not parse invoke of type 0x%x!\n", invokeidvalue); return -1; } } else { pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype); return -1; } } while(0); return -1;}int rose_invoke_decode(struct pri *pri, q931_call *call, unsigned char *data, int len){ int i = 0; int operation_tag; unsigned char *vdata = data; struct rose_component *comp = NULL, *invokeid = NULL, *operationid = NULL; do { /* Invoke ID stuff */ GET_COMPONENT(comp, i, vdata, len);#if 0 CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n");#endif invokeid = comp; NEXT_COMPONENT(comp, i); /* Operation Tag */ GET_COMPONENT(comp, i, vdata, len);#if 0 CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if second ROSE component is of type 0x%x\n");#endif operationid = comp; ASN1_GET_INTEGER(comp, operation_tag); NEXT_COMPONENT(comp, i); /* No argument - return with error */ if (i >= len) return -1; /* Arguement Tag */ GET_COMPONENT(comp, i, vdata, len); if (!comp->type) return -1; if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " [ Handling operation %d ]\n", operation_tag); switch (operation_tag) { case SS_CNID_CALLINGNAME: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Handle Name display operation\n"); switch (comp->type) { case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE: memcpy(call->callername, comp->data, comp->len); call->callername[comp->len] = 0; if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Received caller name '%s'\n", call->callername); return 0; default: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Do not handle argument of type 0x%X\n", comp->type); return -1; } break; case ROSE_DIVERTING_LEG_INFORMATION2: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Handle DivertingLegInformation2\n"); return rose_diverting_leg_information2_decode(pri, call, comp, len-i); case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC No Charging Info Available - not handled!", operation_tag); dump_apdu (pri, comp->data, comp->len); } return -1; case ROSE_AOC_CHARGING_REQUEST: return aoc_aoce_charging_request_decode(pri, call, (u_int8_t *)comp, comp->len + 2); case ROSE_AOC_AOCS_CURRENCY: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC-S Currency - not handled!", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; case ROSE_AOC_AOCS_SPECIAL_ARR: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC-S Special Array - not handled!", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; case ROSE_AOC_AOCD_CURRENCY: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC-D Currency - not handled!", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; case ROSE_AOC_AOCD_CHARGING_UNIT: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC-D Charging Unit - not handled!", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; case ROSE_AOC_AOCE_CURRENCY: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC-E Currency - not handled!", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; case ROSE_AOC_AOCE_CHARGING_UNIT: return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2); if (0) { /* the following function is currently not used - just to make the compiler happy */ aoc_aoce_charging_unit_encode(pri, call, call->aoc_units); /* use this function to forward the aoc-e on a bridged channel */ return 0; } case ROSE_AOC_IDENTIFICATION_OF_CHARGE: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC Identification Of Charge - not handled!", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; default: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag); dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; } } while(0); return -1;}int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data){ struct apdu_event *cur = NULL; struct apdu_event *new_event = NULL; if (!call || !messagetype || !apdu || (apdu_len < 1) || (apdu_len > 255)) return -1; new_event = malloc(sizeof(struct apdu_event)); if (new_event) { memset(new_event, 0, sizeof(struct apdu_event)); new_event->message = messagetype; new_event->callback = function; new_event->data = data; memcpy(new_event->apdu, apdu, apdu_len); new_event->apdu_len = apdu_len; } else { pri_error(call->pri, "!! Malloc failed!\n"); return -1; } if (call->apdus) { cur = call->apdus; while (cur->next) { cur = cur->next; } cur->next = new_event; } else call->apdus = new_event; return 0;}int pri_call_apdu_queue_cleanup(q931_call *call){ struct apdu_event *cur_event = NULL, *free_event = NULL; if (call && call->apdus) { cur_event = call->apdus; while (cur_event) { /* TODO: callbacks, some way of giving return res on status of apdu */ free_event = cur_event; cur_event = cur_event->next; free(free_event); } call->apdus = NULL; } return 0;}int pri_call_add_standard_apdus(struct pri *pri, q931_call *call){ if (!pri->sendfacility) return 0; if (pri->switchtype == PRI_SWITCH_QSIG) { /* For Q.SIG it does network and cpe operations */ if (call->redirectingnum[0]) rose_diverting_leg_information2_encode(pri, call); add_callername_facility_ies(pri, call, 1); return 0; }#if 0 if (pri->localtype == PRI_NETWORK) { switch (pri->switchtype) { case PRI_SWITCH_NI2: add_callername_facility_ies(pri, call, 0); break; default: break; } return 0; } else if (pri->localtype == PRI_CPE) { switch (pri->switchtype) { case PRI_SWITCH_NI2: add_callername_facility_ies(pri, call, 1); break; default: break; } return 0; }#else if (pri->switchtype == PRI_SWITCH_NI2) add_callername_facility_ies(pri, call, (pri->localtype == PRI_CPE));#endif if ((pri->switchtype == PRI_SWITCH_DMS100) && (pri->localtype == PRI_CPE)) { add_dms100_transfer_ability_apdu(pri, call); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -