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

📄 q931.c

📁 Q.931/Q.921 source code compiles
💻 C
📖 第 1 页 / 共 5 页
字号:
	case Q931_PROG_CALLER_RETURNED_TO_ISDN:		call->progressmask |= PRI_PROG_CALLER_RETURNED_TO_ISDN;		break;	case Q931_PROG_INBAND_AVAILABLE:		call->progressmask |= PRI_PROG_INBAND_AVAILABLE;		break;	case Q931_PROG_DELAY_AT_INTERF:		call->progressmask |= PRI_PROG_DELAY_AT_INTERF;		break;	case Q931_PROG_INTERWORKING_WITH_PUBLIC:		call->progressmask |= PRI_PROG_INTERWORKING_WITH_PUBLIC;		break;	case Q931_PROG_INTERWORKING_NO_RELEASE:		call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE;		break;	case Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER:		call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER;		break;	case Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER:		call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER;		break;	default:		pri_error(pri, "XXX Invalid Progress indicator value received: %02x\n",(ie->data[1] & 0x7f));		break;	}	return 0;}static FUNC_SEND(transmit_facility){	struct apdu_event *tmp;	int i = 0;	for (tmp = call->apdus; tmp; tmp = tmp->next) {		if ((tmp->message == msgtype) && !tmp->sent)			break;	}		if (!tmp)	/* No APDU found */		return 0;	if (tmp->apdu_len > 235) { /* TODO: find out how much space we can use */		pri_message(pri, "Requested APDU (%d bytes) is too long\n", tmp->apdu_len);		return 0;	}		memcpy(&ie->data[i], tmp->apdu, tmp->apdu_len);	i += tmp->apdu_len;	tmp->sent = 1;	return i + 2;}static FUNC_RECV(receive_facility){	int i = 0;	int protocol, next_protocol;	struct rose_component *comp = NULL;	enum {		Q932_STATE_NFE,				/* Network facility extension */		Q932_STATE_NPP,				/* Network protocol profile */		Q932_STATE_INTERPRETATION,	/* Interpretation component */		Q932_STATE_SERVICE			/* Service component(s) */	} state = Q932_STATE_SERVICE;#define Q932_HANDLE_PROC(component, my_state, name, handler) \				case component: \					if(state > my_state) { \						pri_error(pri, "!! %s component received in wrong place\n"); \						break; \					} \					state = my_state; \					if (pri->debug) \						pri_message(pri, "Handle Q.932 %s component\n", name); \					(handler)(pri, call, ie, comp->data, comp->len); \					break;#define Q932_HANDLE_NULL(component, my_state, name, handle) \				case component: \					if(state > my_state) { \						pri_error(pri, "!! %s component received in wrong place\n"); \						break; \					} \					state = my_state; \					if (pri->debug & PRI_DEBUG_APDU) \						pri_message(pri, "Q.932 %s component is not handled\n", name); \					break;	if (ie->len < 1)		return -1;	switch(next_protocol = protocol = (ie->data[i] & 0x1f)) {	case Q932_PROTOCOL_CMIP:	case Q932_PROTOCOL_ACSE:		if (pri->debug & PRI_DEBUG_APDU)			pri_message(pri, "!! Don't know how to handle Q.932 Protocol Profile of type 0x%X\n", protocol);		return -1;	case Q932_PROTOCOL_EXTENSIONS:		state = Q932_STATE_NFE;		next_protocol = Q932_PROTOCOL_ROSE;		break;	case Q932_PROTOCOL_ROSE:		break;	default:		pri_error(pri, "!! Invalid Q.932 Protocol Profile of type 0x%X received\n", protocol);		return -1;	}	/* Service indicator octet - Just ignore for now */	if (!(ie->data[i] & 0x80))		i++;	i++;	if (ie->len < 3)		return -1;		while ((i+1 < ie->len) && (&ie->data[i])) {		comp = (struct rose_component*)&ie->data[i];		if (comp->type) {			if (protocol == Q932_PROTOCOL_EXTENSIONS) {				switch (comp->type) {				Q932_HANDLE_NULL(COMP_TYPE_INTERPRETATION, Q932_STATE_INTERPRETATION, "Interpretation", NULL);				Q932_HANDLE_NULL(COMP_TYPE_NFE, Q932_STATE_NFE, "Network facility extensions", NULL);				Q932_HANDLE_NULL(COMP_TYPE_NETWORK_PROTOCOL_PROFILE, Q932_STATE_NPP, "Network protocol profile", NULL);				default:					protocol = next_protocol;					break;				}			}			switch (protocol) {			case Q932_PROTOCOL_ROSE:				switch (comp->type) {				Q932_HANDLE_PROC(COMP_TYPE_INVOKE, Q932_STATE_SERVICE, "ROSE Invoke", rose_invoke_decode);				Q932_HANDLE_PROC(COMP_TYPE_RETURN_RESULT, Q932_STATE_SERVICE, "ROSE return result", rose_return_result_decode);				Q932_HANDLE_PROC(COMP_TYPE_RETURN_ERROR, Q932_STATE_SERVICE, "ROSE return error", rose_return_error_decode);				Q932_HANDLE_PROC(COMP_TYPE_REJECT, Q932_STATE_SERVICE, "ROSE reject", rose_reject_decode);				default:					if (pri->debug & PRI_DEBUG_APDU)						pri_message(pri, "Don't know how to handle ROSE component of type 0x%X\n", comp->type);					break;				}				break;			case Q932_PROTOCOL_CMIP:				switch (comp->type) {				default:					if (pri->debug & PRI_DEBUG_APDU)						pri_message(pri, "Don't know how to handle CMIP component of type 0x%X\n", comp->type);					break;				}				break;			case Q932_PROTOCOL_ACSE:				switch (comp->type) {				default:					if (pri->debug & PRI_DEBUG_APDU)						pri_message(pri, "Don't know how to handle ACSE component of type 0x%X\n", comp->type);					break;				}				break;			}		}		i += (comp->len + 2);	}#undef Q932_HANDLE	return 0;}static FUNC_SEND(transmit_progress_indicator){	int code, mask;	/* Can't send progress indicator on GR-303 -- EVER! */	if (pri->subchannel && !pri->bri)		return 0;	if (call->progressmask > 0) {		if (call->progressmask & (mask = PRI_PROG_CALL_NOT_E2E_ISDN))			code = Q931_PROG_CALL_NOT_E2E_ISDN;		else if (call->progressmask & (mask = PRI_PROG_CALLED_NOT_ISDN))			code = Q931_PROG_CALLED_NOT_ISDN;		else if (call->progressmask & (mask = PRI_PROG_CALLER_NOT_ISDN))			code = Q931_PROG_CALLER_NOT_ISDN;		else if (call->progressmask & (mask = PRI_PROG_INBAND_AVAILABLE))			code = Q931_PROG_INBAND_AVAILABLE;		else if (call->progressmask & (mask = PRI_PROG_DELAY_AT_INTERF))			code = Q931_PROG_DELAY_AT_INTERF;		else if (call->progressmask & (mask = PRI_PROG_INTERWORKING_WITH_PUBLIC))			code = Q931_PROG_INTERWORKING_WITH_PUBLIC;		else if (call->progressmask & (mask = PRI_PROG_INTERWORKING_NO_RELEASE))			code = Q931_PROG_INTERWORKING_NO_RELEASE;		else if (call->progressmask & (mask = PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER))			code = Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER;		else if (call->progressmask & (mask = PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER))			code = Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER;		else {			code = 0;			pri_error(pri, "XXX Undefined progress bit: %x\n", call->progressmask);		}		if (code) {			ie->data[0] = 0x80 | (call->progcode << 5)  | (call->progloc);			ie->data[1] = 0x80 | code;			call->progressmask &= ~mask;			return 4;		}	}	/* Leave off */	return 0;}static FUNC_SEND(transmit_call_state){	if (call->ourcallstate > -1 ) {		ie->data[0] = call->ourcallstate;		return 3;	}	return 0;}static FUNC_RECV(receive_call_state){	call->sugcallstate = ie->data[0] & 0x3f;	return 0;}static char *callstate2str(int callstate){	static struct msgtype callstates[] = {		{ 0, "Null" },		{ 1, "Call Initiated" },		{ 2, "Overlap sending" },		{ 3, "Outgoing call  Proceeding" },		{ 4, "Call Delivered" },		{ 6, "Call Present" },		{ 7, "Call Received" },		{ 8, "Connect Request" },		{ 9, "Incoming Call Proceeding" },		{ 10, "Active" },		{ 11, "Disconnect Request" },		{ 12, "Disconnect Indication" },		{ 15, "Suspend Request" },		{ 17, "Resume Request" },		{ 19, "Release Request" },		{ 22, "Call Abort" },		{ 25, "Overlap Receiving" },		{ 61, "Restart Request" },		{ 62, "Restart" },	};	return code2str(callstate, callstates, sizeof(callstates) / sizeof(callstates[0]));}static FUNC_DUMP(dump_call_state){	pri_message(pri, "%c Call State (len=%2d) [ Ext: %d  Coding: %s (%d)  Call state: %s (%d)\n",		prefix, len, ie->data[0] >> 7, coding2str((ie->data[0] & 0xC0) >> 6), (ie->data[0] & 0xC0) >> 6,		callstate2str(ie->data[0] & 0x3f), ie->data[0] & 0x3f);}static FUNC_DUMP(dump_call_identity){	int x;	pri_message(pri, "%c Call Identity (len=%2d) [ ", prefix, len);	for (x=0;x<ie->len;x++) 		pri_message(pri, "0x%02X ", ie->data[x]);	pri_message(pri, " ]\n");}static FUNC_DUMP(dump_time_date){	pri_message(pri, "%c Time Date (len=%2d) [ ", prefix, len);	if (ie->len > 0)		pri_message(pri, "%02d", ie->data[0]);	if (ie->len > 1)		pri_message(pri, "-%02d", ie->data[1]);	if (ie->len > 2)		pri_message(pri, "-%02d", ie->data[2]);	if (ie->len > 3)		pri_message(pri, " %02d", ie->data[3]);	if (ie->len > 4)		pri_message(pri, ":%02d", ie->data[4]);	if (ie->len > 5)		pri_message(pri, ":%02d", ie->data[5]);	pri_message(pri, " ]\n");}static FUNC_DUMP(dump_keypad_facility){	char tmp[64];		if (ie->len == 0 || ie->len > sizeof(tmp))		return;		memcpy(tmp, ie->data, ie->len);	tmp[ie->len] = '\0';	pri_message(pri, "%c Keypad Facility (len=%2d) [ %s ]\n", prefix, ie->len, tmp );}static FUNC_RECV(receive_keypad_facility){	int mylen;	if (ie->len == 0)		return -1;	if (ie->len > (sizeof(call->keypad_digits) - 1))		mylen = (sizeof(call->keypad_digits) - 1);	else		mylen = ie->len;	memcpy(call->keypad_digits, ie->data, mylen);	call->keypad_digits[mylen] = 0;	return 0;}static FUNC_SEND(transmit_keypad_facility){	int sublen;	sublen = strlen(call->keypad_digits);	if (sublen > 32) {		sublen = 32;		call->keypad_digits[32] = '\0';	}	if (sublen) {		libpri_copy_string((char *)ie->data, (char *)call->keypad_digits, sizeof(call->keypad_digits));		/* Make sure we clear the field */		call->keypad_digits[0] = '\0';		return sublen + 2;	} else		return 0;}static FUNC_DUMP(dump_display){	int x, y;	char *buf = malloc(len + 1);	char tmp[80] = "";	if (buf) {		x=y=0;		if ((x < ie->len) && (ie->data[x] & 0x80)) {			sprintf(tmp, "Charset: %02x ", ie->data[x] & 0x7f);			++x;		}		for (y=x; x<ie->len; x++) 			buf[x] = ie->data[x] & 0x7f;		buf[x] = '\0';		pri_message(pri, "%c Display (len=%2d) %s[ %s ]\n", prefix, ie->len, tmp, &buf[y]);		free(buf);	}}#define CHECK_OVERFLOW(limit) \	if (tmpptr - tmp + limit >= sizeof(tmp)) { \		*tmpptr = '\0'; \		pri_message(pri, "%s", tmpptr = tmp); \	}static void dump_ie_data(struct pri *pri, unsigned char *c, int len){	static char hexs[16] = "0123456789ABCDEF";	char tmp[1024], *tmpptr;	int lastascii = 0;	tmpptr = tmp;	for (; len; --len, ++c) {		CHECK_OVERFLOW(7);		if (isprint(*c)) {			if (!lastascii) {				if (tmpptr != tmp) { 					*tmpptr++ = ',';					*tmpptr++ = ' ';				}				*tmpptr++ = '\'';				lastascii = 1;			}			*tmpptr++ = *c;		} else {			if (lastascii) {				*tmpptr++ = '\'';				lastascii = 0;			}			if (tmpptr != tmp) { 				*tmpptr++ = ',';				*tmpptr++ = ' ';			}			*tmpptr++ = '0';			*tmpptr++ = 'x';			*tmpptr++ = hexs[(*c >> 4) & 0x0f];			*tmpptr++ = hexs[(*c) & 0x0f];		}	}	if (lastascii)		*tmpptr++ = '\'';	*tmpptr = '\0';	pri_message(pri, "%s", tmp);}static FUNC_DUMP(dump_facility){	int dataat = (ie->data[0] & 0x80) ? 1 : 2;	pri_message(pri, "%c Facility (len=%2d, codeset=%d) [ ", prefix, len, Q931_IE_CODESET(full_ie));	dump_ie_data(pri, ie->data, ie->len);	pri_message(NULL, " ]\n");	if (ie->len > 1) {		pri_message(pri, "PROTOCOL %02X\n", ie->data[0] & ASN1_TYPE_MASK);		asn1_dump(pri, &ie->data[dataat], ie->len - dataat);	}}static FUNC_DUMP(dump_network_spec_fac){	pri_message(pri, "%c Network-Specific Facilities (len=%2d) [ ", prefix, ie->len);	if (ie->data[0] == 0x00) { 		pri_message(pri, "%s", code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0])));	}	else 		dump_ie_data(pri, ie->data, ie->len);	pri_message(pri, " ]\n");}static FUNC_RECV(receive_network_spec_fac){	return 0;}static FUNC_SEND(transmit_network_spec_fac){	/* We are ready to transmit single IE only */

⌨️ 快捷键说明

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