diff options
author | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-03-25 08:42:19 +0100 |
---|---|---|
committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-03-25 08:42:19 +0100 |
commit | 24e91dc5627b181f90c800cf613614e5787e76da (patch) | |
tree | 630eb6e8b18492b5d3c3624ab94be3f3e21bc8c0 /src/intf.c | |
download | tsnif-24e91dc5627b181f90c800cf613614e5787e76da.tar.gz tsnif-24e91dc5627b181f90c800cf613614e5787e76da.tar.xz tsnif-24e91dc5627b181f90c800cf613614e5787e76da.zip |
initial commit
Diffstat (limited to 'src/intf.c')
-rw-r--r-- | src/intf.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/intf.c b/src/intf.c new file mode 100644 index 0000000..fde18a3 --- /dev/null +++ b/src/intf.c @@ -0,0 +1,175 @@ + +#include <asm/errno.h> + +#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); +} |