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

📄 isdnl2.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: isdnl2.c,v 1.1.1.1 1999/11/15 13:42:18 vadim Exp $ * Author       Karsten Keil (keil@temic-ech.spacenet.de) *              based on the teles driver from Jan den Ouden * *		This file is (c) under GNU PUBLIC LICENSE *		For changes and modifications please read *		../../../Documentation/isdn/HiSax.cert * * Thanks to    Jan den Ouden *              Fritz Elfert * * $Log: isdnl2.c,v $ * Revision 1.1.1.1  1999/11/15 13:42:18  vadim * Initial import * * Revision 1.10.2.11  1998/11/03 00:06:57  keil * certification related changes * fixed logging for smaller stack use * * Revision 1.10.2.10  1998/09/27 13:06:30  keil * Apply most changes from 2.1.X (HiSax 3.1) * * Revision 1.10.2.9  1998/06/19 15:17:56  keil * fix LAPB tx_cnt for none I-frames * * Revision 1.10.2.8  1998/06/18 23:12:05  keil * LAPB bugfix * * Revision 1.10.2.7  1998/05/27 18:05:51  keil * HiSax 3.0 * * Revision 1.10.2.6  1998/05/26 10:36:57  keil * fixes from certification * * Revision 1.10.2.5  1998/03/07 23:15:31  tsbogend * made HiSax working on Linux/Alpha * * Revision 1.10.2.4  1998/01/27 22:44:38  keil * fixed window size calculation * * Revision 1.10.2.3  1997/11/15 18:54:03  keil * cosmetics * * Revision 1.10.2.2  1997/10/17 22:13:59  keil * update to last hisax version * * Revision 2.2  1997/07/31 11:49:05  keil * Eroor handling for no TEI assign * * Revision 2.1  1997/07/27 21:34:38  keil * cosmetics * * Revision 2.0  1997/06/26 11:07:29  keil * New q.921 and X.75 Layer2 * * *  Old log removed KKe * */#define __NO_VERSION__#include "hisax.h"#include "isdnl2.h"const char *l2_revision = "$Revision: 1.1.1.1 $";static void l2m_debug(struct FsmInst *fi, char *fmt, ...);staticstruct Fsm l2fsm ={NULL, 0, 0, NULL, NULL};enum {	ST_L2_1,	ST_L2_2,	ST_L2_3,	ST_L2_4,	ST_L2_5,	ST_L2_6,	ST_L2_7,	ST_L2_8,};#define L2_STATE_COUNT (ST_L2_8+1)static char *strL2State[] ={	"ST_L2_1",	"ST_L2_2",	"ST_L2_3",	"ST_L2_4",	"ST_L2_5",	"ST_L2_6",	"ST_L2_7",	"ST_L2_8",};enum {	EV_L2_UI,	EV_L2_SABMX,	EV_L2_DISC,	EV_L2_DM,	EV_L2_UA,	EV_L2_FRMR,	EV_L2_SUPER,	EV_L2_I,	EV_L2_DL_DATA,	EV_L2_ACK_PULL,	EV_L2_DL_UNIT_DATA,	EV_L2_DL_ESTABLISH,	EV_L2_DL_RELEASE,	EV_L2_MDL_ASSIGN,	EV_L2_MDL_REMOVE,	EV_L2_MDL_ERROR,	EV_L1_DEACTIVATE,	EV_L2_T200,	EV_L2_T203,};#define L2_EVENT_COUNT (EV_L2_T203+1)static char *strL2Event[] ={	"EV_L2_UI",	"EV_L2_SABMX",	"EV_L2_DISC",	"EV_L2_DM",	"EV_L2_UA",	"EV_L2_FRMR",	"EV_L2_SUPER",	"EV_L2_I",	"EV_L2_DL_DATA",	"EV_L2_ACK_PULL",	"EV_L2_DL_UNIT_DATA",	"EV_L2_DL_ESTABLISH",	"EV_L2_DL_RELEASE",	"EV_L2_MDL_ASSIGN",	"EV_L2_MDL_REMOVE",	"EV_L2_MDL_ERROR",	"EV_L1_DEACTIVATE",	"EV_L2_T200",	"EV_L2_T203",};static int l2addrsize(struct Layer2 *l2);static voidInitWin(struct Layer2 *l2){	int i;	for (i = 0; i < MAX_WINDOW; i++)		l2->windowar[i] = NULL;}static voidReleaseWin(struct Layer2 *l2){	int i, cnt = 0;	for (i = 0; i < MAX_WINDOW; i++) {		if (l2->windowar[i]) {			cnt++;			dev_kfree_skb(l2->windowar[i], FREE_WRITE);			l2->windowar[i] = NULL;		}	}	if (cnt)		printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt);}inline intcansend(struct PStack *st){	int p1;	p1 = st->l2.vs - st->l2.va;	if (p1 < 0)		p1 += (test_bit(FLG_MOD128, &st->l2.flag) ? 128 : 8);	return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag));}inline voidclear_exception(struct Layer2 *l2){	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);	test_and_clear_bit(FLG_REJEXC, &l2->flag);	test_and_clear_bit(FLG_OWN_BUSY, &l2->flag);	test_and_clear_bit(FLG_PEER_BUSY, &l2->flag);}inline intl2headersize(struct Layer2 *l2, int ui){	return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +		(test_bit(FLG_LAPD, &l2->flag) ? 2 : 1));}inline intl2addrsize(struct Layer2 *l2){	return (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1);}static intsethdraddr(struct Layer2 *l2, u_char * header, int rsp){	u_char *ptr = header;	int crbit = rsp;	if (test_bit(FLG_LAPD, &l2->flag)) {		*ptr++ = (l2->sap << 2) | (rsp ? 2 : 0);		*ptr++ = (l2->tei << 1) | 1;		return (2);	} else {		if (test_bit(FLG_ORIG, &l2->flag))			crbit = !crbit;		if (crbit)			*ptr++ = 1;		else			*ptr++ = 3;		return (1);	}}inline static voidenqueue_super(struct PStack *st,	      struct sk_buff *skb){	if (test_bit(FLG_LAPB, &st->l2.flag))		st->l1.bcs->tx_cnt += skb->len;	st->l2.l2l1(st, PH_DATA | REQUEST, skb);}#define enqueue_ui(a, b) enqueue_super(a, b)inline intIsUI(u_char * data, int ext){	return ((data[0] & 0xef) == UI);}inline intIsUA(u_char * data, int ext){	return ((data[0] & 0xef) == UA);}inline intIsDM(u_char * data, int ext){	return ((data[0] & 0xef) == DM);}inline intIsDISC(u_char * data, int ext){	return ((data[0] & 0xef) == DISC);}inline intIsRR(u_char * data, int ext){	if (ext)		return (data[0] == RR);	else		return ((data[0] & 0xf) == 1);}inline intIsSFrame(u_char * data, int ext){	register u_char d = *data;		if (!ext)		d &= 0xf;	return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));}inline intIsSABMX(u_char * data, int ext){	u_char d = data[0] & ~0x10;	return (ext ? d == SABME : d == SABM);}inline intIsREJ(u_char * data, int ext){	return (ext ? data[0] == REJ : (data[0] & 0xf) == REJ);}inline intIsFRMR(u_char * data, int ext){	return ((data[0] & 0xef) == FRMR);}inline intIsRNR(u_char * data, int ext){	return (ext ? data[0] == RNR : (data[0] & 0xf) == RNR);}static intlegalnr(struct PStack *st, int nr){	struct Layer2 *l2 = &st->l2;	int lnr, lvs;	lvs = (l2->vs >= l2->va) ? l2->vs :	    (l2->vs + (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8));	lnr = (nr >= l2->va) ? nr : (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8);	return (lnr <= lvs);}static voidsetva(struct PStack *st, int nr){	struct Layer2 *l2 = &st->l2;	int len;	while (l2->va != nr) {		l2->va = (l2->va + 1) % (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8);		len = l2->windowar[l2->sow]->len;		if (PACKET_NOACK == l2->windowar[l2->sow]->pkt_type)			len = -1;		dev_kfree_skb(l2->windowar[l2->sow], FREE_WRITE);		l2->windowar[l2->sow] = NULL;		l2->sow = (l2->sow + 1) % l2->window;		if (st->lli.l2writewakeup && (len >=0))			st->lli.l2writewakeup(st, len);	}}static voidsend_uframe(struct PStack *st, u_char cmd, u_char cr){	struct sk_buff *skb;	u_char tmp[MAX_HEADER_LEN];	int i;	i = sethdraddr(&st->l2, tmp, cr);	tmp[i++] = cmd;	if (!(skb = alloc_skb(i, GFP_ATOMIC))) {		printk(KERN_WARNING "isdl2 can't alloc sbbuff for send_uframe\n");		return;	}	SET_SKB_FREE(skb);	memcpy(skb_put(skb, i), tmp, i);	enqueue_super(st, skb);}inline u_charget_PollFlag(struct PStack * st, struct sk_buff * skb){	return (skb->data[l2addrsize(&(st->l2))] & 0x10);}inline voidFreeSkb(struct sk_buff *skb){	dev_kfree_skb(skb, FREE_READ);}inline u_charget_PollFlagFree(struct PStack *st, struct sk_buff *skb){	u_char PF;	PF = get_PollFlag(st, skb);	FreeSkb(skb);	return (PF);}static voidestablishlink(struct FsmInst *fi){	struct PStack *st = fi->userdata;	u_char cmd;	clear_exception(&st->l2);	st->l2.rc = 0;	cmd = (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) | 0x10;	send_uframe(st, cmd, CMD);	FsmDelTimer(&st->l2.t203, 1);	FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 1);	test_and_set_bit(FLG_T200_RUN, &st->l2.flag);	FsmChangeState(fi, ST_L2_5);}static voidl2_mdl_error(struct FsmInst *fi, int event, void *arg){	struct sk_buff *skb = arg;	struct PStack *st = fi->userdata;	switch (event) {		case EV_L2_UA:			if (get_PollFlagFree(st, skb))				st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'C');			else				st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'D');			break;		case EV_L2_DM:			if (get_PollFlagFree(st, skb))				st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B');			else {				st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E');				establishlink(fi);				test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);			}			break;	}}static voidl2_dl_establish(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	int state = fi->state;		if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {		FsmChangeState(fi, ST_L2_4);		establishlink(fi);		test_and_set_bit(FLG_L3_INIT, &st->l2.flag);	} else {		FsmChangeState(fi, ST_L2_3);		if (state == ST_L2_1)			st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL);	}}static voidl2_send_ui(struct PStack *st){	struct sk_buff *skb;	u_char header[MAX_HEADER_LEN];	int i;	i = sethdraddr(&(st->l2), header, CMD);	header[i++] = UI;	while ((skb = skb_dequeue(&st->l2.ui_queue))) {		memcpy(skb_push(skb, i), header, i);		enqueue_ui(st, skb);	}}static voidl2_put_ui(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb = arg;	skb_queue_tail(&st->l2.ui_queue, skb);	if (fi->state == ST_L2_1) {		FsmChangeState(fi, ST_L2_2);		st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL);	}	if (fi->state > ST_L2_3)		l2_send_ui(st);}static voidl2_got_ui(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb = arg;	skb_pull(skb, l2headersize(&st->l2, 1));	if (skb->len > st->l2.maxlen) { 		st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O');		FreeSkb(skb);	} else		st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb);}static voidl2_establish(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	if (fi->state != ST_L2_4)		discard_queue(&st->l2.i_queue);	if (fi->state != ST_L2_5)		establishlink(fi);	test_and_set_bit(FLG_L3_INIT, &st->l2.flag);}static voidl2_dl_release(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	if (fi->state == ST_L2_4) {		st->l2.l2l3(st, DL_RELEASE  | CONFIRM, NULL);		return;	} else if (fi->state == ST_L2_5) {		test_and_set_bit(FLG_PEND_REL, &st->l2.flag);		return;	}	discard_queue(&st->l2.i_queue);	FsmChangeState(fi, ST_L2_6);	st->l2.rc = 0;	send_uframe(st, DISC | 0x10, CMD);	FsmDelTimer(&st->l2.t203, 1);	FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 2);	test_and_set_bit(FLG_T200_RUN, &st->l2.flag);}static voidl2_got_SABMX(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb = arg;	int est = 1, state, rsp;	u_char PollFlag;	state = fi->state;	rsp = *skb->data & 0x2;	if (test_bit(FLG_ORIG, &st->l2.flag))		rsp = !rsp;	if (rsp) {		st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L');		FreeSkb(skb);		if ((state == ST_L2_7) || (state == ST_L2_8))			establishlink(fi);		return;	}		if (skb->len != (l2addrsize(&st->l2) + 1)) {		st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');		FreeSkb(skb);		if ((state == ST_L2_7) || (state == ST_L2_8))			establishlink(fi);		return;	}	PollFlag = get_PollFlagFree(st, skb);	if (ST_L2_6 == state) {		send_uframe(st, DM | PollFlag, RSP);		return;	} else		send_uframe(st, UA | PollFlag, RSP);	if (ST_L2_5 == state)		return;	if (ST_L2_4 != state) {		st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F');		if (st->l2.vs != st->l2.va) {

⌨️ 快捷键说明

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