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

📄 pri_facility.c

📁 Q.931/Q.921 source code compiles
💻 C
📖 第 1 页 / 共 5 页
字号:
	long chargingunits = 0, chargetype = -1, temp, chargeIdentifier = -1;	unsigned char *vdata = data;	struct rose_component *comp1 = NULL, *comp2 = NULL, *comp3 = NULL;	int pos1 = 0, pos2, pos3, sublen2, sublen3;	struct addressingdataelements_presentednumberunscreened chargednr;	if (pri->debug & PRI_DEBUG_AOC)		dump_apdu (pri, data, len);	do {		GET_COMPONENT(comp1, pos1, vdata, len);	/* AOCEChargingUnitInfo */		CHECK_COMPONENT(comp1, ASN1_SEQUENCE, "!! Invalid AOC-E Charging Unit argument. Expected Sequence (0x30) but Received 0x%02X\n");		SUB_COMPONENT(comp1, pos1);		GET_COMPONENT(comp1, pos1, vdata, len);		switch (comp1->type) {			case (ASN1_SEQUENCE | ASN1_CONSTRUCTOR):	/* specificChargingUnits */				sublen2 = comp1->len; 				pos2 = pos1;				comp2 = comp1;				SUB_COMPONENT(comp2, pos2);				do {					GET_COMPONENT(comp2, pos2, vdata, len);					switch (comp2->type) {						case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):	/* RecordedUnitsList (0xA1) */							SUB_COMPONENT(comp2, pos2);							GET_COMPONENT(comp2, pos2, vdata, len);							CHECK_COMPONENT(comp2, ASN1_SEQUENCE, "!! Invalid AOC-E Charging Unit argument. Expected Sequence (0x30) but received 0x02%X\n");	/* RecordedUnits */							sublen3 = pos2 + comp2->len;							pos3 = pos2;							comp3 = comp2;							SUB_COMPONENT(comp3, pos3);							do {								GET_COMPONENT(comp3, pos3, vdata, len);								switch (comp3->type) {									case ASN1_INTEGER:	/* numberOfUnits */										ASN1_GET_INTEGER(comp3, temp);										chargingunits += temp;									case ASN1_NULL:		/* notAvailable */										break;									default:										pri_message(pri, "!! Don't know how to handle 0x%02X in AOC-E RecordedUnits\n", comp3->type);								}								NEXT_COMPONENT(comp3, pos3);							} while (pos3 < sublen3);							if (pri->debug & PRI_DEBUG_AOC)								pri_message(pri, "Channel %d/%d, Call %d - received AOC-E charging: %i unit%s\n", 									call->ds1no, call->channelno, call->cr, chargingunits, (chargingunits == 1) ? "" : "s");							break;						case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2):	/* AOCEBillingID (0xA2) */							SUB_COMPONENT(comp2, pos2);							GET_COMPONENT(comp2, pos2, vdata, len);							ASN1_GET_INTEGER(comp2, chargetype);							pri_message(pri, "!! not handled: Channel %d/%d, Call %d - received AOC-E billing ID: %i\n", 								call->ds1no, call->channelno, call->cr, chargetype);							break;						default:							pri_message(pri, "!! Don't know how to handle 0x%02X in AOC-E RecordedUnitsList\n", comp2->type);					}					NEXT_COMPONENT(comp2, pos2);				} while (pos2 < sublen2);				break;			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* freeOfCharge (0x81) */				if (pri->debug & PRI_DEBUG_AOC)					pri_message(pri, "Channel %d/%d, Call %d - received AOC-E free of charge\n", call->ds1no, call->channelno, call->cr);				chargingunits = 0;				break;			default:				pri_message(pri, "!! Invalid AOC-E specificChargingUnits. Expected Sequence (0x30) or Object Identifier (0x81/0x01) but received 0x%02X\n", comp1->type);		}		NEXT_COMPONENT(comp1, pos1);		GET_COMPONENT(comp1, pos1, vdata, len); /* get optional chargingAssociation. will 'break' when reached end of structure */		switch (comp1->type) {			/* TODO: charged number is untested - please report! */			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* chargedNumber (0xA0) */				if(rose_presented_number_unscreened_decode(pri, call, comp1->data, comp1->len, &chargednr) != 0)					return -1;				pri_message(pri, "!! not handled: Received ChargedNr '%s' \n", chargednr.partyaddress);				pri_message(pri, "  ton = %d, pres = %d, npi = %d\n", chargednr.ton, chargednr.pres, chargednr.npi);				break;			case ASN1_INTEGER:				ASN1_GET_INTEGER(comp1, chargeIdentifier);				break;			default:				pri_message(pri, "!! Invalid AOC-E chargingAssociation. Expected Object Identifier (0xA0) or Integer (0x02) but received 0x%02X\n", comp1->type);		}		NEXT_COMPONENT(comp1, 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;	/* oops - aborted before */	}	call->aoc_units = chargingunits;		return 0;}static int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits){	/* sample data: [ 91 a1 12 02 02 3a 78 02 01 24 30 09 30 07 a1 05 30 03 02 01 01 ] */	int i = 0, res = 0, compsp = 0;	unsigned char buffer[255] = "";	struct rose_component *comp = NULL, *compstk[10];	/* ROSE protocol (0x91)*/	buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);	/* ROSE Component (0xA1,len)*/	ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);	ASN1_PUSH(compstk, compsp, comp); 	/* ROSE invokeId component (0x02,len,id)*/	ASN1_ADD_WORDCOMP(comp, INVOKE_IDENTIFIER, buffer, i, ++pri->last_invoke);	/* ROSE operationId component (0x02,0x01,0x24)*/	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_AOC_AOCE_CHARGING_UNIT);	/* AOCEChargingUnitInfo (0x30,len) */	ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);	ASN1_PUSH(compstk, compsp, comp);	if (chargedunits > 0) {		/* SpecificChargingUnits (0x30,len) */		ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);		ASN1_PUSH(compstk, compsp, comp);		/* RecordedUnitsList (0xA1,len) */		ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);		ASN1_PUSH(compstk, compsp, comp);				/* RecordedUnits (0x30,len) */		ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);		ASN1_PUSH(compstk, compsp, comp);				/* NumberOfUnits (0x02,len,charge) */		ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, chargedunits);		ASN1_FIXUP(compstk, compsp, buffer, i);		ASN1_FIXUP(compstk, compsp, buffer, i);		ASN1_FIXUP(compstk, compsp, buffer, i);	} else {		/* freeOfCharge (0x81,0) */		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 */static int rose_calling_name_decode(struct pri *pri, q931_call *call, struct rose_component *choice, int len){	int i = 0;	struct rose_component *comp = NULL;	unsigned char *vdata = choice->data;	int characterSet = 1;	switch (choice->type) {		case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE:			memcpy(call->callername, choice->data, choice->len);			call->callername[choice->len] = 0;			if (pri->debug & PRI_DEBUG_APDU)				pri_message(pri, "    Received simple calling name '%s'\n", call->callername);			return 0;		case ROSE_NAME_PRESENTATION_ALLOWED_EXTENDED:			do {				GET_COMPONENT(comp, i, vdata, len);				CHECK_COMPONENT(comp, ASN1_OCTETSTRING, "Don't know what to do if nameData is of type 0x%x\n");				memcpy(call->callername, comp->data, comp->len);				call->callername[comp->len] = 0;				NEXT_COMPONENT(comp, i);				GET_COMPONENT(comp, i, vdata, len);				CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if CharacterSet is of type 0x%x\n");				ASN1_GET_INTEGER(comp, characterSet);			}			while (0);			if (pri->debug & PRI_DEBUG_APDU)				pri_message(pri, "    Received extended calling name '%s', characterset %d\n", call->callername, characterSet);			return 0;		case ROSE_NAME_PRESENTATION_RESTRICTED_SIMPLE:		case ROSE_NAME_PRESENTATION_RESTRICTED_EXTENDED:		case ROSE_NAME_PRESENTATION_RESTRICTED_NULL:		case ROSE_NAME_NOT_AVAIL:		default:			if (pri->debug & PRI_DEBUG_APDU)				pri_message(pri, "Do not handle argument of type 0x%X\n", choice->type);			return -1;	}}/* ===== Call Transfer Supplementary Service (ECMA-178) ===== */static int rose_party_number_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;	do {		GET_COMPONENT(comp, i, vdata, len);		switch(comp->type) {			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):   /* [0] IMPLICIT NumberDigits -- default: unknownPartyNumber */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PartyNumber: UnknownPartyNumber len=%d\n", len);				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				value->npi = PRI_NPI_UNKNOWN;				value->ton = PRI_TON_UNKNOWN;				break;			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):   /* [1] IMPLICIT PublicPartyNumber */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PartyNumber: PublicPartyNumber len=%d\n", len);				size = rose_public_party_number_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				value->npi = PRI_NPI_E163_E164;				break;			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):   /* [3] IMPLICIT NumberDigits -- not used: dataPartyNumber */				pri_message(pri, "!! PartyNumber: dataPartyNumber is reserved!\n");				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				value->npi = PRI_NPI_X121 /* ??? */;				value->ton = PRI_TON_UNKNOWN /* ??? */;				break;			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4):   /* [4] IMPLICIT NumberDigits -- not used: telexPartyNumber */				pri_message(pri, "!! PartyNumber: telexPartyNumber is reserved!\n");				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				value->npi = PRI_NPI_F69 /* ??? */;				value->ton = PRI_TON_UNKNOWN /* ??? */;				break;			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):   /* [5] IMPLICIT PrivatePartyNumber */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PartyNumber: PrivatePartyNumber len=%d\n", len);				size = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1; 				value->npi = PRI_NPI_PRIVATE;				break;			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8):   /* [8] IMPLICIT NumberDigits -- not used: nationalStandatdPartyNumber */				pri_message(pri, "!! PartyNumber: nationalStandardPartyNumber is reserved!\n");				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				value->npi = PRI_NPI_NATIONAL;				value->ton = PRI_TON_NATIONAL;				break;			default:				pri_message(pri, "Invalid PartyNumber component 0x%X\n", comp->type);				return -1;		}		ASN1_FIXUP_LEN(comp, size);		if (pri->debug & PRI_DEBUG_APDU)			pri_message(pri, "     PartyNumber: '%s' size=%d len=%d\n", value->partyaddress, size, len);		return size;	}	while (0);	return -1;}static int rose_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value){	int i = 0;	int size = 0;	struct rose_component *comp = NULL;	unsigned char *vdata = data;	int scrind = -1;	do {		/* Party Number */		GET_COMPONENT(comp, i, vdata, len);		size = rose_party_number_decode(pri, call, (u_int8_t *)comp, comp->len + 2, (struct addressingdataelements_presentednumberunscreened*) value);		if (size < 0)			return -1;		comp->len = size;		NEXT_COMPONENT(comp, i);		/* Screening Indicator */		GET_COMPONENT(comp, i, vdata, len);		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with NumberScreened ROSE component type 0x%x\n");		ASN1_GET_INTEGER(comp, scrind);		// Todo: scrind = screeningindicator_for_q931(pri, scrind);		NEXT_COMPONENT(comp, i);		value->scrind = scrind;		if (pri->debug & PRI_DEBUG_APDU)			pri_message(pri, "     NumberScreened: '%s' ScreeningIndicator=%d  i=%d  len=%d\n", value->partyaddress, scrind, i, len);		return i-2;  // We do not have a sequence header here.	}	while (0);	return -1;}static int rose_presented_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *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_UNKNOWN;	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] IMPLICIT presentationAllowedNumber */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PresentedNumberScreened: presentationAllowedNumber comp->len=%d\n", comp->len);				value->pres = PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;				size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				ASN1_FIXUP_LEN(comp, size);				return size + 2;			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1):    /* [1] IMPLICIT presentationRestricted */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PresentedNumberScreened: presentationRestricted comp->len=%d\n", comp->len);				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_PASSED_SCREEN;				return 2;			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2):    /* [2] IMPLICIT numberNotAvailableDueToInterworking */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PresentedNumberScreened: NumberNotAvailableDueToInterworking comp->len=%d\n", comp->len);				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;				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PresentedNumberScreened: numberNotAvailableDueToInterworking Type=0x%X  i=%d len=%d size=%d\n", comp->type, i, len);				return 2;			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):    /* [3] IMPLICIT presentationRestrictedNumber */				if (pri->debug & PRI_DEBUG_APDU)					pri_message(pri, "     PresentedNumberScreened: presentationRestrictedNumber comp->len=%d\n", comp->len);				value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;				size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);				if (size < 0)					return -1;				ASN1_FIXUP_LEN(comp, size);				return size + 2;			default:				pri_message(pri, "Invalid PresentedNumberScreened component 0x%X\n", comp->

⌨️ 快捷键说明

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