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

📄 pri_facility.c

📁 Q.931/Q.921 source code compiles
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * libpri: An implementation of Primary Rate ISDN * * Written by Matthew Fredrickson <creslin@digium.com> * * Copyright (C) 2004-2005, Digium, Inc. * All Rights Reserved. *//* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. * * In addition, when this program is distributed with Asterisk in * any form that would qualify as a 'combined work' or as a * 'derivative work' (but not mere aggregation), you can redistribute * and/or modify the combination under the terms of the license * provided with that copy of Asterisk, instead of the license * terms granted here. */#include "compat.h"#include "libpri.h"#include "pri_internal.h"#include "pri_q921.h"#include "pri_q931.h"#include "pri_facility.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>static char *asn1id2text(int id){	static char data[32];	static char *strings[] = {		"none",		"Boolean",		"Integer",		"Bit String",		"Octet String",		"NULL",		"Object Identifier",		"Object Descriptor",		"External Reference",		"Real Number",		"Enumerated",		"Embedded PDV",		"UTF-8 String",		"Relative Object ID",		"Reserved (0e)",		"Reserved (0f)",		"Sequence",		"Set",		"Numeric String",		"Printable String",		"Tele-Text String",		"IA-5 String",		"UTC Time",		"Generalized Time",	};	if (id > 0 && id <= 0x18) {		return strings[id];	} else {		sprintf(data, "Unknown (%02x)", id);		return data;	}}static int asn1_dumprecursive(struct pri *pri, void *comp_ptr, int len, int level){	unsigned char *vdata = (unsigned char *)comp_ptr;	struct rose_component *comp;	int i = 0;	int j, k, l;	int clen = 0;	while (len > 0) {		GET_COMPONENT(comp, i, vdata, len);		pri_message(pri, "%*s%02X %04X", 2 * level, "", comp->type, comp->len);		if ((comp->type == 0) && (comp->len == 0))			return clen + 2;		if ((comp->type & ASN1_PC_MASK) == ASN1_PRIMITIVE) {			for (j = 0; j < comp->len; ++j)				pri_message(pri, " %02X", comp->data[j]);		}		if ((comp->type & ASN1_CLAN_MASK) == ASN1_UNIVERSAL) {			switch (comp->type & ASN1_TYPE_MASK) {			case 0:				pri_message(pri, " (none)");				break;			case ASN1_BOOLEAN:				pri_message(pri, " (BOOLEAN: %d)", comp->data[0]);				break;			case ASN1_INTEGER:				for (k = l = 0; k < comp->len; ++k)					l = (l << 8) | comp->data[k];				pri_message(pri, " (INTEGER: %d)", l);				break;			case ASN1_BITSTRING:				pri_message(pri, " (BITSTRING:");				for (k = 0; k < comp->len; ++k)				pri_message(pri, " %02x", comp->data[k]);				pri_message(pri, ")");				break;			case ASN1_OCTETSTRING:				pri_message(pri, " (OCTETSTRING:");				for (k = 0; k < comp->len; ++k)					pri_message(pri, " %02x", comp->data[k]);				pri_message(pri, ")");				break;			case ASN1_NULL:				pri_message(pri, " (NULL)");				break;			case ASN1_OBJECTIDENTIFIER:				pri_message(pri, " (OBJECTIDENTIFIER:");				for (k = 0; k < comp->len; ++k)					pri_message(pri, " %02x", comp->data[k]);				pri_message(pri, ")");				break;			case ASN1_ENUMERATED:				for (k = l = 0; k < comp->len; ++k)					l = (l << 8) | comp->data[k];				pri_message(pri, " (ENUMERATED: %d)", l);				break;			case ASN1_SEQUENCE:				pri_message(pri, " (SEQUENCE)");				break;			default:				pri_message(pri, " (component %02x - %s)", comp->type, asn1id2text(comp->type & ASN1_TYPE_MASK));				break;			}		}		else if ((comp->type & ASN1_CLAN_MASK) == ASN1_CONTEXT_SPECIFIC) {			pri_message(pri, " (CONTEXT SPECIFIC [%d])", comp->type & ASN1_TYPE_MASK);		}		else {			pri_message(pri, " (component %02x)", comp->type);		}		pri_message(pri, "\n");		if ((comp->type & ASN1_PC_MASK) == ASN1_CONSTRUCTOR)			j = asn1_dumprecursive(pri, comp->data, (comp->len ? comp->len : INT_MAX), level+1);		else			j = comp->len;		j += 2;		len -= j;		vdata += j;		clen += j;	}	return clen;}int asn1_dump(struct pri *pri, void *comp, int len){	return asn1_dumprecursive(pri, comp, len, 0);}static unsigned char get_invokeid(struct pri *pri){	return ++pri->last_invoke;}struct addressingdataelements_presentednumberunscreened {	char partyaddress[21];	char partysubaddress[21];	int  npi;       /* Numbering Plan Indicator */	int  ton;       /* Type Of Number */	int  pres;      /* Presentation */};struct addressingdataelements_presentednumberscreened {	char partyaddress[21];	char partysubaddress[21];	int  npi;       /* Numbering Plan Indicator */	int  ton;       /* Type Of Number */	int  pres;      /* Presentation */	int  scrind;    /* Screening Indicator */};#define PRI_CHECKOVERFLOW(size) \		if (msgptr - message + (size) >= sizeof(message)) { \			*msgptr = '\0'; \			pri_message(pri, "%s", message); \			msgptr = message; \		}static void dump_apdu(struct pri *pri, unsigned char *c, int len) {	#define MAX_APDU_LENGTH	255	static char hexs[16] = "0123456789ABCDEF";	int i;	char message[(2 + MAX_APDU_LENGTH * 3 + 6 + MAX_APDU_LENGTH + 3)] = "";	/* please adjust here, if you make changes below! */	char *msgptr;		msgptr = message;	*msgptr++ = ' ';	*msgptr++ = '[';	for (i=0; i<len; i++) {		PRI_CHECKOVERFLOW(3);		*msgptr++ = ' ';		*msgptr++ = hexs[(c[i] >> 4) & 0x0f];		*msgptr++ = hexs[(c[i]) & 0x0f];	}	PRI_CHECKOVERFLOW(6);	strcpy(msgptr, " ] - [");	msgptr += strlen(msgptr);	for (i=0; i<len; i++) {		PRI_CHECKOVERFLOW(1);		*msgptr++ = ((c[i] < ' ') || (c[i] > '~')) ? '.' : c[i];	}	PRI_CHECKOVERFLOW(2);	*msgptr++ = ']';	*msgptr++ = '\n';	*msgptr = '\0';	pri_message(pri, "%s", message);}#undef PRI_CHECKOVERFLOWint redirectingreason_from_q931(struct pri *pri, int redirectingreason){	switch(pri->switchtype) {		case PRI_SWITCH_QSIG:			switch(redirectingreason) {				case PRI_REDIR_UNKNOWN:					return QSIG_DIVERT_REASON_UNKNOWN;				case PRI_REDIR_FORWARD_ON_BUSY:					return QSIG_DIVERT_REASON_CFB;				case PRI_REDIR_FORWARD_ON_NO_REPLY:					return QSIG_DIVERT_REASON_CFNR;				case PRI_REDIR_UNCONDITIONAL:					return QSIG_DIVERT_REASON_CFU;				case PRI_REDIR_DEFLECTION:				case PRI_REDIR_DTE_OUT_OF_ORDER:				case PRI_REDIR_FORWARDED_BY_DTE:					pri_message(pri, "!! Don't know how to convert Q.931 redirection reason %d to Q.SIG\n", redirectingreason);					/* Fall through */				default:					return QSIG_DIVERT_REASON_UNKNOWN;			}		default:			switch(redirectingreason) {				case PRI_REDIR_UNKNOWN:					return Q952_DIVERT_REASON_UNKNOWN;				case PRI_REDIR_FORWARD_ON_BUSY:					return Q952_DIVERT_REASON_CFB;				case PRI_REDIR_FORWARD_ON_NO_REPLY:					return Q952_DIVERT_REASON_CFNR;				case PRI_REDIR_DEFLECTION:					return Q952_DIVERT_REASON_CD;				case PRI_REDIR_UNCONDITIONAL:					return Q952_DIVERT_REASON_CFU;				case PRI_REDIR_DTE_OUT_OF_ORDER:				case PRI_REDIR_FORWARDED_BY_DTE:					pri_message(pri, "!! Don't know how to convert Q.931 redirection reason %d to Q.952\n", redirectingreason);					/* Fall through */				default:					return Q952_DIVERT_REASON_UNKNOWN;			}	}}static int redirectingreason_for_q931(struct pri *pri, int redirectingreason){	switch(pri->switchtype) {		case PRI_SWITCH_QSIG:			switch(redirectingreason) {				case QSIG_DIVERT_REASON_UNKNOWN:					return PRI_REDIR_UNKNOWN;				case QSIG_DIVERT_REASON_CFU:					return PRI_REDIR_UNCONDITIONAL;				case QSIG_DIVERT_REASON_CFB:					return PRI_REDIR_FORWARD_ON_BUSY;				case QSIG_DIVERT_REASON_CFNR:					return PRI_REDIR_FORWARD_ON_NO_REPLY;				default:					pri_message(pri, "!! Unknown Q.SIG diversion reason %d\n", redirectingreason);					return PRI_REDIR_UNKNOWN;			}		default:			switch(redirectingreason) {				case Q952_DIVERT_REASON_UNKNOWN:					return PRI_REDIR_UNKNOWN;				case Q952_DIVERT_REASON_CFU:					return PRI_REDIR_UNCONDITIONAL;				case Q952_DIVERT_REASON_CFB:					return PRI_REDIR_FORWARD_ON_BUSY;				case Q952_DIVERT_REASON_CFNR:					return PRI_REDIR_FORWARD_ON_NO_REPLY;				case Q952_DIVERT_REASON_CD:					return PRI_REDIR_DEFLECTION;				case Q952_DIVERT_REASON_IMMEDIATE:					pri_message(pri, "!! Dont' know how to convert Q.952 diversion reason IMMEDIATE to PRI analog\n");					return PRI_REDIR_UNKNOWN;	/* ??? */				default:					pri_message(pri, "!! Unknown Q.952 diversion reason %d\n", redirectingreason);					return PRI_REDIR_UNKNOWN;			}	}}int typeofnumber_from_q931(struct pri *pri, int ton){	switch(ton) {		case PRI_TON_INTERNATIONAL:			return Q932_TON_INTERNATIONAL;		case PRI_TON_NATIONAL:			return Q932_TON_NATIONAL;		case PRI_TON_NET_SPECIFIC:			return Q932_TON_NET_SPECIFIC;		case PRI_TON_SUBSCRIBER:			return Q932_TON_SUBSCRIBER;		case PRI_TON_ABBREVIATED:			return Q932_TON_ABBREVIATED;		case PRI_TON_RESERVED:		default:			pri_message(pri, "!! Unsupported Q.931 TypeOfNumber value (%d)\n", ton);			/* fall through */		case PRI_TON_UNKNOWN:			return Q932_TON_UNKNOWN;	}}static int typeofnumber_for_q931(struct pri *pri, int ton){	switch (ton) {		case Q932_TON_UNKNOWN:			return PRI_TON_UNKNOWN;		case Q932_TON_INTERNATIONAL:			return PRI_TON_INTERNATIONAL;		case Q932_TON_NATIONAL:			return PRI_TON_NATIONAL;		case Q932_TON_NET_SPECIFIC:			return PRI_TON_NET_SPECIFIC;		case Q932_TON_SUBSCRIBER:			return PRI_TON_SUBSCRIBER;		case Q932_TON_ABBREVIATED:			return PRI_TON_ABBREVIATED;		default:			pri_message(pri, "!! Invalid Q.932 TypeOfNumber %d\n", ton);			return PRI_TON_UNKNOWN;	}}int asn1_name_decode(void * data, int len, char *namebuf, int buflen){	struct rose_component *comp = (struct rose_component*)data;	int datalen = 0, res = 0;	if (comp->len == ASN1_LEN_INDEF) {		datalen = strlen((char *)comp->data);		res = datalen + 2;	} else		datalen = res = comp->len;	if (datalen > buflen) {		/* Truncate */		datalen = buflen;	}	memcpy(namebuf, comp->data, datalen);	return res + 2;}int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len){	struct rose_component *comp = NULL;		if (len < 2 + src_len)		return -1;	if (max_len && (src_len > max_len))		src_len = max_len;	comp = (struct rose_component *)data;	comp->type = asn1_type;	comp->len = src_len;	memcpy(comp->data, src, src_len);		return 2 + src_len;}int asn1_copy_string(char * buf, int buflen, struct rose_component *comp){	int res;	int datalen;

⌨️ 快捷键说明

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