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

📄 isdnl2.c

📁 linux-2.6.15.6
💻 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.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 i;	int unsigned p1;	u_long flags;	if (!cansend(st))		return;	skb = skb_dequeue(&l2->i_queue);	if (!skb)		return;	spin_lock_irqsave(&l2->lock, flags);	if(test_bit(FLG_MOD128, &l2->flag))		p1 = (l2->vs - l2->va) % 128;	else		p1 = (l2->vs - l2->va) % 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]);	}	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;	}	spin_unlock_irqrestore(&l2->lock, flags);	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);		memcpy(skb_put(skb, i), header, i);		memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len);		dev_kfree_skb(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_empty(&l2->i_queue) && cansend(st))		st->l2.l2l1(st, PH_PULL | REQUEST, NULL);}static voidl2_st8_got_super(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	struct sk_buff *skb = arg;	int PollFlag, rsp, rnr = 0;	unsigned int nr;	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, st)) {		set_peer_busy(l2);		rnr = 1;	} else		clear_peer_busy(l2);	if (test_bit(FLG_MOD128, &l2->flag)) {		PollFlag = (skb->data[1] & 0x1) == 0x1;		nr = skb->data[1] >> 1;	} else {		PollFlag = (skb->data[0] & 0x10);		nr = (skb->data[0] >> 5) & 0x7;	}	dev_kfree_skb(skb);	if (rsp && PollFlag) {		if (legalnr(st, nr)) {			if (rnr) {				restart_t200(st, 15);			} else {				stop_t200(st, 16);				FsmAddTimer(&l2->t203, l2->T203,					    EV_L2_T203, NULL, 5);				setva(st, nr);			}			invoke_retransmission(st, nr);			FsmChangeState(fi, ST_L2_7);			if (!skb_queue_empty(&l2->i_queue) && cansend(st))				st->l2.l2l1(st, PH_PULL | REQUEST, NULL);		} else			nrerrorrecovery(fi);	} else {		if (!rsp && PollFlag)			enquiry_response(st);		if (legalnr(st, nr)) {			setva(st, nr);		} else			nrerrorrecovery(fi);	}}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 (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) ||		/* I or S */	    (IsUA(skb->data) && (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);	}	dev_kfree_skb(skb);}static voidl2_st24_tei_remove(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.ui_queue);	st->l2.tei = -1;	FsmChangeState(fi, ST_L2_1);}static voidl2_st3_tei_remove(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.ui_queue);	st->l2.tei = -1;	st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);	FsmChangeState(fi, ST_L2_1);}static voidl2_st5_tei_remove(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.i_queue);	skb_queue_purge(&st->l2.ui_queue);	freewin(st);	st->l2.tei = -1;	stop_t200(st, 17);	st5_dl_release_l2l3(st);	FsmChangeState(fi, ST_L2_1);}static voidl2_st6_tei_remove(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.ui_queue);	st->l2.tei = -1;	stop_t200(st, 18);	st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL);	FsmChangeState(fi, ST_L2_1);}static voidl2_tei_remove(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.i_queue);	skb_queue_purge(&st->l2.ui_queue);	freewin(st);	st->l2.tei = -1;	stop_t200(st, 17);	FsmDelTimer(&st->l2.t203, 19);	st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);	FsmChangeState(fi, ST_L2_1);}static voidl2_st14_persistant_da(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;		skb_queue_purge(&st->l2.i_queue);	skb_queue_purge(&st->l2.ui_queue);	if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))		st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);}static voidl2_st5_persistant_da(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.i_queue);	skb_queue_purge(&st->l2.ui_queue);	freewin(st);	stop_t200(st, 19);	st5_dl_release_l2l3(st);	FsmChangeState(fi, ST_L2_4);}static voidl2_st6_persistant_da(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.ui_queue);	stop_t200(st, 20);	st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL);	FsmChangeState(fi, ST_L2_4);}static voidl2_persistant_da(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	skb_queue_purge(&st->l2.i_queue);	skb_queue_purge(&st->l2.ui_queue);	freewin(st);	stop_t200(st, 19);	FsmDelTimer(&st->l2.t203, 19);	st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);	FsmChangeState(fi, ST_L2_4);}static voidl2_set_own_busy(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	if(!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) {		enquiry_cr(st, RNR, RSP, 0);		test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);	}}static voidl2_clear_own_busy(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	if(!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) {		enquiry_cr(st, RR, RSP, 0);		test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);	}}static voidl2_frame_error(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	st->ma.layer(st, MDL_ERROR | INDICATION, arg);}static voidl2_frame_error_reest(struct FsmInst *fi, int event, void *arg){	struct PStack *st = fi->userdata;	st->ma.layer(st, MDL_ERROR | INDICATION, arg);	establishlink(fi);	test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);}static struct FsmNode L2FnList[] __initdata ={	{ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign},	{ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3},	{ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish},	{ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3},	{ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},	{ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},	{ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release},	{ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel},	{ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect},	{ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect},	{ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest},	{ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull},	{ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},	{ST_L2_1, EV_L2_DL_UNIT_DATA, l2_queue_ui_assign},	{ST_L2_2, EV_L2_DL_UNIT_DATA, l2_queue_ui},	{ST_L2_3, EV_L2_DL_UNIT_DATA, l2_queue_ui},	{ST_L2_4, EV_L2_DL_UNIT_DATA, l2_send_ui},	{ST_L2_5, EV_L2_DL_UNIT_DATA, l2_send_ui},	{ST_L2_6, EV_L2_DL_UNIT_DATA, l2_send_ui},	{ST_L2_7, EV_L2_DL_UNIT_DATA, l2_send_ui},	{ST_L2_8, EV_L2_DL_UNIT_DATA, l2_send_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_st24_tei_remove},	{ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove},	{ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove},	{ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove},	{ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_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_SABME, l2_start_multi},	{ST_L2_5, EV_L2_SABME, l2_send_UA},	{ST_L2_6, EV_L2_SABME, l2_send_DM},	{ST_L2_7, EV_L2_SABME, l2_restart_multi},	{ST_L2_8, EV_L2_SABME, l2_restart_multi},	{ST_L2_4, EV_L2_DISC, l2_send_DM},	{ST_L2_5, EV_L2_DISC, l2_send_DM},	{ST_L2_6, EV_L2_DISC, l2_send_UA},	{ST_L2_7, EV_L2_DISC, l2_stop_multi},	{ST_L2_8, EV_L2_DISC, l2_stop_multi},	{ST_L2_4, EV_L2_UA, l2_mdl_error_ua},	{ST_L2_5, EV_L2_UA, l2_connected},	{ST_L2_6, EV_L2_UA, l2_released},	{ST_L2_7, EV_L2_UA, l2_mdl_error_ua},	{ST_L2_8, EV_L2_UA, l2_mdl_error_ua},	{ST_L2_4, EV_L2_DM, l2_reestablish},	{ST_L2_5, EV_L2_DM, l2_st5_dm_release},	{ST_L2_6, EV_L2_DM, l2_st6_dm_release},	{ST_L2_7, EV_L2_DM, l2_mdl_error_dm},	{ST_L2_8, EV_L2_DM, l2_st8_mdl_error_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_st7_got_super},	{ST_L2_8, EV_L2_SUPER, l2_st8_got_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_st7_tout_200},	{ST_L2_8, EV_L2_T200, l2_st8_tout_200},	{ST_L2_7, EV_L2_T203, l2_st7_tout_203},	{ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},	{ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy},	{ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy},	{ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},	{ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},	{ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error},	{ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error},	{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},	{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},	{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da},	{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},	{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da},	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da},	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_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;	int c = 0;	switch (pr) {		case (PH_DATA | INDICATION):			datap = skb->data;			len = l2addrsize(&st->l2);			if (skb->len > len)				datap += len;			else {				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N');				dev_kfree_skb(skb);				return;			}			if (!(*datap & 1)) {	/* I-Frame */				if(!(c = iframe_error(st, skb)))					ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb);			} else if (IsSFrame(datap, st)) {	/* S-Frame */				if(!(c = super_error(st, skb)))					ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb);			} else if (IsUI(datap)) {				if(!(c = UI_error(st, skb)))					ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb);			} else if (IsSABME(datap, st)) {				if(!(c = unnum_error(st, skb, CMD)))					ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb);			} else if (IsUA(datap)) {				if(!(c = unnum_error(st, skb, RSP)))					ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb);			} else if (IsDISC(datap)) {				if(!(c = unnum_error(st, skb, CMD)))					ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb);			} else if (IsDM(datap)) {				if(!(c = unnum_error(st, skb, RSP)))					ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb);			} else if (IsFRMR(datap)) {				if(!(c = FRMR_error(st,skb)))					ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);			} else {				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L');				dev_kfree_skb(skb);				ret = 0;			}			if(c) {				dev_kfree_skb(skb);				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c);				ret = 0;			}			if (ret)				dev_kfree_skb(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_REQ, 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);			}			break;		case (DL_UNIT_DATA | REQUEST):			if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) {				dev_kfree_skb((struct sk_buff *) arg);			}			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_REQ, 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_REQ, arg);			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, 21);	FsmDelTimer(&st->l2.t203, 16);	skb_queue_purge(&st->l2.i_queue);	skb_queue_purge(&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){	spin_lock_init(&st->l2.lock);	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){}int __initIsdnl2New(void){	l2fsm.state_count = L2_STATE_COUNT;	l2fsm.event_count = L2_EVENT_COUNT;	l2fsm.strEvent = strL2Event;	l2fsm.strState = strL2State;	return FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);}voidIsdnl2Free(void){	FsmFree(&l2fsm);}

⌨️ 快捷键说明

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