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

📄 isdnl2.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct PStack *st = fi->userdata;	if (test_bit(FLG_LAPD, &st->l2.flag) &&		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9);		return;	}	test_and_clear_bit(FLG_T200_RUN, &st->l2.flag);	if (fi->state == ST_L2_7) {		st->l2.rc = 0;		FsmChangeState(fi, ST_L2_8);	}	if (st->l2.rc == st->l2.N200) {		establishlink(fi);	} else {		transmit_enquiry(st);		st->l2.rc++;	}}static voidl2_st7_tout_203(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	if (test_bit(FLG_LAPD, &st->l2.flag) &&		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {		FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 9);		return;	}	FsmChangeState(fi, ST_L2_8);	transmit_enquiry(st);	st->l2.rc = 0;}static voidl2_pull_iqueue(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb, *oskb;	struct Layer2 *l2 = &st->l2;	u_char header[MAX_HEADER_LEN];	int p1, i;	if (!cansend(st))		return;	skb = skb_dequeue(&l2->i_queue);	if (!skb)		return;	p1 = l2->vs - l2->va;	if (p1 < 0)		p1 += test_bit(FLG_MOD128, &l2->flag) ? 128 : 8;	p1 = (p1 + l2->sow) % l2->window;	if (l2->windowar[p1]) {		printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n",		       p1);		dev_kfree_skb(l2->windowar[p1], FREE_WRITE);	}	l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC);	i = sethdraddr(&st->l2, header, CMD);	if (test_bit(FLG_MOD128, &l2->flag)) {		header[i++] = l2->vs << 1;		header[i++] = l2->vr << 1;		l2->vs = (l2->vs + 1) % 128;	} else {		header[i++] = (l2->vr << 5) | (l2->vs << 1);		l2->vs = (l2->vs + 1) % 8;	}	p1 = skb->data - skb->head;	if (p1 >= i)		memcpy(skb_push(skb, i), header, i);	else {		printk(KERN_WARNING		"isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);		oskb = skb;		skb = alloc_skb(oskb->len + i, GFP_ATOMIC);		SET_SKB_FREE(skb);		memcpy(skb_put(skb, i), header, i);		memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len);		FreeSkb(oskb);	}	st->l2.l2l1(st, PH_PULL | INDICATION, skb);	test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);	if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) {		FsmDelTimer(&st->l2.t203, 13);		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 11);	}	if (skb_queue_len(&l2->i_queue) && cansend(st))		st->l2.l2l1(st, PH_PULL | REQUEST, NULL);}static voidl2_got_st8_super(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb = arg;	int PollFlag, nr, rsp, rnr = 0;	struct Layer2 *l2 = &st->l2;	rsp = *skb->data & 0x2;	if (test_bit(FLG_ORIG, &l2->flag))		rsp = !rsp;	skb_pull(skb, l2addrsize(l2));	if (IsRNR(skb->data, test_bit(FLG_MOD128, &l2->flag))) {		test_and_set_bit(FLG_PEER_BUSY, &l2->flag);		rnr = 1;	} else		test_and_clear_bit(FLG_PEER_BUSY, &l2->flag);	if (test_bit(FLG_MOD128, &l2->flag)) {		if (skb->len == 2) {			PollFlag = (skb->data[1] & 0x1) == 0x1;			nr = skb->data[1] >> 1;		} else {			st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');			FreeSkb(skb);			establishlink(fi);			return;		}	} else {		if (skb->len == 1) {			PollFlag = (skb->data[0] & 0x10);			nr = (skb->data[0] >> 5) & 0x7;		} else {			st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');			FreeSkb(skb);			establishlink(fi);			return;		}	}	FreeSkb(skb);	if (rsp && PollFlag) {		if (legalnr(st, nr)) {			setva(st, nr);			if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))				FsmDelTimer(&st->l2.t200, 7);			FsmDelTimer(&l2->t203, 8);			if (rnr) {				FsmRestartTimer(&l2->t200, l2->T200,						EV_L2_T200, NULL, 14);				test_and_set_bit(FLG_T200_RUN, &st->l2.flag);			} else				FsmAddTimer(&l2->t203, l2->T203,					    EV_L2_T203, NULL, 5);			invoke_retransmission(st, nr);			FsmChangeState(fi, ST_L2_7);			if (skb_queue_len(&l2->i_queue) && cansend(st))				st->l2.l2l1(st, PH_PULL | REQUEST, NULL);			else if (fi->userint & LC_FLUSH_WAIT) {				fi->userint &= ~LC_FLUSH_WAIT;				st->l2.l2l3(st, DL_FLUSH | INDICATION, NULL);			}		}	} else {		if (!rsp && PollFlag)			enquiry_response(st);		if (legalnr(st, nr)) {			setva(st, nr);		}	}}static voidl2_got_FRMR(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb = arg;	skb_pull(skb, l2addrsize(&st->l2) + 1);	if (test_bit(FLG_MOD128, &st->l2.flag)) {		if (skb->len < 5)			st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');		else			l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x",				skb->data[0], skb->data[1], skb->data[2],				skb->data[3], skb->data[4]);	} else {		if (skb->len < 3)			st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');		else			l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x",				skb->data[0], skb->data[1], skb->data[2]);	}	if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) ||		/* I or S */	    (IsUA(skb->data, 0) && (fi->state == ST_L2_7))) {		st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'K');		establishlink(fi);		test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);	}	FreeSkb(skb);}static voidl2_tei_remove(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	discard_queue(&st->l2.i_queue);	discard_queue(&st->l2.ui_queue);	st->l2.tei = -1;	if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))		FsmDelTimer(&st->l2.t200, 18);	FsmDelTimer(&st->l2.t203, 19);	if (fi->state != ST_L2_4)		st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);	FsmChangeState(fi, ST_L2_1);}static voidl2_persistant_da(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	int rel = DL_RELEASE | INDICATION;			discard_queue(&st->l2.i_queue);	discard_queue(&st->l2.ui_queue);	if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))		FsmDelTimer(&st->l2.t200, 18);	FsmDelTimer(&st->l2.t203, 19);	clear_exception(&st->l2);	switch (fi->state) {		case ST_L2_1:			if (!test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))				break;		case ST_L2_3:			st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);		case ST_L2_2:			FsmChangeState(fi, ST_L2_1);			break;		case ST_L2_6:			rel = DL_RELEASE | CONFIRM;		case ST_L2_5:			if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag))				rel = DL_RELEASE | CONFIRM;		case ST_L2_7:		case ST_L2_8:			st->l2.l2l3(st, rel, NULL);			FsmChangeState(fi, ST_L2_4);			break;		case ST_L2_4:			if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))				st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);			break;	}	test_and_clear_bit(FLG_PEND_REL, &st->l2.flag);	test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag);}static struct FsmNode L2FnList[] HISAX_INITDATA ={	{ST_L2_1, EV_L2_DL_ESTABLISH, l2_dl_establish},	{ST_L2_2, EV_L2_DL_ESTABLISH, l2_dl_establish},	{ST_L2_4, EV_L2_DL_ESTABLISH, l2_establish},	{ST_L2_5, EV_L2_DL_ESTABLISH, l2_establish},	{ST_L2_7, EV_L2_DL_ESTABLISH, l2_establish},	{ST_L2_8, EV_L2_DL_ESTABLISH, l2_establish},	{ST_L2_4, EV_L2_DL_RELEASE, l2_dl_release},	{ST_L2_5, EV_L2_DL_RELEASE, l2_dl_release},	{ST_L2_7, EV_L2_DL_RELEASE, l2_dl_release},	{ST_L2_8, EV_L2_DL_RELEASE, l2_dl_release},	{ST_L2_5, EV_L2_DL_DATA, l2_feed_iqueue},	{ST_L2_7, EV_L2_DL_DATA, l2_feed_iqueue},	{ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},	{ST_L2_1, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_2, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_3, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_4, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_5, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_6, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_7, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_8, EV_L2_DL_UNIT_DATA, l2_put_ui},	{ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei},	{ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei},	{ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei},	{ST_L2_2, EV_L2_MDL_ERROR, l2_tei_remove},	{ST_L2_3, EV_L2_MDL_ERROR, l2_tei_remove},	{ST_L2_4, EV_L2_MDL_REMOVE, l2_tei_remove},	{ST_L2_5, EV_L2_MDL_REMOVE, l2_tei_remove},	{ST_L2_6, EV_L2_MDL_REMOVE, l2_tei_remove},	{ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove},	{ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove},	{ST_L2_4, EV_L2_SABMX, l2_got_SABMX},	{ST_L2_5, EV_L2_SABMX, l2_got_SABMX},	{ST_L2_6, EV_L2_SABMX, l2_got_SABMX},	{ST_L2_7, EV_L2_SABMX, l2_got_SABMX},	{ST_L2_8, EV_L2_SABMX, l2_got_SABMX},	{ST_L2_4, EV_L2_DISC, l2_got_disconn},	{ST_L2_5, EV_L2_DISC, l2_got_disconn},	{ST_L2_6, EV_L2_DISC, l2_got_disconn},	{ST_L2_7, EV_L2_DISC, l2_got_disconn},	{ST_L2_8, EV_L2_DISC, l2_got_disconn},	{ST_L2_4, EV_L2_UA, l2_mdl_error},	{ST_L2_5, EV_L2_UA, l2_got_ua},	{ST_L2_6, EV_L2_UA, l2_got_ua},	{ST_L2_7, EV_L2_UA, l2_mdl_error},	{ST_L2_8, EV_L2_UA, l2_mdl_error},	{ST_L2_4, EV_L2_DM, l2_got_dm},	{ST_L2_5, EV_L2_DM, l2_got_dm},	{ST_L2_6, EV_L2_DM, l2_got_dm},	{ST_L2_7, EV_L2_DM, l2_got_dm},	{ST_L2_8, EV_L2_DM, l2_got_dm},	{ST_L2_1, EV_L2_UI, l2_got_ui},	{ST_L2_2, EV_L2_UI, l2_got_ui},	{ST_L2_3, EV_L2_UI, l2_got_ui},	{ST_L2_4, EV_L2_UI, l2_got_ui},	{ST_L2_5, EV_L2_UI, l2_got_ui},	{ST_L2_6, EV_L2_UI, l2_got_ui},	{ST_L2_7, EV_L2_UI, l2_got_ui},	{ST_L2_8, EV_L2_UI, l2_got_ui},	{ST_L2_7, EV_L2_FRMR, l2_got_FRMR},	{ST_L2_8, EV_L2_FRMR, l2_got_FRMR},	{ST_L2_7, EV_L2_SUPER, l2_got_st7_super},	{ST_L2_8, EV_L2_SUPER, l2_got_st8_super},	{ST_L2_7, EV_L2_I, l2_got_iframe},	{ST_L2_8, EV_L2_I, l2_got_iframe},	{ST_L2_5, EV_L2_T200, l2_st5_tout_200},	{ST_L2_6, EV_L2_T200, l2_st6_tout_200},	{ST_L2_7, EV_L2_T200, l2_st78_tout_200},	{ST_L2_8, EV_L2_T200, l2_st78_tout_200},	{ST_L2_7, EV_L2_T203, l2_st7_tout_203},	{ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},	{ST_L2_1, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_2, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_3, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_4, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_5, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_6, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da},	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},};#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))static voidisdnl2_l1l2(struct PStack *st, int pr, void *arg){	struct sk_buff *skb = arg;	u_char *datap;	int ret = 1, len;	switch (pr) {		case (PH_DATA | INDICATION):			datap = skb->data;			len = l2addrsize(&st->l2);			if (skb->len > len)				datap += len;			else {				st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');				FreeSkb(skb);				return;			}			if (!(*datap & 1))	/* I-Frame */				ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb);			else if (IsSFrame(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb);			else if (IsUI(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb);			else if (IsSABMX(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_SABMX, skb);			else if (IsUA(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb);			else if (IsDISC(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb);			else if (IsDM(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb);			else if (IsFRMR(datap, test_bit(FLG_MOD128, &st->l2.flag)))				ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);			else {				ret = 1;				if ((st->l2.l2m.state == ST_L2_7) ||					(st->l2.l2m.state == ST_L2_8))					establishlink(&st->l2.l2m);				st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L');			}			if (ret) {				FreeSkb(skb);			}			break;		case (PH_PULL | CONFIRM):			FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);			break;		case (PH_PAUSE | INDICATION):			test_and_set_bit(FLG_DCHAN_BUSY, &st->l2.flag);			break;		case (PH_PAUSE | CONFIRM):			test_and_clear_bit(FLG_DCHAN_BUSY, &st->l2.flag);			break;		case (PH_ACTIVATE | CONFIRM):		case (PH_ACTIVATE | INDICATION):			test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag);			if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))				FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg);			break;		case (PH_DEACTIVATE | INDICATION):		case (PH_DEACTIVATE | CONFIRM):			test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag);			FsmEvent(&st->l2.l2m, EV_L1_DEACTIVATE, arg);			break;		default:			l2m_debug(&st->l2.l2m, "l2 unknown pr %04x", pr);			break;	}}static voidisdnl2_l3l2(struct PStack *st, int pr, void *arg){	switch (pr) {		case (DL_DATA | REQUEST):			if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) {				dev_kfree_skb((struct sk_buff *) arg, FREE_READ);			}			break;		case (DL_UNIT_DATA | REQUEST):			if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) {				dev_kfree_skb((struct sk_buff *) arg, FREE_READ);			}			break;		case (DL_ESTABLISH | REQUEST):			if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) {				if (test_bit(FLG_LAPD, &st->l2.flag) ||					test_bit(FLG_ORIG, &st->l2.flag)) {					FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg);				}			} else {				if (test_bit(FLG_LAPD, &st->l2.flag) ||					test_bit(FLG_ORIG, &st->l2.flag)) {					test_and_set_bit(FLG_ESTAB_PEND, &st->l2.flag);				}				st->l2.l2l1(st, PH_ACTIVATE, NULL);			}			break;		case (DL_RELEASE | REQUEST):			if (test_bit(FLG_LAPB, &st->l2.flag)) {				st->l2.l2l1(st, PH_DEACTIVATE, NULL);			}			FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE, arg);			break;		case (DL_FLUSH | REQUEST):			(&st->l2.l2m)->userint |= LC_FLUSH_WAIT;			break;		case (MDL_ASSIGN | REQUEST):			FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg);			break;		case (MDL_REMOVE | REQUEST):			FsmEvent(&st->l2.l2m, EV_L2_MDL_REMOVE, arg);			break;		case (MDL_ERROR | RESPONSE):			FsmEvent(&st->l2.l2m, EV_L2_MDL_ERROR, arg);			break;	}}voidreleasestack_isdnl2(struct PStack *st){	FsmDelTimer(&st->l2.t200, 15);	FsmDelTimer(&st->l2.t203, 16);	discard_queue(&st->l2.i_queue);	discard_queue(&st->l2.ui_queue);	ReleaseWin(&st->l2);}static voidl2m_debug(struct FsmInst *fi, char *fmt, ...){	va_list args;	struct PStack *st = fi->userdata;	va_start(args, fmt);	VHiSax_putstatus(st->l1.hardware, st->l2.debug_id, fmt, args);	va_end(args);}voidsetstack_isdnl2(struct PStack *st, char *debug_id){	st->l1.l1l2 = isdnl2_l1l2;	st->l3.l3l2 = isdnl2_l3l2;	skb_queue_head_init(&st->l2.i_queue);	skb_queue_head_init(&st->l2.ui_queue);	InitWin(&st->l2);	st->l2.debug = 0;	st->l2.l2m.fsm = &l2fsm;	if (test_bit(FLG_LAPB, &st->l2.flag))		st->l2.l2m.state = ST_L2_4;	else	st->l2.l2m.state = ST_L2_1;	st->l2.l2m.debug = 0;	st->l2.l2m.userdata = st;	st->l2.l2m.userint = 0;	st->l2.l2m.printdebug = l2m_debug;	strcpy(st->l2.debug_id, debug_id);	FsmInitTimer(&st->l2.l2m, &st->l2.t200);	FsmInitTimer(&st->l2.l2m, &st->l2.t203);}static voidtransl2_l3l2(struct PStack *st, int pr, void *arg){	switch (pr) {		case (DL_DATA | REQUEST):		case (DL_UNIT_DATA | REQUEST):			st->l2.l2l1(st, PH_DATA | REQUEST, arg);			break;		case (DL_ESTABLISH | REQUEST):			st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);			break;		case (DL_RELEASE | REQUEST):			st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);			break;	}}voidsetstack_transl2(struct PStack *st){	st->l3.l3l2 = transl2_l3l2;}voidreleasestack_transl2(struct PStack *st){}HISAX_INITFUNC(voidIsdnl2New(void)){	l2fsm.state_count = L2_STATE_COUNT;	l2fsm.event_count = L2_EVENT_COUNT;	l2fsm.strEvent = strL2Event;	l2fsm.strState = strL2State;	FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);}voidIsdnl2Free(void){	FsmFree(&l2fsm);}

⌨️ 快捷键说明

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