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

📄 pri_facility.c

📁 Q921的LINUX下的驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 */			pri_message(pri, "!! privatePartyNumber isn't handled\n");			value->npi = PRI_NPI_PRIVATE;			return -1;		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;	/* 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;			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));		}		if (originalcallednr.pres >= 0) {			call->origcalledplan = originalcallednr.npi;			call->origcalledpres = originalcallednr.pres;			libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));		}		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 */	/* Always is 1 because other isn't available in the current design */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1);		/* ROSE DivertingLegInformation2.diversionReason component */	ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, redirectingreason_from_q931(pri, call->redirectingreason));			/* ROSE DivertingLegInformation2.divertingNr component */	ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);		ASN1_PUSH(compstk, compsp, comp);		/* Redirecting information always not screened */		switch(call->redirectingpres) {		case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:		case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:			if (call->redirectingnum && strlen(call->redirectingnum)) {				ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);				ASN1_PUSH(compstk, compsp, comp);					/* NPI of redirected number is not supported in the current design */				ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);				ASN1_PUSH(compstk, compsp, comp);					ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, typeofnumber_from_q931(pri, call->redirectingplan >> 4));					j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, call->redirectingnum, strlen(call->redirectingnum));				if (j < 0)					return -1;									i += j;				ASN1_FIXUP(compstk, compsp, buffer, i);				ASN1_FIXUP(compstk, compsp, buffer, i);				break;			}			/* fall through */		case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:		case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:			ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);			break;		/* Don't know how to handle this */		case PRES_ALLOWED_NETWORK_NUMBER:		case PRES_PROHIB_NETWORK_NUMBER:		case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:		case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:			ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);			break;		default:			pri_message(pri, "!! Undefined presentation value for redirecting number: %d\n", call->redirectingpres);		case PRES_NUMBER_NOT_AVAILABLE:			ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i);			break;	}	ASN1_FIXUP(compstk, compsp, buffer, i);	/* ROSE DivertingLegInformation2.originalCalledNr component */	/* This information isn't supported by current design - duplicate divertingNr */	ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2), buffer, i);	ASN1_PUSH(compstk, compsp, comp);		/* Redirecting information always not screened */	switch(call->redirectingpres) {		case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:		case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:			if (call->redirectingnum && strlen(call->redirectingnum)) {				ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);				ASN1_PUSH(compstk, compsp, comp);				ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);				ASN1_PUSH(compstk, compsp, comp);				ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, typeofnumber_from_q931(pri, call->redirectingplan >> 4));					j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, call->redirectingnum, strlen(call->redirectingnum));				if (j < 0)					return -1;								i += j;				ASN1_FIXUP(compstk, compsp, buffer, i);				ASN1_FIXUP(compstk, compsp, buffer, i);				break;			}				/* fall through */		case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:		case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:			ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);			break;		/* Don't know how to handle this */		case PRES_ALLOWED_NETWORK_NUMBER:		case PRES_PROHIB_NETWORK_NUMBER:		case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:		case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:			ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);			break;		default:			pri_message(pri, "!! Undefined presentation value for redirecting number: %d\n", call->redirectingpres);		case PRES_NUMBER_NOT_AVAILABLE:			ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i);			break;	}	ASN1_FIXUP(compstk, compsp, buffer, i);			/* Fix length of stacked components */	while(compsp > 0) {		ASN1_FIXUP(compstk, compsp, buffer, i);	}		if (pri_call_apdu_queue(call, Q931_SETUP, buffer, i, NULL, NULL))		return -1;			return 0;}/* Send the rltThirdParty: Invoke */int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2){	int i = 0;	unsigned char buffer[256];	struct rose_component *comp = NULL, *compstk[10];	const unsigned char rlt_3rd_pty = RLT_THIRD_PARTY;	q931_call *callwithid = NULL, *apdubearer = NULL;	int compsp = 0;	if (c2->transferable) {		apdubearer = c1;		callwithid = c2;	} else if (c1->transferable) {		apdubearer = c2;		callwithid = c1;	} else		return -1;	buffer[i++] = (Q932_PROTOCOL_ROSE);	buffer[i++] = (0x80 | RLT_SERVICE_ID); /* Service Identifier octet */	ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);	ASN1_PUSH(compstk, compsp, comp);	/* Invoke ID is set to the operation ID */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_3rd_pty);	/* Operation Tag */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_3rd_pty);	/* Additional RLT invoke info - Octet 12 */	ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);	ASN1_PUSH(compstk, compsp, comp);	ASN1_ADD_WORDCOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, callwithid->rlt_call_id & 0xFFFFFF); /* Length is 3 octets */	/* Reason for redirect - unused, set to 129 */	ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i, 0);	ASN1_FIXUP(compstk, compsp, buffer, i);	ASN1_FIXUP(compstk, compsp, buffer, i);	if (pri_call_apdu_queue(apdubearer, Q931_FACILITY, buffer, i, NULL, NULL))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -