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

📄 pri_facility.c

📁 Q921的LINUX下的驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		return -1;	if (q931_facility(apdubearer->pri, apdubearer)) {		pri_message(pri, "Could not schedule facility message for call %d\n", apdubearer->cr);		return -1;	}	return 0;}static int add_dms100_transfer_ability_apdu(struct pri *pri, q931_call *c){	int i = 0;	unsigned char buffer[256];	struct rose_component *comp = NULL, *compstk[10];	const unsigned char rlt_op_ind = RLT_OPERATION_IND;	int compsp = 0;	buffer[i++] = (Q932_PROTOCOL_ROSE);  /* Note to self: DON'T set the EXT bit */	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_op_ind);		/* Operation Tag - basically the same as the invoke ID tag */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_op_ind);	ASN1_FIXUP(compstk, compsp, buffer, i);	if (pri_call_apdu_queue(c, Q931_SETUP, buffer, i, NULL, NULL))		return -1;	else		return 0;}/* Sending callername information functions */static int add_callername_facility_ies(struct pri *pri, q931_call *c, int cpe){	int res = 0;	int i = 0;	unsigned char buffer[256];	unsigned char namelen = 0;	struct rose_component *comp = NULL, *compstk[10];	int compsp = 0;	int mymessage = 0;	static unsigned char op_tag[] = { 		0x2a, /* informationFollowing 42 */		0x86,		0x48,		0xce,		0x15,		0x00,		0x04	};			if (!strlen(c->callername)) {		return -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, 0);	ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);	ASN1_PUSH(compstk, compsp, comp);	/* Invoke ID */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));	/* Operation Tag */	res = asn1_string_encode(ASN1_OBJECTIDENTIFIER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag));	if (res < 0)		return -1;	i += res;	ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);	ASN1_FIXUP(compstk, compsp, buffer, i);	if (!cpe) {		if (pri_call_apdu_queue(c, Q931_SETUP, buffer, i, NULL, NULL))			return -1;	}	/* Now the APDU that contains the information that needs sent.	 * We can reuse the buffer since the queue function doesn't	 * need it. */	i = 0;	namelen = strlen(c->callername);	if (namelen > 50) {		namelen = 50; /* truncate the name */	}	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, 0);	ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);	ASN1_PUSH(compstk, compsp, comp);	/* Invoke ID */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));	/* Operation ID: Calling name */	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, SS_CNID_CALLINGNAME);	res = asn1_string_encode((ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), &buffer[i], sizeof(buffer)-i,  50, c->callername, namelen);	if (res < 0)		return -1;	i += res;	ASN1_FIXUP(compstk, compsp, buffer, i);	if (cpe) 		mymessage = Q931_SETUP;	else		mymessage = Q931_FACILITY;	if (pri_call_apdu_queue(c, mymessage, buffer, i, NULL, NULL))		return -1;		return 0;}/* End Callername *//* MWI related encode and decode functions */static void mwi_activate_encode_cb(void *data){	return;}int mwi_message_send(struct pri* pri, q931_call *call, struct pri_sr *req, int activate){	int i = 0;	unsigned char buffer[255] = "";	int destlen = strlen(req->called);	struct rose_component *comp = NULL, *compstk[10];	int compsp = 0;	int res;	if (destlen <= 0) {		return -1;	} else if (destlen > 20)		destlen = 20;  /* Destination number cannot be greater then 20 digits */	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, 0);	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));	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, (activate) ? SS_MWI_ACTIVATE : SS_MWI_DEACTIVATE);	ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);	ASN1_PUSH(compstk, compsp, comp);	/* PartyNumber */	res = asn1_string_encode((ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), &buffer[i], sizeof(buffer)-i, destlen, req->called, destlen);		if (res < 0)		return -1;	i += res;	/* Enumeration: basicService */	ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1 /* contents: Voice */);	ASN1_FIXUP(compstk, compsp, buffer, i);	ASN1_FIXUP(compstk, compsp, buffer, i);	return pri_call_apdu_queue(call, Q931_SETUP, buffer, i, mwi_activate_encode_cb, NULL);}/* End MWI *//* EECT functions */int eect_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];	int compsp = 0;	static unsigned char op_tag[] = {		0x2A,		0x86,		0x48,		0xCE,		0x15,		0x00,		0x08,	};	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, 0);	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_OBJECTIDENTIFIER, &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);	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 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(c1->pri, c1);	if (res) {		pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr);		return -1;	}	return 0;}/* End EECT *//* 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) {	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) */

⌨️ 快捷键说明

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