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

📄 fsm.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** fsm.c - Network Control Protocol Finite State Machine program file.** Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.* portions Copyright (c) 1997 by Global Election Systems Inc.** The authors hereby grant permission to use, copy, modify, distribute,* and license this software and its documentation for any purpose, provided* that existing copyright notices are retained in all copies and that this* notice and the following disclaimer are included verbatim in any * distributions. No written agreement, license, or royalty fee is required* for any of the authorized uses.** THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.******************************************************************************** REVISION HISTORY** 03-01-01 Marc Boucher <marc@mbsi.ca>*   Ported to lwIP.* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.*	Original based on BSD fsm.c.*****************************************************************************//* * fsm.c - {Link, IP} Control Protocol Finite State Machine. * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. *//* * TODO: * Randomize fsm id on link/init. * Deal with variable outgoing MTU. */#include "ppp.h"#if PPP_SUPPORT > 0#include "fsm.h"#include "pppdebug.h"/*************************//*** LOCAL DEFINITIONS ***//*************************//************************//*** LOCAL DATA TYPES ***//************************//***********************************//*** LOCAL FUNCTION DECLARATIONS ***//***********************************/static void fsm_timeout (void *);static void fsm_rconfreq (fsm *, u_char, u_char *, int);static void fsm_rconfack (fsm *, int, u_char *, int);static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);static void fsm_rtermreq (fsm *, int, u_char *, int);static void fsm_rtermack (fsm *);static void fsm_rcoderej (fsm *, u_char *, int);static void fsm_sconfreq (fsm *, int);#define PROTO_NAME(f)	((f)->callbacks->proto_name)/******************************//*** PUBLIC DATA STRUCTURES ***//******************************//*****************************//*** LOCAL DATA STRUCTURES ***//*****************************/int peer_mru[NUM_PPP];/***********************************//*** PUBLIC FUNCTION DEFINITIONS ***//***********************************//* * fsm_init - Initialize fsm. * * Initialize fsm state. */void fsm_init(fsm *f){	f->state = INITIAL;	f->flags = 0;	f->id = 0;				/* XXX Start with random id? */	f->timeouttime = FSM_DEFTIMEOUT;	f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;	f->maxtermtransmits = FSM_DEFMAXTERMREQS;	f->maxnakloops = FSM_DEFMAXNAKLOOPS;	f->term_reason_len = 0;}/* * fsm_lowerup - The lower layer is up. */void fsm_lowerup(fsm *f){	int oldState = f->state;	switch( f->state ){	case INITIAL:		f->state = CLOSED;		break;		case STARTING:		if( f->flags & OPT_SILENT )			f->state = STOPPED;		else {			/* Send an initial configure-request */			fsm_sconfreq(f, 0);			f->state = REQSENT;		}	break;		default:		FSMDEBUG((LOG_INFO, "%s: Up event in state %d!\n",				PROTO_NAME(f), f->state));	}		FSMDEBUG((LOG_INFO, "%s: lowerup state %d -> %d\n",			PROTO_NAME(f), oldState, f->state));}/* * fsm_lowerdown - The lower layer is down. * * Cancel all timeouts and inform upper layers. */void fsm_lowerdown(fsm *f){	int oldState = f->state;		switch( f->state ){	case CLOSED:		f->state = INITIAL;		break;		case STOPPED:		f->state = STARTING;		if( f->callbacks->starting )			(*f->callbacks->starting)(f);		break;		case CLOSING:		f->state = INITIAL;		UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */		break;		case STOPPING:	case REQSENT:	case ACKRCVD:	case ACKSENT:		f->state = STARTING;		UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */		break;		case OPENED:		if( f->callbacks->down )			(*f->callbacks->down)(f);		f->state = STARTING;		break;		default:		FSMDEBUG((LOG_INFO, "%s: Down event in state %d!\n",				PROTO_NAME(f), f->state));	}		FSMDEBUG((LOG_INFO, "%s: lowerdown state %d -> %d\n",			PROTO_NAME(f), oldState, f->state));}/* * fsm_open - Link is allowed to come up. */void fsm_open(fsm *f){	int oldState = f->state;		switch( f->state ){		case INITIAL:			f->state = STARTING;			if( f->callbacks->starting )				(*f->callbacks->starting)(f);			break;				case CLOSED:		if( f->flags & OPT_SILENT )			f->state = STOPPED;		else {			/* Send an initial configure-request */			fsm_sconfreq(f, 0);			f->state = REQSENT;		}		break;		case CLOSING:		f->state = STOPPING;		/* fall through */	case STOPPED:	case OPENED:		if( f->flags & OPT_RESTART ){			fsm_lowerdown(f);			fsm_lowerup(f);		}		break;	}		FSMDEBUG((LOG_INFO, "%s: open state %d -> %d\n",			PROTO_NAME(f), oldState, f->state));}/* * fsm_close - Start closing connection. * * Cancel timeouts and either initiate close or possibly go directly to * the CLOSED state. */void fsm_close(fsm *f, char *reason){	int oldState = f->state;		f->term_reason = reason;	f->term_reason_len = (reason == NULL? 0: strlen(reason));	switch( f->state ){	case STARTING:		f->state = INITIAL;		break;	case STOPPED:		f->state = CLOSED;		break;	case STOPPING:		f->state = CLOSING;		break;		case REQSENT:	case ACKRCVD:	case ACKSENT:	case OPENED:		if( f->state != OPENED )			UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */		else if( f->callbacks->down )			(*f->callbacks->down)(f);	/* Inform upper layers we're down */				/* Init restart counter, send Terminate-Request */		f->retransmits = f->maxtermtransmits;		fsm_sdata(f, TERMREQ, f->reqid = ++f->id,					(u_char *) f->term_reason, f->term_reason_len);		TIMEOUT(fsm_timeout, f, f->timeouttime);		--f->retransmits;				f->state = CLOSING;		break;	}		FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d -> %d\n",			PROTO_NAME(f), reason, oldState, f->state));}/* * fsm_sdata - Send some data. * * Used for all packets sent to our peer by this module. */void fsm_sdata(	fsm *f,	u_char code, 	u_char id,	u_char *data,	int datalen){	u_char *outp;	int outlen;		/* Adjust length to be smaller than MTU */	outp = outpacket_buf[f->unit];	if (datalen > peer_mru[f->unit] - (int)HEADERLEN)		datalen = peer_mru[f->unit] - HEADERLEN;	if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)		BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);	outlen = datalen + HEADERLEN;	MAKEHEADER(outp, f->protocol);	PUTCHAR(code, outp);	PUTCHAR(id, outp);	PUTSHORT(outlen, outp);	pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);	FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n",				PROTO_NAME(f), code, id, outlen));}/* * fsm_input - Input packet. */void fsm_input(fsm *f, u_char *inpacket, int l){	u_char *inp = inpacket;	u_char code, id;	int len;		/*	* Parse header (code, id and length).	* If packet too short, drop it.	*/	if (l < HEADERLEN) {		FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n",					f->protocol));		return;	}	GETCHAR(code, inp);	GETCHAR(id, inp);	GETSHORT(len, inp);	if (len < HEADERLEN) {		FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n",				f->protocol));		return;	}	if (len > l) {		FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n",				f->protocol));		return;	}	len -= HEADERLEN;		/* subtract header length */		if( f->state == INITIAL || f->state == STARTING ){		FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.\n",				f->protocol, f->state));		return;	}	FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));	/*	 * Action depends on code.	 */	switch (code) {	case CONFREQ:		fsm_rconfreq(f, id, inp, len);		break;		case CONFACK:		fsm_rconfack(f, id, inp, len);		break;		case CONFNAK:	case CONFREJ:		fsm_rconfnakrej(f, code, id, inp, len);		break;		case TERMREQ:		fsm_rtermreq(f, id, inp, len);		break;		case TERMACK:		fsm_rtermack(f);		break;		case CODEREJ:		fsm_rcoderej(f, inp, len);		break;		default:		if( !f->callbacks->extcode				|| !(*f->callbacks->extcode)(f, code, id, inp, len) )			fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);		break;	}}/* * fsm_protreject - Peer doesn't speak this protocol. * * Treat this as a catastrophic error (RXJ-). */void fsm_protreject(fsm *f){	switch( f->state ){	case CLOSING:		UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */		/* fall through */	case CLOSED:		f->state = CLOSED;		if( f->callbacks->finished )			(*f->callbacks->finished)(f);		break;		case STOPPING:

⌨️ 快捷键说明

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