Sequential state machine

Sequential state machine — State machine helpers

Functions

Types and Values

typedef fpi_ssm

Includes

#include <fpi-ssm.h>

Description

Asynchronous driver design encourages some kind of state machine behind it. In most cases, the state machine is entirely linear - you only go to the next state, you never jump or go backwards. The fpi_ssm functions help you implement such a machine.

e.g. S1S2S3S4

S1 is the start state There is also an implicit error state and an implicit accepting state (both with implicit edges from every state).

You can also jump to any arbitrary state (while marking completion of the current state) while the machine is running. In other words there are implicit edges linking one state to every other state.

To create an fpi_ssm, you pass a state handler function and the total number of states (4 in the above example) to fpi_ssm_new(). Note that the state numbers start at zero, making them match the first value in a C enumeration.

To start a ssm, you pass in a completion callback function to fpi_ssm_start() which gets called when the ssm completes (both on error and on failure).

To iterate to the next state, call fpi_ssm_next_state(). It is legal to attempt to iterate beyond the final state - this is equivalent to marking the ssm as successfully completed.

To mark successful completion of a SSM, either iterate beyond the final state or call fpi_ssm_mark_completed() from any state.

To mark failed completion of a SSM, call fpi_ssm_mark_failed() from any state. You must pass a non-zero error code.

Your state handling function looks at the return value of fpi_ssm_get_cur_state() in order to determine the current state and hence which operations to perform (a switch statement is appropriate).

Typically, the state handling function fires off an asynchronous communication with the device (such as a libsub transfer), and the callback function iterates the machine to the next state upon success (or fails).

Your completion callback should examine the return value of fpi_ssm_get_error() in order to determine whether the fpi_ssm completed or failed. An error code of zero indicates successful completion.

Functions

ssm_completed_fn ()

void
(*ssm_completed_fn) (fpi_ssm *ssm,
                     struct fp_dev *dev,
                     void *user_data);

The callback called when a state machine completes successfully, as set when calling fpi_ssm_start().

Parameters

ssm

a fpi_ssm state machine

 

dev

the fp_dev fingerprint device

 

user_data

the user data passed to fpi_ssm_new()

 

ssm_handler_fn ()

void
(*ssm_handler_fn) (fpi_ssm *ssm,
                   struct fp_dev *dev,
                   void *user_data);

The callback called when a state machine transitions from one state to the next, as set when calling fpi_ssm_new().

Parameters

ssm

a fpi_ssm state machine

 

dev

the fp_dev fingerprint device

 

user_data

the user data passed to fpi_ssm_new()

 

fpi_ssm_new ()

fpi_ssm *
fpi_ssm_new (struct fp_dev *dev,
             ssm_handler_fn handler,
             int nr_states,
             void *user_data);

Allocate a new ssm, with nr_states states. The handler callback will be called after each state transition.

Parameters

dev

a fp_dev fingerprint device

 

handler

the callback function

 

nr_states

the number of states

 

user_data

the user data to pass to callbacks

 

Returns

a new fpi_ssm state machine


fpi_ssm_free ()

void
fpi_ssm_free (fpi_ssm *machine);

Frees a state machine. This does not call any error or success callbacks, so you need to do this yourself.

Parameters

machine

an fpi_ssm state machine

 

fpi_ssm_start ()

void
fpi_ssm_start (fpi_ssm *ssm,
               ssm_completed_fn callback);

Starts a state machine. You can also use this function to restart a completed or failed state machine. The callback will be called on completion.

Parameters

ssm

an fpi_ssm state machine

 

callback

the ssm_completed_fn callback to call on completion

 

fpi_ssm_start_subsm ()

void
fpi_ssm_start_subsm (fpi_ssm *parent,
                     fpi_ssm *child);

Starts a state machine as a child of another. if the child completes successfully, the parent will be advanced to the next state. if the child fails, the parent will be marked as failed with the same error code.

The child will be automatically freed upon completion or failure.

Parameters

parent

an fpi_ssm state machine

 

child

an fpi_ssm state machine

 

fpi_ssm_next_state ()

void
fpi_ssm_next_state (fpi_ssm *machine);

Iterate to next state of a state machine. If the current state is the last state, then the state machine will be marked as completed, as if calling fpi_ssm_mark_completed().

Parameters

machine

an fpi_ssm state machine

 

fpi_ssm_next_state_timeout_cb ()

void
fpi_ssm_next_state_timeout_cb (struct fp_dev *dev,
                               void *data);

Same as fpi_ssm_next_state(), but to be used as a callback for an fpi_timeout_add() callback, when the state change needs to happen after a timeout.

Make sure to pass the fpi_ssm as the user_data argument for that fpi_timeout_add() call.

Parameters

dev

a struct fp_dev

 

data

a pointer to an fpi_ssm state machine

 

fpi_ssm_jump_to_state ()

void
fpi_ssm_jump_to_state (fpi_ssm *machine,
                       int state);

Jump to the state state, bypassing intermediary states.

Parameters

machine

an fpi_ssm state machine

 

state

the state to jump to

 

fpi_ssm_mark_completed ()

void
fpi_ssm_mark_completed (fpi_ssm *machine);

Mark a ssm as completed successfully. The callback set when creating the state machine with fpi_ssm_new() will be called synchronously.

Parameters

machine

an fpi_ssm state machine

 

fpi_ssm_mark_failed ()

void
fpi_ssm_mark_failed (fpi_ssm *machine,
                     int error);

Mark a state machine as failed with error as the error code.

Parameters

machine

an fpi_ssm state machine

 

error

the error code

 

fpi_ssm_get_user_data ()

void *
fpi_ssm_get_user_data (fpi_ssm *machine);

Retrieve the pointer to user data set when fpi_ssm_new() is called.

Parameters

machine

an fpi_ssm state machine

 

Returns

a pointer


fpi_ssm_get_error ()

int
fpi_ssm_get_error (fpi_ssm *machine);

Returns the error code set by fpi_ssm_mark_failed().

Parameters

machine

an fpi_ssm state machine

 

Returns

a error code


fpi_ssm_get_cur_state ()

int
fpi_ssm_get_cur_state (fpi_ssm *machine);

Returns the value of the current state. Note that states are 0-indexed, so a value of 0 means “the first state”.

Parameters

machine

an fpi_ssm state machine

 

Returns

the current state.

Types and Values

fpi_ssm

typedef struct fpi_ssm fpi_ssm;

Sequential state machine that iterates sequentially over a predefined series of states. Can be terminated by either completion or failure error conditions.