diff options
Diffstat (limited to 'src/fsm.c')
-rw-r--r-- | src/fsm.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/fsm.c b/src/fsm.c new file mode 100644 index 0000000..f56c857 --- /dev/null +++ b/src/fsm.c @@ -0,0 +1,127 @@ + +#include <asm/errno.h> + +#include "intf.h" +#include "trans.h" + + +static int process_release(struct tsnif_handle *h, struct tsnif_term *term) +{ + if (!h->ops || !h->ops->cb_release) + return -1; + + return h->ops->cb_release(term); +} + +static int process_error(struct tsnif_handle *h, struct tsnif_term *term, int err) +{ + if (!h->ops || !h->ops->cb_err) + return -1; + + return h->ops->cb_err(term, err); +} + +static int process_tgroup(struct tsnif_handle *h, struct tsnif_term *term, + int group) +{ + int err; + + err = trans_group(&h->trans, group); + term->state = err ? TSNIF_INTF_STATE_DONE : TSNIF_INTF_STATE_DATA; + + TSNIF_DEBUG("adding group %d, err %d\n", group, err); + return err; +} + +static int new(struct tsnif_handle *h, + struct tsnif_term *term, + struct trans_msg *msg) +{ + int err = 0; + + switch(msg->cmd) { + case TSNIF_CMD_TGROUP: + err = process_tgroup(h, term, msg->group); + break; + + case TSNIF_CMD_RELEASE: + err = process_release(h, term); + break; + + case TSNIF_CMD_ATTACH: + /* got ATTACH cmd without error ??? */ + err = -EINVAL; + if (msg->err) + break; + + err = process_error(h, term, msg->error); + break; + + default: + return -1; + } + + return err; +} + +static int process_data(struct tsnif_handle *h, + struct tsnif_term *term, + struct trans_msg *msg) +{ + struct tsnif_data data; + + TSNIF_DEBUG("type %d, idx %d\n", + term->type, term->idx); + + if (!h->ops || !h->ops->cb_data) + return -1; + + data.ptr = msg->data.ptr; + data.len = msg->data.len; + data.flags = msg->data.flags; + + return h->ops->cb_data(term, &data); +} + +static int data(struct tsnif_handle *h, + struct tsnif_term *term, + struct trans_msg *msg) +{ + int err = 0; + + switch(msg->cmd) { + case TSNIF_CMD_RELEASE: + err = process_release(h, term); + break; + + case TSNIF_CMD_DATA: + err = process_data(h, term, msg); + break; + + default: + return -1; + } + + return err; +} + +int fsm_process(struct tsnif_handle *h, + struct tsnif_term *term, + struct trans_msg *msg) +{ + TSNIF_DEBUG("got cmd %d for term type %d, idx %d, state %d\n", + msg->cmd, term->type, term->idx, term->state); + + switch(term->state) { + case TSNIF_INTF_STATE_NEW: + return new(h, term, msg); + + case TSNIF_INTF_STATE_DATA: + return data(h, term, msg); + + default: + return -1; + } + + return 0; +} |