⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pri_facility.c

📁 Q921的LINUX下的驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -