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

📄 l3_1tr6.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: l3_1tr6.c,v 2.15.2.3 2004/01/13 14:31:25 keil Exp $ * * German 1TR6 D-channel protocol * * Author       Karsten Keil * Copyright    by Karsten Keil      <keil@isdn4linux.de> *  * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read * Documentation/isdn/HiSax.cert * */#include "hisax.h"#include "l3_1tr6.h"#include "isdnl3.h"#include <linux/ctype.h>extern char *HiSax_getrev(const char *revision);static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";#define MsgHead(ptr, cref, mty, dis) \	*ptr++ = dis; \	*ptr++ = 0x1; \	*ptr++ = cref ^ 0x80; \	*ptr++ = mtystatic voidl3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd){	struct sk_buff *skb;	u_char *p;	if (!(skb = l3_alloc_skb(4)))		return;	p = skb_put(skb, 4);	MsgHead(p, pc->callref, mt, pd);	l3_msg(pc->st, DL_DATA | REQUEST, skb);}static voidl3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg){	StopAllL3Timer(pc);	newl3state(pc, 19);	l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);	L3AddTimer(&pc->timer, T308, CC_T308_1);}static voidl3_1tr6_invalid(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	dev_kfree_skb(skb);	l3_1tr6_release_req(pc, 0, NULL);}static voidl3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb){	dev_kfree_skb(skb);	if (pc->st->l3.debug & L3_DEB_WARN)		l3_debug(pc->st, msg);	l3_1tr6_release_req(pc, 0, NULL);}static voidl3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[128];	u_char *p = tmp;	u_char *teln;	u_char *eaz;	u_char channel = 0;	int l;	MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1);	teln = pc->para.setup.phone;	pc->para.spv = 0;	if (!isdigit(*teln)) {		switch (0x5f & *teln) {			case 'S':				pc->para.spv = 1;				break;			case 'C':				channel = 0x08;			case 'P':				channel |= 0x80;				teln++;				if (*teln == '1')					channel |= 0x01;				else					channel |= 0x02;				break;			default:				if (pc->st->l3.debug & L3_DEB_WARN)					l3_debug(pc->st, "Wrong MSN Code");				break;		}		teln++;	}	if (channel) {		*p++ = 0x18;	/* channel indicator */		*p++ = 1;		*p++ = channel;	}	if (pc->para.spv) {	/* SPV ? */		/* NSF SPV */		*p++ = WE0_netSpecFac;		*p++ = 4;	/* Laenge */		*p++ = 0;		*p++ = FAC_SPV;	/* SPV */		*p++ = pc->para.setup.si1;	/* 0 for all Services */		*p++ = pc->para.setup.si2;	/* 0 for all Services */		*p++ = WE0_netSpecFac;		*p++ = 4;	/* Laenge */		*p++ = 0;		*p++ = FAC_Activate;	/* aktiviere SPV (default) */		*p++ = pc->para.setup.si1;	/* 0 for all Services */		*p++ = pc->para.setup.si2;	/* 0 for all Services */	}	eaz = pc->para.setup.eazmsn;	if (*eaz) {		*p++ = WE0_origAddr;		*p++ = strlen(eaz) + 1;		/* Classify as AnyPref. */		*p++ = 0x81;	/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */		while (*eaz)			*p++ = *eaz++ & 0x7f;	}	*p++ = WE0_destAddr;	*p++ = strlen(teln) + 1;	/* Classify as AnyPref. */	*p++ = 0x81;		/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */	while (*teln)		*p++ = *teln++ & 0x7f;	*p++ = WE_Shift_F6;	/* Codesatz 6 fuer Service */	*p++ = WE6_serviceInd;	*p++ = 2;		/* len=2 info,info2 */	*p++ = pc->para.setup.si1;	*p++ = pc->para.setup.si2;	l = p - tmp;	if (!(skb = l3_alloc_skb(l)))		return;	memcpy(skb_put(skb, l), tmp, l);	L3DelTimer(&pc->timer);	L3AddTimer(&pc->timer, T303, CC_T303);	newl3state(pc, 1);	l3_msg(pc->st, DL_DATA | REQUEST, skb);}static voidl3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	int bcfound = 0;	char tmp[80];	struct sk_buff *skb = arg;	p = skb->data;	/* Channel Identification */	p = skb->data;	if ((p = findie(p, skb->len, WE0_chanID, 0))) {		if (p[1] != 1) {			l3_1tr6_error(pc, "setup wrong chanID len", skb);			return;		}		if ((p[2] & 0xf4) != 0x80) {			l3_1tr6_error(pc, "setup wrong WE0_chanID", skb);			return;		}		if ((pc->para.bchannel = p[2] & 0x3))				bcfound++;	} else {		l3_1tr6_error(pc, "missing setup chanID", skb);		return;	}	p = skb->data;	if ((p = findie(p, skb->len, WE6_serviceInd, 6))) {		pc->para.setup.si1 = p[2];		pc->para.setup.si2 = p[3];	} else {		l3_1tr6_error(pc, "missing setup SI", skb);		return;	}	p = skb->data;	if ((p = findie(p, skb->len, WE0_destAddr, 0)))		iecpy(pc->para.setup.eazmsn, p, 1);	else		pc->para.setup.eazmsn[0] = 0;	p = skb->data;	if ((p = findie(p, skb->len, WE0_origAddr, 0))) {		iecpy(pc->para.setup.phone, p, 1);	} else		pc->para.setup.phone[0] = 0;	p = skb->data;	pc->para.spv = 0;	if ((p = findie(p, skb->len, WE0_netSpecFac, 0))) {		if ((FAC_SPV == p[3]) || (FAC_Activate == p[3]))			pc->para.spv = 1;	}	dev_kfree_skb(skb);	/* Signal all services, linklevel takes care of Service-Indicator */	if (bcfound) {		if ((pc->para.setup.si1 != 7) && (pc->st->l3.debug & L3_DEB_WARN)) {			sprintf(tmp, "non-digital call: %s -> %s",				pc->para.setup.phone,				pc->para.setup.eazmsn);			l3_debug(pc->st, tmp);		}		newl3state(pc, 6);		pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);	} else		release_l3_process(pc);}static voidl3_1tr6_setup_ack(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	L3DelTimer(&pc->timer);	p = skb->data;	newl3state(pc, 2);	if ((p = findie(p, skb->len, WE0_chanID, 0))) {		if (p[1] != 1) {			l3_1tr6_error(pc, "setup_ack wrong chanID len", skb);			return;		}		if ((p[2] & 0xf4) != 0x80) {			l3_1tr6_error(pc, "setup_ack wrong WE0_chanID", skb);			return;		}		pc->para.bchannel = p[2] & 0x3;	} else {		l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb);		return;	}	dev_kfree_skb(skb);	L3AddTimer(&pc->timer, T304, CC_T304);	pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);}static voidl3_1tr6_call_sent(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	L3DelTimer(&pc->timer);	p = skb->data;	if ((p = findie(p, skb->len, WE0_chanID, 0))) {		if (p[1] != 1) {			l3_1tr6_error(pc, "call sent wrong chanID len", skb);			return;		}		if ((p[2] & 0xf4) != 0x80) {			l3_1tr6_error(pc, "call sent wrong WE0_chanID", skb);			return;		}		if ((pc->state == 2) && (pc->para.bchannel != (p[2] & 0x3))) {			l3_1tr6_error(pc, "call sent wrong chanID value", skb);			return;		}		pc->para.bchannel = p[2] & 0x3;	} else {		l3_1tr6_error(pc, "missing call sent WE0_chanID", skb);		return;	}	dev_kfree_skb(skb);	L3AddTimer(&pc->timer, T310, CC_T310);	newl3state(pc, 3);	pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);}static voidl3_1tr6_alert(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	dev_kfree_skb(skb);	L3DelTimer(&pc->timer);	/* T304 */	newl3state(pc, 4);	pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);}static voidl3_1tr6_info(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	int i, tmpcharge = 0;	char a_charge[8], tmp[32];	struct sk_buff *skb = arg;	p = skb->data;	if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {		iecpy(a_charge, p, 1);		for (i = 0; i < strlen(a_charge); i++) {			tmpcharge *= 10;			tmpcharge += a_charge[i] & 0xf;		}		if (tmpcharge > pc->para.chargeinfo) {			pc->para.chargeinfo = tmpcharge;			pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);		}		if (pc->st->l3.debug & L3_DEB_CHARGE) {			sprintf(tmp, "charging info %d", pc->para.chargeinfo);			l3_debug(pc->st, tmp);		}	} else if (pc->st->l3.debug & L3_DEB_CHARGE)		l3_debug(pc->st, "charging info not found");	dev_kfree_skb(skb);}static voidl3_1tr6_info_s2(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	dev_kfree_skb(skb);}static voidl3_1tr6_connect(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	L3DelTimer(&pc->timer);	/* T310 */	if (!findie(skb->data, skb->len, WE6_date, 6)) {		l3_1tr6_error(pc, "missing connect date", skb);		return;	}	newl3state(pc, 10);	dev_kfree_skb(skb);	pc->para.chargeinfo = 0;	pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);}static voidl3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	u_char *p;	p = skb->data;	if ((p = findie(p, skb->len, WE0_cause, 0))) {		if (p[1] > 0) {			pc->para.cause = p[2];			if (p[1] > 1)				pc->para.loc = p[3];			else				pc->para.loc = 0;		} else {			pc->para.cause = 0;			pc->para.loc = 0;		}	} else {		pc->para.cause = NO_CAUSE;		l3_1tr6_error(pc, "missing REL cause", skb);		return;	}	dev_kfree_skb(skb);	StopAllL3Timer(pc);	newl3state(pc, 0);	l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1);	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);	release_l3_process(pc);}static voidl3_1tr6_rel_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	dev_kfree_skb(skb);	StopAllL3Timer(pc);	newl3state(pc, 0);	pc->para.cause = NO_CAUSE;	pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);	release_l3_process(pc);}static voidl3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	u_char *p;	int i, tmpcharge = 0;	char a_charge[8], tmp[32];	StopAllL3Timer(pc);	p = skb->data;	if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {		iecpy(a_charge, p, 1);		for (i = 0; i < strlen(a_charge); i++) {			tmpcharge *= 10;			tmpcharge += a_charge[i] & 0xf;		}		if (tmpcharge > pc->para.chargeinfo) {			pc->para.chargeinfo = tmpcharge;			pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);		}		if (pc->st->l3.debug & L3_DEB_CHARGE) {			sprintf(tmp, "charging info %d", pc->para.chargeinfo);			l3_debug(pc->st, tmp);		}	} else if (pc->st->l3.debug & L3_DEB_CHARGE)		l3_debug(pc->st, "charging info not found");	p = skb->data;	if ((p = findie(p, skb->len, WE0_cause, 0))) {		if (p[1] > 0) {			pc->para.cause = p[2];			if (p[1] > 1)				pc->para.loc = p[3];			else				pc->para.loc = 0;		} else {			pc->para.cause = 0;			pc->para.loc = 0;		}	} else {		if (pc->st->l3.debug & L3_DEB_WARN)			l3_debug(pc->st, "cause not found");		pc->para.cause = NO_CAUSE;	}	if (!findie(skb->data, skb->len, WE6_date, 6)) {		l3_1tr6_error(pc, "missing connack date", skb);		return;	}	dev_kfree_skb(skb);	newl3state(pc, 12);	pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);}static voidl3_1tr6_connect_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	if (!findie(skb->data, skb->len, WE6_date, 6)) {		l3_1tr6_error(pc, "missing connack date", skb);		return;	}	dev_kfree_skb(skb);	newl3state(pc, 10);	pc->para.chargeinfo = 0;	L3DelTimer(&pc->timer);	pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);}static voidl3_1tr6_alert_req(struct l3_process *pc, u_char pr, void *arg){	newl3state(pc, 7);	l3_1TR6_message(pc, MT_N1_ALERT, PROTO_DIS_N1);}static voidl3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg){

⌨️ 快捷键说明

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