#include #include "intf.h" #include "list.h" #include "fsm.h" int tsnif_debug = 0; static struct tsnif_term *term_find(struct tsnif_handle *h, int type, int idx) { struct tsnif_term *t; list_for_each_entry(t, &h->terms, list) if ((t->type == type) && (t->idx == idx)) return t; return NULL; } static int notify_cb(struct tsnif_handle *h, struct trans_msg *msg) { struct tsnif_term term; if (!h->ops || !h->ops->cb_notify) return -1; memset(&term, 0x0, sizeof(term)); term.type = msg->type; term.idx = msg->idx; term.handle = h; term.state = TSNIF_INTF_STATE_NEW; return h->ops->cb_notify(&term, msg->cmd); } static int process_mgroup(struct tsnif_handle *h, struct trans_msg *msg) { return trans_group(&h->trans, msg->group); } static int trans_cb(struct trans_handle *h, struct trans_msg *msg) { struct tsnif_handle *handle; struct tsnif_term *term; TSNIF_DEBUG("got cmd %d, type %d, idx %d\n", msg->cmd, msg->type, msg->idx); handle = container_of(h, struct tsnif_handle, trans); /* then non term related bussines */ switch(msg->cmd) { case TSNIF_CMD_TTY_CREATE: case TSNIF_CMD_TTY_RELEASE: return notify_cb(handle, msg); case TSNIF_CMD_MGROUP: return process_mgroup(handle, msg); } /* and term it is now */ term = term_find(handle, msg->type, msg->idx); if (!term) return -ENODEV; return fsm_process(handle, term, msg); } static int init_mgroup(struct tsnif_handle *h) { struct trans_msg msg; msg.cmd = TSNIF_CMD_MGROUP; return trans_send(&h->trans, &msg); } int tsnif_init(struct tsnif_handle *h, struct tsnif_ops *ops) { int err; if (!ops) return -EINVAL; memset(h, 0x0, sizeof(*h)); h->ops = ops; INIT_LIST_HEAD(&h->terms); err = trans_init(&h->trans, trans_cb); if (err) return err; return init_mgroup(h); } int tsnif_close(struct tsnif_handle *h) { return trans_close(&h->trans); } int tsnif_process(struct tsnif_handle *h) { return trans_process(&h->trans); } int tsnif_fd(struct tsnif_handle *h) { return trans_fd(&h->trans); } int tsnif_term_add(struct tsnif_handle *h, struct tsnif_term *term, int type, int idx) { struct tsnif_term *t; t = term_find(h, type, idx); if (t) return -EEXIST; memset(term, 0x0, sizeof(*term)); term->type = type; term->idx = idx; term->handle = h; term->state = TSNIF_INTF_STATE_NEW; list_add_tail(&term->list, &h->terms); return 0; } int tsnif_term_del(struct tsnif_handle *h, struct tsnif_term *term) { list_del(&term->list); return 0; } int tsnif_attach(struct tsnif_term *term) { struct trans_msg msg; struct tsnif_handle *h = term->handle; TSNIF_DEBUG("type %d, idx %d\n", term->type, term->idx); if (term->state != TSNIF_INTF_STATE_NEW) { TSNIF_DEBUG("wrong state (%d) skiping detach\n", term->state); return -1; } msg.type = term->type; msg.idx = term->idx; msg.cmd = TSNIF_CMD_ATTACH; return trans_send(&h->trans, &msg); } int tsnif_detach(struct tsnif_term *term) { struct trans_msg msg; struct tsnif_handle *h = term->handle; TSNIF_DEBUG("type %d, idx %d\n", term->type, term->idx); if (term->state != TSNIF_INTF_STATE_DATA) { TSNIF_DEBUG("wrong state (%d) skiping detach\n", term->state); return -1; } msg.type = term->type; msg.idx = term->idx; msg.cmd = TSNIF_CMD_DETACH; return trans_send(&h->trans, &msg); }