fsm.c 1.5 KB
Newer Older
1 2 3
/*
 * Alessandro Rubini for CERN, 2011 -- public domain
 */
4 5
#include <pptp/pptp.h>
#include <pptp/diag.h>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

/*
 * This is the state machine code. i.e. the extension-independent
 * function that runs the machine. Errors are managed and reported
 * here (based on the diag module). The returned value is the time
 * in milliseconds to wait before reentering the state machine.
 * the normal protocol. If an extended protocol is used, the table used
 * is that of the extension, otherwise the one in state-table-default.c
 */

int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen)
{
	struct pp_state_table_item *ip;
	int state, err;

21
	if (packet)
22
		msg_unpack_header(ppi, packet);
23

24 25 26 27 28 29 30 31 32
	state = ppi->state;

	/* a linear search is affordable up to a few dozen items */
	for (ip = pp_state_table; ip->state != PPS_END_OF_TABLE; ip++) {
		if (ip->state != state)
			continue;
		/* found: handle this state */
		ppi->next_state = state;
		ppi->next_delay = 0;
33
		ppi->is_new_state = 0;
34 35 36 37 38 39 40 41 42
		pp_diag_fsm(ppi, 0 /* enter */, plen);
		err = ip->f1(ppi, packet, plen);
		if (!err && ip->f2)
			err = ip->f2(ppi, packet, plen);
		if (err)
			pp_diag_error(ppi, err);
		pp_diag_fsm(ppi, 1 /* leave */, 0 /* unused */);

		/* done: accept next state and delay */
43 44 45 46
		if (ppi->state != ppi->next_state) {
			ppi->state = ppi->next_state;
			ppi->is_new_state = 1;
		}
47 48 49 50 51 52
		return ppi->next_delay;
	}
	/* Unknwon state, can't happen */
	pp_diag_error_str2(ppi, "Unknown state in FSM", "");
	return 10000; /* No way out. Repeat message every 10s */
}