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

📄 q931.c

📁 Q921的LINUX下的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	do {		switch(i) {		case 0:	/* Octet 3 */			pri_message(pri, "%c Redirecting Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)",				prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);			break;		case 1: /* Octet 3a */			pri_message(pri, "\n%c                               Ext: %d  Presentation: %s (%d)",				prefix, ie->data[1] >> 7, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f);			break;		case 2: /* Octet 3b */			pri_message(pri, "\n%c                               Ext: %d  Reason: %s (%d)",				prefix, ie->data[2] >> 7, redirection_reason2str(ie->data[2] & 0x7f), ie->data[2] & 0x7f);			break;		}	}	while(!(ie->data[i++]& 0x80));	q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);	pri_message(pri, "  '%s' ]\n", cnum);}static FUNC_DUMP(dump_connected_number){	unsigned char cnum[256];	int i = 0;	/* To follow Q.931 (4.5.1), we must search for start of octet 4 by	   walking through all bytes until one with ext bit (8) set to 1 */	do {		switch(i) {		case 0:	/* Octet 3 */			pri_message(pri, "%c Connected Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)",				prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);			break;		case 1: /* Octet 3a */			pri_message(pri, "\n%c                             Ext: %d  Presentation: %s (%d)",				prefix, ie->data[1] >> 7, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f);			break;		}	}	while(!(ie->data[i++]& 0x80));	q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);	pri_message(pri, "  '%s' ]\n", cnum);}static FUNC_RECV(receive_redirecting_number){	int i = 0;	/* To follow Q.931 (4.5.1), we must search for start of octet 4 by	   walking through all bytes until one with ext bit (8) set to 1 */	do {		switch(i) {		case 0:			call->redirectingplan = ie->data[i] & 0x7f;			break;		case 1:			call->redirectingpres = ie->data[i] & 0x7f;			break;		case 2:			call->redirectingreason = ie->data[i] & 0x0f;			break;		}	}	while(!(ie->data[i++] & 0x80));	q931_get_number((unsigned char *) call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i);	return 0;}static FUNC_SEND(transmit_redirecting_number){	if (order > 1)		return 0;	if (call->redirectingnum && *call->redirectingnum) {		ie->data[0] = call->redirectingplan;		ie->data[1] = call->redirectingpres;		ie->data[2] = (call->redirectingreason & 0x0f) | 0x80;		memcpy(ie->data + 3, call->redirectingnum, strlen(call->redirectingnum));		return strlen(call->redirectingnum) + 3 + 2;	}	return 0;}static FUNC_DUMP(dump_redirecting_subaddr){	unsigned char cnum[256];	q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);	pri_message(pri, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",		prefix, len, ie->data[0] >> 7,		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,		(ie->data[0] & 0x08) >> 3, cnum);}static FUNC_RECV(receive_calling_party_subaddr){	/* copy digits to call->callingsubaddr */ 	q931_get_number((unsigned char *) call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);	return 0;}static FUNC_RECV(receive_called_party_number){	/* copy digits to call->callednum */ 	q931_get_number((unsigned char *) call->callednum, sizeof(call->callednum), ie->data + 1, len - 3);	call->calledplan = ie->data[0] & 0x7f;	return 0;}static FUNC_SEND(transmit_called_party_number){	ie->data[0] = 0x80 | call->calledplan;	if (*call->callednum)		memcpy(ie->data + 1, call->callednum, strlen(call->callednum));	return strlen(call->callednum) + 3;}static FUNC_RECV(receive_calling_party_number){	u_int8_t *data;	size_t length;        	if (ie->data[0] & 0x80) {		data = ie->data + 1;		length = len - 3;		call->callerpres = 0; /* PI presentation allowed SI user-provided, not screened */        	} else {		data = ie->data + 2;		length = len - 4;		call->callerpres = ie->data[1] & 0x7f;	}	if (call->callerpres == PRES_ALLOWED_NETWORK_NUMBER ||		call->callerpres == PRES_PROHIB_NETWORK_NUMBER) {		q931_get_number((u_int8_t *)call->callerani, sizeof(call->callerani), data, length);		call->callerplanani = ie->data[0] & 0x7f;		if (!*call->callernum) { /*Copy ANI to CallerID if CallerID is not already set */			libpri_copy_string(call->callernum, call->callerani, sizeof(call->callernum));			call->callerplan = call->callerplanani;		}			} else {		q931_get_number((u_int8_t *)call->callernum, sizeof(call->callernum), data, length);		call->callerplan = ie->data[0] & 0x7f;	}	return 0;}static FUNC_SEND(transmit_calling_party_number){	ie->data[0] = call->callerplan;	ie->data[1] = 0x80 | call->callerpres;	if (*call->callernum) 		memcpy(ie->data + 2, call->callernum, strlen(call->callernum));	return strlen(call->callernum) + 4;}static FUNC_DUMP(dump_user_user){	int x;	pri_message(pri, "%c User-User Information (len=%2d) [", prefix, len);	for (x=0;x<ie->len;x++)		pri_message(pri, " %02x", ie->data[x] & 0x7f);	pri_message(pri, " ]\n");}static FUNC_RECV(receive_user_user){                call->useruserprotocoldisc = ie->data[0] & 0xff;        if (call->useruserprotocoldisc == 4) /* IA5 */          q931_get_number((unsigned char *) call->useruserinfo, sizeof(call->useruserinfo), ie->data + 1, len - 3);	return 0;}static FUNC_SEND(transmit_user_user){        	int datalen = strlen(call->useruserinfo);	if (datalen > 0) {		/* Restricted to 35 characters */		if (msgtype == Q931_USER_INFORMATION) {			if (datalen > 260)				datalen = 260;		} else {			if (datalen > 35)				datalen = 35;		}		ie->data[0] = 4; /* IA5 characters */		memcpy(&ie->data[1], call->useruserinfo, datalen);		call->useruserinfo[0] = '\0';		return datalen + 3;	}	return 0;}static char *prog2str(int prog){	static struct msgtype progs[] = {		{ Q931_PROG_CALL_NOT_E2E_ISDN, "Call is not end-to-end ISDN; further call progress information may be available inband." },		{ Q931_PROG_CALLED_NOT_ISDN, "Called equipment is non-ISDN." },		{ Q931_PROG_CALLER_NOT_ISDN, "Calling equipment is non-ISDN." },		{ Q931_PROG_INBAND_AVAILABLE, "Inband information or appropriate pattern now available." },		{ Q931_PROG_DELAY_AT_INTERF, "Delay in response at called Interface." },		{ Q931_PROG_INTERWORKING_WITH_PUBLIC, "Interworking with a public network." },		{ Q931_PROG_INTERWORKING_NO_RELEASE, "Interworking with a network unable to supply a release signal." },		{ Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER, "Interworking with a network unable to supply a release signal before answer." },		{ Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER, "Interworking with a network unable to supply a release signal after answer." },	};	return code2str(prog, progs, sizeof(progs) / sizeof(progs[0]));}static char *coding2str(int cod){	static struct msgtype cods[] = {		{ CODE_CCITT, "CCITT (ITU) standard" },		{ CODE_INTERNATIONAL, "Non-ITU international standard" }, 		{ CODE_NATIONAL, "National standard" }, 		{ CODE_NETWORK_SPECIFIC, "Network specific standard" },	};	return code2str(cod, cods, sizeof(cods) / sizeof(cods[0]));}static char *loc2str(int loc){	static struct msgtype locs[] = {		{ LOC_USER, "User" },		{ LOC_PRIV_NET_LOCAL_USER, "Private network serving the local user" },		{ LOC_PUB_NET_LOCAL_USER, "Public network serving the local user" },		{ LOC_TRANSIT_NET, "Transit network" },		{ LOC_PUB_NET_REMOTE_USER, "Public network serving the remote user" },		{ LOC_PRIV_NET_REMOTE_USER, "Private network serving the remote user" },		{ LOC_INTERNATIONAL_NETWORK, "International network" },		{ LOC_NETWORK_BEYOND_INTERWORKING, "Network beyond the interworking point" },	};	return code2str(loc, locs, sizeof(locs) / sizeof(locs[0]));}static FUNC_DUMP(dump_progress_indicator){	pri_message(pri, "%c Progress Indicator (len=%2d) [ Ext: %d  Coding: %s (%d)  0: %d  Location: %s (%d)\n",		prefix, len, ie->data[0] >> 7, coding2str((ie->data[0] & 0x60) >> 5), (ie->data[0] & 0x60) >> 5,		(ie->data[0] & 0x10) >> 4, loc2str(ie->data[0] & 0xf), ie->data[0] & 0xf);	pri_message(pri, "%c                               Ext: %d  Progress Description: %s (%d) ]\n",		prefix, ie->data[1] >> 7, prog2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f);}static FUNC_RECV(receive_display){	unsigned char *data;	data = ie->data;	if (data[0] & 0x80) {		/* Skip over character set */		data++;		len--;	}	q931_get_number((unsigned char *) call->callername, sizeof(call->callername), data, len - 2);	return 0;}static FUNC_SEND(transmit_display){	int i;		if ((pri->switchtype == PRI_SWITCH_QSIG) ||	    ((pri->switchtype == PRI_SWITCH_EUROISDN_E1) && (pri->localtype == PRI_CPE)) ||	    !call->callername[0])		return 0;	i = 0;	if(pri->switchtype != PRI_SWITCH_EUROISDN_E1) {		ie->data[0] = 0xb1;		++i;	}	memcpy(ie->data + i, call->callername, strlen(call->callername));	return 2 + i + strlen(call->callername);}static FUNC_RECV(receive_progress_indicator){	call->progloc = ie->data[0] & 0xf;	call->progcode = (ie->data[0] & 0x60) >> 5;	switch (call->progress = (ie->data[1] & 0x7f)) {	case Q931_PROG_CALL_NOT_E2E_ISDN:		call->progressmask |= PRI_PROG_CALL_NOT_E2E_ISDN;		break;	case Q931_PROG_CALLED_NOT_ISDN:		call->progressmask |= PRI_PROG_CALLED_NOT_ISDN;		break;	case Q931_PROG_CALLER_NOT_ISDN:		call->progressmask |= PRI_PROG_CALLER_NOT_ISDN;		break;	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, 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;

⌨️ 快捷键说明

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