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

📄 pri_facility.c

📁 Q.931/Q.921 source code compiles
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 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))		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 */	if (pri->switchtype == PRI_SWITCH_QSIG) {		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 */	if (pri->switchtype == PRI_SWITCH_QSIG) {		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){	int i = 0;	int res = 0;	unsigned char buffer[255] = "";	short call_reference = c2->cr ^ 0x8000;  /* Let's do the trickery to make sure the flag is correct */	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_ROSE);	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);

⌨️ 快捷键说明

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