state-machine.c 1.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
/*
 * Alessandro Rubini for CERN, 2011 -- public domain
 */
#include <pproto/pproto.h>
#include <pproto/diag.h>

/*
 * 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;

	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;
		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 */
		ppi->state = ppi->next_state;
		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 */
}