summaryrefslogtreecommitdiffstats
path: root/src/intf.c
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2010-03-25 08:42:19 +0100
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2010-03-25 08:42:19 +0100
commit24e91dc5627b181f90c800cf613614e5787e76da (patch)
tree630eb6e8b18492b5d3c3624ab94be3f3e21bc8c0 /src/intf.c
downloadtsnif-24e91dc5627b181f90c800cf613614e5787e76da.tar.gz
tsnif-24e91dc5627b181f90c800cf613614e5787e76da.tar.xz
tsnif-24e91dc5627b181f90c800cf613614e5787e76da.zip
initial commit
Diffstat (limited to 'src/intf.c')
-rw-r--r--src/intf.c175
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);
+}