From 69f57959d50cf08d063484551f15f6990582953d Mon Sep 17 00:00:00 2001
From: Timo Dritschler <timo.dritschler@kit.edu>
Date: Tue, 27 May 2014 15:30:08 +0200
Subject: Changed build system to CMake

---
 src/CMakeLists.txt |   2 +
 src/kiro-client.c  | 256 +++++++++++++++++++++++++++++++++++++
 src/kiro-client.h  |  90 +++++++++++++
 src/kiro-rdma.h    | 230 ++++++++++++++++++++++++++++++++++
 src/kiro-server.c  | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/kiro-server.h  | 106 ++++++++++++++++
 src/kiro-trb.c     | 270 +++++++++++++++++++++++++++++++++++++++
 src/kiro-trb.h     | 332 ++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 1647 insertions(+)
 create mode 100644 src/CMakeLists.txt
 create mode 100644 src/kiro-client.c
 create mode 100644 src/kiro-client.h
 create mode 100644 src/kiro-rdma.h
 create mode 100644 src/kiro-server.c
 create mode 100644 src/kiro-server.h
 create mode 100644 src/kiro-trb.c
 create mode 100644 src/kiro-trb.h

(limited to 'src')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..a657e1c
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(kiro kiro-trb.c kiro-client.c kiro-server.c)
+target_link_libraries(kiro SDL m rdmacm ibverbs pthread)
diff --git a/src/kiro-client.c b/src/kiro-client.c
new file mode 100644
index 0000000..807d7d5
--- /dev/null
+++ b/src/kiro-client.c
@@ -0,0 +1,256 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+/**
+ * SECTION: kiro-client
+ * @Short_description: KIRO RDMA Client / Consumer
+ * @Title: KiroClient
+ *
+ * KiroClient implements the client / active / consumer side of the the RDMA
+ * Communication Channel. It uses a KIRO-CLIENT to manage data read from the Server.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <rdma/rdma_verbs.h>
+#include <glib.h>
+#include "kiro-client.h"
+#include "kiro-rdma.h"
+#include "kiro-trb.h"
+
+#include <errno.h>
+
+
+/*
+ * Definition of 'private' structures and members and macro to access them
+ */
+
+#define KIRO_CLIENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), KIRO_TYPE_CLIENT, KiroClientPrivate))
+
+struct _KiroClientPrivate {
+
+    /* Properties */
+    // PLACEHOLDER //
+
+    /* 'Real' private structures */
+    /* (Not accessible by properties) */
+    struct rdma_event_channel   *ec;        // Main Event Channel
+    struct rdma_cm_id           *conn;      // Connection to the Server
+    
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (KiroClient, kiro_client, G_TYPE_OBJECT);
+
+
+static void kiro_client_init (KiroClient *self)
+{
+    KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+    memset(priv, 0, sizeof(&priv));
+}
+
+static void
+kiro_client_finalize (GObject *object)
+{
+    //KiroClient *self = KIRO_CLIENT(object);
+    //KiroClientPrivate * priv = KIRO_CLIENT_GET_PRIVATE(self);
+    //PASS
+}
+
+static void
+kiro_client_class_init (KiroClientClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+    gobject_class->finalize = kiro_client_finalize;
+}
+
+
+
+int kiro_client_connect (KiroClient *self, char *address, char* port)
+{
+    KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+
+    if(priv->conn)
+    {
+        printf("Already connected to server.\n");
+        return -1;
+    }
+    
+    struct rdma_addrinfo hints, *res_addrinfo;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_port_space = RDMA_PS_IB;
+    if(rdma_getaddrinfo(address, port, &hints, &res_addrinfo))
+    {
+        printf("Failed to contruct address information for %s:%s\n",address, port);
+        return -1;
+    }
+    printf("Address information created.\n");
+    
+    struct ibv_qp_init_attr qp_attr;
+    memset(&qp_attr, 0, sizeof(qp_attr));
+    qp_attr.cap.max_send_wr = 10;
+    qp_attr.cap.max_recv_wr = 10;
+    qp_attr.cap.max_send_sge = 1;
+    qp_attr.cap.max_recv_sge = 1;
+    qp_attr.qp_context = priv->conn;
+    qp_attr.sq_sig_all = 1;
+    
+    if(rdma_create_ep(&(priv->conn), res_addrinfo, NULL, &qp_attr))
+    {
+        printf("Endpoint creation failed with error: %i\n", errno);
+        return -1;
+    }
+    printf("Route to server resolved.\n");
+    
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)calloc(1,sizeof(struct kiro_connection_context));
+    if(!ctx)
+    {
+        printf("Failed to create connection context.\n");
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    
+    ctx->cf_mr_send = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+    ctx->cf_mr_recv = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+    if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
+    {
+        printf("Failed to allocate Control Flow Memory Container.\n");
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    
+    ctx->cf_mr_recv = kiro_create_rdma_memory(priv->conn->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
+    ctx->cf_mr_send = kiro_create_rdma_memory(priv->conn->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
+    if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
+    {
+        printf("Failed to register control message memory.\n");
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    ctx->cf_mr_recv->size = ctx->cf_mr_send->size = sizeof(struct kiro_ctrl_msg);
+    priv->conn->context = ctx;
+    
+    if(rdma_post_recv(priv->conn, priv->conn, ctx->cf_mr_recv->mem, ctx->cf_mr_recv->size, ctx->cf_mr_recv->mr))
+    {
+        printf("Posting preemtive receive for connection failed with error: %i\n", errno);
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    
+    if(rdma_connect(priv->conn, NULL))
+    {
+        printf("Failed to establish connection to the server.\n");
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    printf("Connected to server.\n");
+    
+    
+    struct ibv_wc wc;
+    if(rdma_get_recv_comp(priv->conn, &wc) < 0)
+    {
+        printf("Failure waiting for POST from server.\n");
+        rdma_disconnect(priv->conn);
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    printf("Got Message from Server.\n");
+    ctx->peer_mr = (((struct kiro_ctrl_msg *)(ctx->cf_mr_recv->mem))->peer_mri);
+    printf("Expected Memory Size is: %u\n",ctx->peer_mr.length);
+    
+    ctx->rdma_mr = kiro_create_rdma_memory(priv->conn->pd, ctx->peer_mr.length, IBV_ACCESS_LOCAL_WRITE);
+    if(!ctx->rdma_mr)
+    {
+        printf("Failed to allocate memory for receive buffer.\n");
+        rdma_disconnect(priv->conn);
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    printf("Connection setup completed successfully!\n");
+    
+    return 0;
+}
+
+
+
+int kiro_client_sync (KiroClient *self)
+{   
+    KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)priv->conn->context;
+    
+    if(rdma_post_read(priv->conn, priv->conn, ctx->rdma_mr->mem, ctx->peer_mr.length, ctx->rdma_mr->mr, 0, ctx->peer_mr.addr, ctx->peer_mr.rkey))
+    {
+        printf("Failed to read from server.\n");
+        rdma_disconnect(priv->conn);
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    
+    struct ibv_wc wc;
+    if(rdma_get_send_comp(priv->conn, &wc) < 0)
+    {
+        printf("Failure reading from server.\n");
+        rdma_disconnect(priv->conn);
+        kiro_destroy_connection_context(&ctx);
+        rdma_destroy_ep(priv->conn);
+        return -1;
+    }
+    return 0;
+}
+
+
+void* kiro_client_get_memory (KiroClient *self)
+{
+    KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+    if(!priv->conn)
+        return NULL;
+
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)priv->conn->context;
+    if(!ctx->rdma_mr)
+        return NULL;
+        
+    return ctx->rdma_mr->mem;
+}
+
+
+size_t kiro_client_get_memory_size (KiroClient *self)
+{
+    KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+    if(!priv->conn)
+        return 0;
+
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)priv->conn->context;
+    if(!ctx->rdma_mr)
+        return 0;
+        
+    return ctx->rdma_mr->size;
+}
+
+
+
+
+
diff --git a/src/kiro-client.h b/src/kiro-client.h
new file mode 100644
index 0000000..e3e60de
--- /dev/null
+++ b/src/kiro-client.h
@@ -0,0 +1,90 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+/**
+ * SECTION: kiro-client
+ * @Short_description: KIRO RDMA Client / Consumer
+ * @Title: KiroClient
+ *
+ * KiroClient implements the client / active / consumer side of the the RDMA
+ * Communication Channel. It uses a KIRO-CLIENT to manage data read from the Server.
+ */
+ 
+#ifndef __KIRO_CLIENT_H
+#define __KIRO_CLIENT_H
+
+#include <stdint.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define KIRO_TYPE_CLIENT             (kiro_client_get_type())
+#define KIRO_CLIENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), KIRO_TYPE_CLIENT, KiroClient))
+#define KIRO_IS_CLIENT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), KIRO_TYPE_CLIENT))
+#define KIRO_CLIENT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), KIRO_TYPE_CLIENT, KiroClientClass))
+#define KIRO_IS_CLIENT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), KIRO_TYPE_CLIENT))
+#define KIRO_CLIENT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), KIRO_TYPE_CLIENT, KiroClientClass))
+
+
+typedef struct _KiroClient           KiroClient;
+typedef struct _KiroClientClass      KiroClientClass;
+typedef struct _KiroClientPrivate    KiroClientPrivate;
+
+
+struct _KiroClient {
+    
+    GObject parent;
+    
+    /*< private >*/
+    KiroClientPrivate *priv;
+};
+
+
+/**
+ * IbvConnectorInterface:
+ *
+ * Base interface for IbvConnectors.
+ */
+
+struct _KiroClientClass {
+    
+    GObjectClass parent_class;
+       
+};
+
+
+
+/* GObject and GType functions */
+GType       kiro_client_get_type            (void);
+
+GObject     kiro_client_new                 (void);
+
+/* client functions */
+
+
+int         kiro_client_connect             (KiroClient* client, char* dest_addr, char* dest_port);
+
+int         kiro_client_sync                (KiroClient* client);
+
+void*       kiro_client_get_memory          (KiroClient* client);
+
+size_t      kior_client_get_memory_size     (KiroClient* client);
+
+G_END_DECLS
+
+#endif //__KIRO_CLIENT_H
\ No newline at end of file
diff --git a/src/kiro-rdma.h b/src/kiro-rdma.h
new file mode 100644
index 0000000..fa16fd1
--- /dev/null
+++ b/src/kiro-rdma.h
@@ -0,0 +1,230 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifndef __KIRO_RDMA_H__
+#define __KIRO_RDMA_H__
+
+
+#include <rdma/rdma_cma.h>
+
+  
+struct kiro_connection_context {
+        
+    // Information and necessary structurs
+    uint32_t                identifier;             // Unique Identifier for this connection (Application Specific)
+    struct kiro_rdma_mem    *cf_mr_recv;            // Control-Flow Memory Region Receive
+    struct kiro_rdma_mem    *cf_mr_send;            // Control-Flow Memory Region Send
+    struct kiro_rdma_mem    *rdma_mr;               // Memory Region for RDMA Operations
+
+    struct ibv_mr           peer_mr;                // RDMA Memory Region Information of the peer
+    
+    enum {
+        KIRO_IDLE,
+        KIRO_MRI_REQUESTED,                         // Memory Region Information Requested
+        KIRO_RDMA_ESTABLISHED,                      // MRI Exchange complete. RDMA is ready
+        KIRO_RDMA_ACTIVE                            // RDMA Operation is being performed
+    } rdma_state;
+    
+};
+
+
+struct kiro_connection {
+    
+    uint32_t                identifier;
+    struct rdma_cm_id       *id;
+    struct kiro_connection  *next;
+    
+};
+
+
+struct kiro_ctrl_msg {
+    
+    enum {
+        KIRO_REQ_RDMA,                              // Requesting RDMA Access to/from the peer
+        KIRO_ACK_RDMA,                              // acknowledge RDMA Request and provide Memory Region Information
+        KIRO_REJ_RDMA                               // RDMA Request rejected :(  (peer_mri will be invalid)
+    } msg_type;
+    
+    struct ibv_mr peer_mri;
+    
+};
+
+
+struct kiro_rdma_mem {
+    
+    void            *mem;   // Pointer to the beginning of the memory block           
+    struct ibv_mr   *mr;    // Memory Region associated with the memory
+    size_t          size;   // Size in Bytes of the memory block
+
+};
+
+
+static int kiro_attach_qp (struct rdma_cm_id *id)
+{
+    if(!id)
+        return -1;
+    
+    id->pd = ibv_alloc_pd(id->verbs);
+    id->send_cq_channel = ibv_create_comp_channel(id->verbs);
+    id->recv_cq_channel = id->send_cq_channel; //we use one shared completion channel
+    id->send_cq = ibv_create_cq(id->verbs, 1, id, id->send_cq_channel, 0);
+    id->recv_cq = id->send_cq; //we use one shared completion queue
+    
+    struct ibv_qp_init_attr qp_attr;
+    memset(&qp_attr, 0, sizeof(struct ibv_qp_init_attr));
+    qp_attr.qp_context = (uintptr_t)id;
+    qp_attr.send_cq = id->send_cq;
+    qp_attr.recv_cq = id->recv_cq;
+    qp_attr.qp_type = IBV_QPT_RC;
+    qp_attr.cap.max_send_wr = 1;
+    qp_attr.cap.max_recv_wr = 1;
+    qp_attr.cap.max_send_sge = 1;
+    qp_attr.cap.max_recv_sge = 1;
+    
+    return rdma_create_qp(id, id->pd, &qp_attr);
+}
+
+
+static int kiro_register_rdma_memory (struct ibv_pd *pd, struct ibv_mr **mr, void *mem, size_t mem_size, int access)
+{
+    
+    if(mem_size == 0)
+    {    
+        printf("Cant allocate memory of size '0'.\n");
+        return -1;
+    }
+    
+    void *mem_handle = mem;
+    
+    if(!mem_handle)
+        mem_handle = malloc(mem_size);
+        
+    if(!mem_handle)
+    {
+        printf("Failed to allocate memory [Register Memory].");
+        return -1;
+    }        
+    
+    *mr = ibv_reg_mr(pd, mem_handle, mem_size, access);
+    if(!(*mr))
+    {
+        // Memory Registration failed
+        printf("Failed to register memory region!\n");
+        free(mem_handle);
+        return -1;
+    }
+    
+    return 0;
+}
+
+
+static struct kiro_rdma_mem* kiro_create_rdma_memory (struct ibv_pd *pd, size_t mem_size, int access)
+{
+    if(mem_size == 0)
+    {    
+        printf("Cant allocate memory of size '0'.\n");
+        return NULL;
+    }
+    
+    struct kiro_rdma_mem *krm = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+    if(!krm)
+    {
+        printf("Failed to create new KIRO RDMA Memory.\n");
+        return NULL;
+    }
+    
+    if(kiro_register_rdma_memory(pd, &(krm->mr), krm->mem, mem_size, access))
+    {
+        free(krm);
+        return NULL;
+    }
+    
+    if(!krm->mem)
+        krm->mem = krm->mr->addr;
+    
+    
+    return krm;
+    
+}
+
+
+static void kiro_destroy_rdma_memory (struct kiro_rdma_mem *krm)
+{
+    if(!krm)
+        return;
+        
+    if(krm->mr)
+        ibv_dereg_mr(krm->mr);
+        
+    if(krm->mem)
+        free(krm->mem);
+        
+    free(krm);
+    krm = NULL;
+}
+
+
+static void kiro_destroy_connection_context (struct kiro_connection_context **ctx)
+{
+    if(!ctx)
+        return;
+    
+    if(!(*ctx))
+        return;
+        
+    if((*ctx)->cf_mr_recv)
+        kiro_destroy_rdma_memory((*ctx)->cf_mr_recv);
+    if((*ctx)->cf_mr_send)
+        kiro_destroy_rdma_memory((*ctx)->cf_mr_send);
+        
+    //The RDMA-Memory Region normally contains allocated memory from the USER that has
+    //just been 'registered' for RDMA. DON'T free it! Just deregister it. The user is
+    //responsible for freeing this memory. 
+    if((*ctx)->rdma_mr)
+    {
+        if((*ctx)->rdma_mr->mr)
+            ibv_dereg_mr((*ctx)->rdma_mr->mr);
+           
+        free((*ctx)->rdma_mr);
+        (*ctx)->rdma_mr = NULL;
+    }
+
+    free(*ctx);
+    *ctx = NULL;
+}
+
+
+static void kiro_destroy_connection (struct rdma_cm_id **conn)
+{
+    if(!(*conn))
+        return;
+        
+    rdma_disconnect(*conn);
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)((*conn)->context);
+    if(ctx)
+        kiro_destroy_connection_context(&ctx);
+        
+    rdma_destroy_ep(*conn);
+    *conn = NULL;
+}
+
+
+#endif //__KIRO_RDMA_H__   
\ No newline at end of file
diff --git a/src/kiro-server.c b/src/kiro-server.c
new file mode 100644
index 0000000..52304c8
--- /dev/null
+++ b/src/kiro-server.c
@@ -0,0 +1,361 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+/**
+ * SECTION: kiro-server
+ * @Short_description: KIRO RDMA Server / Consumer
+ * @Title: KiroServer
+ *
+ * KiroServer implements the server / passive / provider side of the the RDMA
+ * Communication Channel. It uses a KIRO-TRB to manage its data.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <rdma/rdma_verbs.h>
+#include <glib.h>
+#include "kiro-server.h"
+#include "kiro-rdma.h"
+#include "kiro-trb.h"
+
+
+/*
+ * Definition of 'private' structures and members and macro to access them
+ */
+
+#define KIRO_SERVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), KIRO_TYPE_SERVER, KiroServerPrivate))
+
+struct _KiroServerPrivate {
+
+    /* Properties */
+    // PLACEHOLDER //
+
+    /* 'Real' private structures */
+    /* (Not accessible by properties) */
+    struct rdma_event_channel   *ec;            // Main Event Channel
+    struct rdma_cm_id           *base;          // Base-Listening-Connection
+    struct kiro_connection      *client;        // Connection to the client
+    pthread_t                   event_listener; // Pointer to the completion-listener thread of this connection
+    pthread_mutex_t             mtx;            // Mutex to signal the listener-thread termination
+    void                        *mem;           // Pointer to the server buffer
+    size_t                      mem_size;       // Server Buffer Size in bytes
+
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (KiroServer, kiro_server, G_TYPE_OBJECT);
+
+
+static void kiro_server_init (KiroServer *self)
+{
+    KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self);
+    memset(priv, 0, sizeof(&priv));
+}
+
+
+static void
+kiro_server_finalize (GObject *object)
+{
+    //PASS
+}
+
+
+static void
+kiro_server_class_init (KiroServerClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+    gobject_class->finalize = kiro_server_finalize;
+}
+
+
+static int connect_client (struct rdma_cm_id *client)
+{
+    if(!client)
+        return -1;
+        
+    if( -1 == kiro_attach_qp(client))
+    {
+        printf("Could not create a QP for the new connection.\n");
+        rdma_destroy_id(client);
+        return -1;
+    }
+    
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)calloc(1,sizeof(struct kiro_connection_context));
+    if(!ctx)
+    {
+        printf("Failed to create connection context.\n");
+        rdma_destroy_id(client);
+        return -1;
+    }
+    
+    ctx->cf_mr_send = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+    ctx->cf_mr_recv = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+    if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
+    {
+        printf("Failed to allocate Control Flow Memory Container.\n");
+        goto error;
+    }
+    
+    ctx->cf_mr_recv = kiro_create_rdma_memory(client->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
+    ctx->cf_mr_send = kiro_create_rdma_memory(client->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
+    if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
+    {
+        printf("Failed to register control message memory.\n");
+        goto error;
+    }
+    ctx->cf_mr_recv->size = ctx->cf_mr_send->size = sizeof(struct kiro_ctrl_msg);
+    client->context = ctx;
+    
+    if(rdma_post_recv(client, client, ctx->cf_mr_recv->mem, ctx->cf_mr_recv->size, ctx->cf_mr_recv->mr))
+    {
+        printf("Posting preemtive receive for connection failed.\n");
+        goto error;
+    }
+    
+    if(rdma_accept(client, NULL))
+    {
+        printf("Failed to establish connection to the client with error: %i.\n", errno);
+        goto error;
+    }
+    printf("Client Connected.\n");
+    return 0;
+
+
+error:
+    rdma_reject(client, NULL, 0);
+    kiro_destroy_connection_context(&ctx);
+    rdma_destroy_id(client);
+    return -1;
+}
+
+
+static int welcome_client (struct rdma_cm_id *client, void *mem, size_t mem_size)
+{
+    struct kiro_connection_context *ctx = (struct kiro_connection_context *)(client->context);
+    ctx->rdma_mr = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+    if(!ctx->rdma_mr)
+    {
+        printf("Failed to allocate RDMA Memory Container.\n");
+        return -1;
+    }
+    
+    ctx->rdma_mr->mem = mem;
+    ctx->rdma_mr->size = mem_size;
+    ctx->rdma_mr->mr = rdma_reg_read(client, ctx->rdma_mr->mem, ctx->rdma_mr->size);
+    if(!ctx->rdma_mr->mr)
+    {
+        printf("Failed to register RDMA Memory Region.\n");
+        kiro_destroy_rdma_memory(ctx->rdma_mr);
+        return -1;
+    }
+    
+    struct kiro_ctrl_msg *msg = (struct kiro_ctrl_msg *)(ctx->cf_mr_send->mem);
+    msg->msg_type = KIRO_ACK_RDMA;
+    msg->peer_mri = *(ctx->rdma_mr->mr);
+    
+    if(rdma_post_send(client, client, ctx->cf_mr_send->mem, ctx->cf_mr_send->size, ctx->cf_mr_send->mr, IBV_SEND_SIGNALED))
+    {
+        printf("Failure while trying to post SEND.\n");
+        kiro_destroy_rdma_memory(ctx->rdma_mr);
+        return -1;
+    }
+    
+    struct ibv_wc wc;
+    
+    if(rdma_get_send_comp(client, &wc) < 0)
+    {
+        printf("Failed to post RDMA MRI to client.\n");
+        kiro_destroy_rdma_memory(ctx->rdma_mr);
+        return -1;
+    }
+    printf("RDMA MRI sent to client.\n");
+
+    return 0;
+}
+
+
+void * event_loop (void *self)
+{
+    KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE((KiroServer *)self);
+    struct rdma_cm_event *active_event;
+
+    int stop = 0;
+
+    while(0 == stop) {
+        if(0 <= rdma_get_cm_event(priv->ec, &active_event))
+        {
+            
+            struct rdma_cm_event *ev = malloc(sizeof(*active_event));
+            if(!ev)
+            {
+                printf("Unable to allocate memory for Event handling!\n");
+                rdma_ack_cm_event(active_event); 
+                continue;
+            }
+            memcpy(ev, active_event, sizeof(*active_event));
+            rdma_ack_cm_event(active_event);            
+            
+            if (ev->event == RDMA_CM_EVENT_CONNECT_REQUEST)
+            {
+
+                /*
+                priv->client = (struct kiro_connection *)calloc(1, sizeof(struct kiro_connection));
+                if(!(priv->client))
+                {
+                    printf("Failed to create container for client connection.\n");
+                    free(ev);
+                    continue;
+                }
+                priv->client->identifier = 0; //First Client
+                priv->client->id = ev->id;
+                */
+                
+                if(0 == connect_client(ev->id))
+                {
+                    // Connection set-up successfully! (Server)
+                    // Post a welcoming "Recieve" for handshaking
+                    welcome_client(ev->id, priv->mem, priv->mem_size);
+                }
+            }
+            else if(ev->event == RDMA_CM_EVENT_DISCONNECTED)
+            {
+                printf("Got disconnect request.\n");
+                //pthread_mutex_unlock(&(priv->mtx));
+                kiro_destroy_connection(&(ev->id));
+                printf("Connection closed successfully\n");
+            }            
+            free(ev);
+        }
+
+        // Mutex will be freed as a signal to stop request
+        if(0 == pthread_mutex_trylock(&(priv->mtx)))
+            stop = 1;
+    }
+
+    printf("Closing Event Listener Thread\n");
+    return NULL;
+}
+
+
+
+
+int kiro_server_start (KiroServer *self, char *address, char *port, void* mem, size_t mem_size)
+{
+    KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self);
+
+    if(priv->base)
+    {
+        printf("Server already started.\n");
+        return -1;
+    }
+    
+    if(!mem || mem_size == 0)
+    {
+        printf("Invalid memory given to provide.\n");
+        return -1;
+    }
+    
+    struct rdma_addrinfo hints, *res_addrinfo;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_port_space = RDMA_PS_IB;
+    hints.ai_flags = RAI_PASSIVE;
+    if(rdma_getaddrinfo(address, port, &hints, &res_addrinfo))
+    {
+        printf("Failed to create address information.");
+        return -1;
+    }
+    
+    struct ibv_qp_init_attr qp_attr;
+    memset(&qp_attr, 0, sizeof(qp_attr));
+    qp_attr.cap.max_send_wr = 10;
+    qp_attr.cap.max_recv_wr = 10;
+    qp_attr.cap.max_send_sge = 1;
+    qp_attr.cap.max_recv_sge = 1;
+    qp_attr.qp_context = priv->base;
+    qp_attr.sq_sig_all = 1;
+    
+    if(rdma_create_ep(&(priv->base), res_addrinfo, NULL, &qp_attr))
+    {
+        printf("Endpoint creation failed.\n");
+        return -1;
+    }
+    printf("Endpoint created.\n");
+    
+    char *addr_local = NULL;
+    struct sockaddr* src_addr = rdma_get_local_addr(priv->base);
+    if(!src_addr)
+    {
+        addr_local = "NONE";
+    }
+    else
+    {
+        addr_local = inet_ntoa(((struct sockaddr_in *)src_addr)->sin_addr);
+        /*
+        if(src_addr->sa_family == AF_INET)
+            addr_local = &(((struct sockaddr_in*)src_addr)->sin_addr);
+        else
+            addr_local = &(((struct sockaddr_in6*)src_addr)->sin6_addr);
+        */
+    }
+    
+    printf("Bound to address %s:%s\n",addr_local, port);
+    
+    if(rdma_listen(priv->base, 0))
+    {
+        printf("Failed to put server into listening state.\n");
+        rdma_destroy_ep(priv->base);
+        return -1;
+    }
+    
+    priv->mem = mem;
+    priv->mem_size = mem_size;
+
+    priv->ec = rdma_create_event_channel();
+    int oldflags = fcntl (priv->ec->fd, F_GETFL, 0);
+    /* Only change the FD Mode if we were able to get its flags */
+    if (oldflags >= 0) {
+        oldflags |= O_NONBLOCK;
+        /* Store modified flag word in the descriptor. */
+        fcntl (priv->ec->fd, F_SETFL, oldflags);
+    }
+    if(rdma_migrate_id(priv->base, priv->ec))
+    {
+        printf("Was unable to migrate connection to new Event Channel.\n");
+        rdma_destroy_ep(priv->base);
+        return -1;
+    }
+
+    pthread_mutex_init(&(priv->mtx), NULL);
+    pthread_mutex_lock(&(priv->mtx));
+    pthread_create(&(priv->event_listener), NULL, event_loop, self);
+
+    printf("Enpoint listening.\n");
+    
+    sleep(1);
+    return 0;
+}
+
+
+
+
+
+
+
diff --git a/src/kiro-server.h b/src/kiro-server.h
new file mode 100644
index 0000000..cb9b57c
--- /dev/null
+++ b/src/kiro-server.h
@@ -0,0 +1,106 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+/**
+ * SECTION: kiro-server
+ * @Short_description: KIRO RDMA Server / Consumer
+ * @Title: KiroServer
+ *
+ * KiroServer implements the server / passive / provider side of the the RDMA
+ * Communication Channel. It uses a KIRO-TRB to manage its data.
+ */
+ 
+#ifndef __KIRO_SERVER_H
+#define __KIRO_SERVER_H
+
+#include <stdint.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define KIRO_TYPE_SERVER             (kiro_server_get_type())
+#define KIRO_SERVER(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), KIRO_TYPE_SERVER, KiroServer))
+#define KIRO_IS_SERVER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), KIRO_TYPE_SERVER))
+#define KIRO_SERVER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), KIRO_TYPE_SERVER, KiroServerClass))
+#define KIRO_IS_SERVER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), KIRO_TYPE_SERVER))
+#define KIRO_SERVER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), KIRO_TYPE_SERVER, KiroServerClass))
+
+
+typedef struct _KiroServer           KiroServer;
+typedef struct _KiroServerClass      KiroServerClass;
+typedef struct _KiroServerPrivate    KiroServerPrivate;
+
+
+struct _KiroServer {
+    
+    GObject parent;
+    
+    /*< private >*/
+    KiroServerPrivate *priv;
+};
+
+
+/**
+ * IbvConnectorInterface:
+ *
+ * Base interface for IbvConnectors.
+ */
+
+struct _KiroServerClass {
+    
+    GObjectClass parent_class;
+       
+};
+
+
+
+/* GObject and GType functions */
+GType       kiro_server_get_type            (void);
+
+GObject     kiro_server_new                 (void);
+
+/* server functions */
+
+/**
+ * kiro_server_start - Starts the server, providing the given memory
+ * @server: KIRO SERVER to perform the operation on
+ * @bind_addr: Local address to bind the server to
+ * @bind_port: Local port to listen for connections
+ * @mem: Pointer to the memory that is to be provided
+ * @mem_size: Size in bytes of the given memory
+ * Description:
+ *   Starts the server to provide the given memory to any connecting
+ *   client.
+ * Notes:
+ *   If the bind_addr is NULL, the server will bind to the first device
+ *   it can find on the machine and listen across all IPs. Otherwise it
+ *   will try to bind to the device associated with the given address.
+ *   Address is given as a string of either a hostname or a dot-seperated
+ *   IPv4 address or a colon-seperated IPv6 hex-address.
+ *   If bind_port is NULL the server will choose a free port randomly
+ *   and return the chosen port as return value.
+ *   If server creation fails, -1 is returned instead.
+ * See also:
+ *   kiro_trb_reshape, kiro_trb_adopt,
+ *   kiro_trb_clone
+ */
+int kiro_server_start (KiroServer* server, char* bind_addr, char* bind_port, void* mem, size_t mem_size);
+
+G_END_DECLS
+
+#endif //__KIRO_SERVER_H
\ No newline at end of file
diff --git a/src/kiro-trb.c b/src/kiro-trb.c
new file mode 100644
index 0000000..e81a4f7
--- /dev/null
+++ b/src/kiro-trb.c
@@ -0,0 +1,270 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+/**
+ * SECTION: kiro-trb
+ * @Short_description: KIRO 'Transmittable Ring Buffer'
+ * @Title: KiroTrb
+ *
+ * KiroTrb implements a 'Transmittable Ring Buffer' that holds all necessary information
+ * about its content inside itself, so its data can be exchanged between different
+ * instances of the KiroTrb Class and/or sent over a network.
+ */
+
+#include <stdio.h>
+ 
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "kiro-trb.h"
+
+
+/*
+ * Definition of 'private' structures and members and macro to access them
+ */
+
+#define KIRO_TRB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), KIRO_TYPE_TRB, KiroTrbPrivate))
+
+struct _KiroTrbPrivate {
+
+    /* Properties */
+    // PLACEHOLDER //
+
+    /* 'Real' private structures */
+    /* (Not accessible by properties) */
+    int         initialized;    // 1 if Buffer is Valid, 0 otherwise
+    void        *mem;            // Access to the actual buffer in Memory
+    void        *frame_top;      // First byte of the buffer storage
+    void        *current;        // Pointer to the current fill state
+    uint64_t    element_size;   
+    uint64_t    max_elements;
+    uint64_t    iteration;      // How many times the buffer has wraped around
+    
+    /* easy access */
+    uint64_t    buff_size;
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (KiroTrb, kiro_trb, G_TYPE_OBJECT);
+
+
+static
+void kiro_trb_init (KiroTrb *self)
+{
+    KiroTrbPrivate *priv = KIRO_TRB_GET_PRIVATE(self);
+    priv->initialized = 0;
+}
+
+static void
+kiro_trb_finalize (GObject *object)
+{
+    KiroTrb *self = KIRO_TRB(object);
+    KiroTrbPrivate *priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->mem)
+        free(priv->mem);
+}
+
+static void
+kiro_trb_class_init (KiroTrbClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+    gobject_class->finalize = kiro_trb_finalize;
+}
+
+
+/* Privat functions */
+
+void write_header (KiroTrbPrivate* priv)
+{
+    if(!priv)
+        return;
+    struct KiroTrbInfo* tmp_info = (struct KiroTrbInfo*)priv->mem;
+    tmp_info->buffer_size_bytes = priv->buff_size;
+    tmp_info->element_size = priv->element_size;
+    tmp_info->offset = (priv->iteration * priv->max_elements) + ((priv->current - priv->frame_top) / priv->element_size);
+    memcpy(priv->mem, tmp_info, sizeof(struct KiroTrbInfo));
+}
+
+
+
+/* TRB functions */
+
+uint64_t kiro_trb_get_element_size (KiroTrb* self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return 0;
+    return priv->element_size;
+}
+
+
+uint64_t kiro_trb_get_max_elements (KiroTrb* self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return 0;
+    return priv->max_elements;
+}
+
+
+uint64_t kiro_trb_get_raw_size (KiroTrb* self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return 0;
+    return priv->buff_size;
+}
+
+
+void* kiro_trb_get_raw_buffer (KiroTrb* self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); 
+    if(priv->initialized != 1)
+        return NULL;
+    write_header(priv);
+    return priv->mem;
+}
+
+
+
+void* kiro_trb_get_element (KiroTrb* self, uint64_t element)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return NULL;
+    
+    uint64_t relative = 0;    
+    if(priv->iteration == 0)
+        relative = element * priv->element_size;
+    else
+        relative = ((priv->current - priv->frame_top) + (priv->element_size * element)) % (priv->buff_size - sizeof(struct KiroTrbInfo));
+        
+    return priv->frame_top + relative;
+}
+
+
+void kiro_trb_flush (KiroTrb *self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    priv->iteration = 0;
+    priv->current = priv->frame_top;
+    write_header(priv);
+}
+
+
+int kiro_trb_is_setup (KiroTrb *self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    return priv->initialized;
+}
+
+
+int kiro_trb_reshape (KiroTrb *self, uint64_t element_size, uint64_t element_count)
+{
+    size_t new_size = (element_size * element_count) + sizeof(struct KiroTrbInfo);
+    void* newmem = malloc(new_size);
+    if(!newmem)
+        return -1;
+    ((struct KiroTrbInfo *)newmem)->buffer_size_bytes = new_size;
+    ((struct KiroTrbInfo *)newmem)->element_size = element_size;
+    ((struct KiroTrbInfo *)newmem)->offset = 0;
+    kiro_trb_adopt(self, newmem);
+    return 0;
+}
+
+
+int kiro_trb_push (KiroTrb *self, void *element_in)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return -1;
+    if((priv->current + priv->element_size) > (priv->mem + priv->buff_size))
+        return -1;
+    memcpy(priv->current, element_in, priv->element_size);
+    priv->current += priv->element_size;
+    if(priv->current >= priv->frame_top + (priv->element_size * priv->max_elements))
+    {
+        priv->current = priv->frame_top;
+        priv->iteration++;
+    }
+    write_header(priv);
+    return 0;        
+}
+
+
+void* kiro_trb_dma_push (KiroTrb *self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return NULL;
+    if((priv->current + priv->element_size) > (priv->mem + priv->buff_size))
+        return NULL;
+    void *mem_out = priv->current;
+    priv->current += priv->element_size;
+    if(priv->current >= priv->frame_top + (priv->element_size * priv->max_elements))
+    {
+        priv->current = priv->frame_top;
+        priv->iteration++;
+    }
+    write_header(priv);
+    return mem_out;        
+}
+
+
+void kiro_trb_refresh (KiroTrb *self)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->initialized != 1)
+        return;
+    struct KiroTrbInfo *tmp = (struct KiroTrbInfo *)priv->mem;
+    priv->buff_size = tmp->buffer_size_bytes;
+    priv->element_size = tmp->element_size;
+    priv->max_elements = (tmp->buffer_size_bytes - sizeof(struct KiroTrbInfo)) / tmp->element_size;
+    priv->iteration = tmp->offset / priv->max_elements;
+    priv->frame_top = priv->mem + sizeof(struct KiroTrbInfo);
+    priv->current = priv->frame_top + ((tmp->offset % priv->max_elements) * priv->element_size);
+    priv->initialized = 1;
+}
+
+
+void kiro_trb_adopt (KiroTrb *self, void *buff_in)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    if(priv->mem)
+        free(priv->mem);
+    priv->mem = buff_in;
+    priv->initialized = 1;
+    kiro_trb_refresh(self);
+}
+
+
+int kiro_trb_clone (KiroTrb *self, void *buff_in)
+{
+    KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self);
+    struct KiroTrbInfo *header = (struct KiroTrbInfo *)buff_in;
+    void *newmem = malloc(header->buffer_size_bytes);
+    if(!newmem)
+        return -1;
+    memcpy(newmem, buff_in, header->buffer_size_bytes);
+    if(priv->mem)
+        free(priv->mem);
+    priv->mem = newmem;
+    priv->initialized = 1;
+    kiro_trb_refresh(self);
+    return 0;
+}
diff --git a/src/kiro-trb.h b/src/kiro-trb.h
new file mode 100644
index 0000000..5c2b462
--- /dev/null
+++ b/src/kiro-trb.h
@@ -0,0 +1,332 @@
+/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu>
+   (Karlsruhe Institute of Technology)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   This library is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+   details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this library; if not, write to the Free Software Foundation, Inc., 51
+   Franklin St, Fifth Floor, Boston, MA 02110, USA
+*/
+
+/**
+ * SECTION: kiro-trb
+ * @Short_description: KIRO 'Transmittable Ring Buffer'
+ * @Title: KiroTrb
+ *
+ * KiroTrb implements a 'Transmittable Ring Buffer' that holds all necessary information
+ * about its content inside itself, so its data can be exchanged between different
+ * instances of the KiroTrb Class and/or sent over a network.
+ */
+ 
+#ifndef __KIRO_TRB_H
+#define __KIRO_TBR_H
+
+#include <stdint.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define KIRO_TYPE_TRB             (kiro_trb_get_type())
+#define KIRO_TRB(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), KIRO_TYPE_TRB, KiroTrb))
+#define KIRO_IS_TRB(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), KIRO_TYPE_TRB))
+#define KIRO_TRB_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), KIRO_TYPE_TRB, KiroTrbClass))
+#define KIRO_IS_TRB_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), KIRO_TYPE_TRB))
+#define KIRO_TRB_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), KIRO_TYPE_TRB, KiroTrbClass))
+
+
+typedef struct _KiroTrb           KiroTrb;
+typedef struct _KiroTrbClass      KiroTrbClass;
+typedef struct _KiroTrbPrivate    KiroTrbPrivate;
+
+
+struct _KiroTrb {
+    
+    GObject parent;
+
+};
+
+
+/**
+ * IbvConnectorInterface:
+ *
+ * Base interface for IbvConnectors.
+ */
+
+struct _KiroTrbClass {
+    
+    GObjectClass parent_class;
+       
+};
+
+
+struct KiroTrbInfo {
+    
+    /* internal information about the buffer */
+    uint64_t buffer_size_bytes;  // Size in bytes INCLUDING this header
+    uint64_t element_size;       // Size in bytes of one single element
+    uint64_t offset;             // Current Offset to access the 'oldest' element (in element count!)
+    
+} __attribute__((packed));
+
+
+/* GObject and GType functions */
+GType       kiro_trb_get_type           (void);
+
+GObject     kiro_trb_new                (void);
+
+
+/* trb functions */
+
+/**
+ * kiro_trb_get_element_size - Returns the element size in bytes
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Returns the size of the individual elements in the buffer
+ * See also:
+ *   kiro_trb_reshape, kiro_trb_adopt, kiro_trb_clone
+ */
+uint64_t kiro_trb_get_element_size (KiroTrb* trb);
+
+/**
+ * kiro_trb_get_max_elements - Returns the capacity of the buffer
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Returns the mximal number of elements that can be stored in
+ *   the buffer
+ * See also:
+ *   kiro_trb_get_element_size, kiro_trb_reshape, kiro_trb_adopt,
+ *   kiro_trb_clone
+ */
+uint64_t kiro_trb_get_max_elements (KiroTrb* trb);
+
+
+/**
+ * kiro_trb_get_raw_size - Returns the size of the buffer memory
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Returns the size of the buffers internal memory
+ * Notes:
+ *   The returned size is given INCLUDING the header on top of the
+ *   buffers internal memory
+ * See also:
+ *   kiro_trb_reshape, kiro_trb_adopt,
+ *   kiro_trb_clone
+ */
+uint64_t kiro_trb_get_raw_size (KiroTrb* trb);
+
+
+/**
+ * kiro_trb_get_raw_buffer - Returns a pointer to the buffer memory
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Returns a pointer to the memory structure of the given buffer.
+ * Notes:
+ *   The returned pointer points to the beginning of the internal
+ *   memory of the buffer, including all header information. The
+ *   user is responsible to ensure the consistency of any data
+ *   written to the memory and should call 'kiro_trb_refesh' in
+ *   case any header information was changed.
+ *   The pointed to memory might become invalid at any time by
+ *   concurrent access to the TRB, reshaping, adopting or cloning
+ *   a new memory block.
+ *   Under no circumstances might the memory pointed to by the returned
+ *   pointer be 'freed' by the user!
+ *   If this function is called on a buffer that is not yet setup,
+ *   a NULL pointer is returned instead.
+ * See also:
+ *   kiro_trb_refesh, kiro_trb_reshape, kiro_trb_adopt, kiro_trb_clone
+ */
+void* kiro_trb_get_raw_buffer (KiroTrb* trb);
+
+
+/**
+ * kiro_trb_get_element - Returns a pointer to the element at the given
+ * index.
+ * @trb: KIRO TRB to perform the operation on
+ * @index: Index of the element in the buffer to access
+ * Description:
+ *   Returns a pointer to the element in the buffer at the given index.
+ * Notes:
+ *   The returned pointer to the element is only guaranteed to be valid
+ *   immediately after the function call. The user is responsible to
+ *   ensure that no data is written to the returned memory. The
+ *   element pointed to might become invalid at any time by any concurrent
+ *   access to the buffer wraping around and overwriting the element or
+ *   changing the buffer memory entirely.
+ *   Under no circumstances might the memory pointed to by the returned
+ *   pointer be 'freed' by the user!
+ *   If this function is called on a buffer that is not yet setup,
+ *   a NULL pointer is returned instead.
+ * See also:
+ *   kiro_trb_get_element_size, kiro_trb_get_raw_buffer
+ */
+void* kiro_trb_get_element (KiroTrb* trb, uint64_t index);
+
+
+/**
+ * kiro_trb_dma_push - Gives DMA to the next element and pushes the buffer
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Returns a pointer to the next element in the buffer and increases
+ *   all internal counters and meta data as if an element was pushed
+ *   onto the buffer.
+ * Notes:
+ *   The returned pointer to the element is only guaranteed to be valid
+ *   immediately after the function call. The user is responsible to
+ *   ensure that no more data is written than 'element_size'. The
+ *   element pointed to might become invalid at any time by any concurrent
+ *   access to the buffer wraping around and overwriting the element or
+ *   changing the buffer memory entirely.
+ *   Under no circumstances might the memory pointed to by the returned
+ *   pointer be 'freed' by the user!
+ *   If this function is called on a buffer that is not yet setup,
+ *   a NULL pointer is returned instead.
+ * See also:
+ *   kiro_trb_push, kiro_trb_get_element_size, kiro_trb_get_raw_buffer
+ */
+void* kiro_trb_dma_push (KiroTrb*);
+
+
+/**
+ * kiro_trb_flush - Resets the buffer
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Resets the internal buffer structures so the buffer is
+ *   'empty' again.
+ * Notes:
+ *   The underlying memory is not cleared, freed or rewritten.
+ *   Only the header is rewritten and the internal pointer and
+ *   counter structures get reset to zero.
+ * See also:
+ *   kiro_trb_reshape, kiro_trb_adopt, kiro_trb_clone
+ */
+void kiro_trb_flush (KiroTrb* trb);
+
+
+/**
+ * kiro_trb_is_setup - Returns the setup status of the buffer
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Returns an integer designating of the buffer is ready to
+ *   be used or needs to be 'reshaped' before it can accept data
+ * Notes:
+ *   A return value of 0 designates that the buffer is not ready
+ *   to be used. Values greater than 0 designate that the buffer
+ *   is setup properly and is ready to accept data.
+ * See also:
+ *   kiro_trb_reshape, kiro_trb_adopt, kiro_trb_clone
+ */
+int kiro_trb_is_setup (KiroTrb* trb);
+
+
+/**
+ * kiro_trb_reshape - Reallocates internal memory and structures
+ * @trb: KIRO TRB to perform the operation on
+ * @element_size: Individual size of the elements to store in bytes
+ * @element_count: Maximum number of elements to be stored
+ * Description:
+ *   (Re)Allocates internal memory for the given ammount of elements
+ *   at the given individual size
+ * Notes:
+ *   If this function gets called when the buffer already has internal
+ *   memory (buffer is setup), that memory gets freed automatically.
+ *   If the function fails (Negative return value) none of the old
+ *   memory and data structures get changed.
+ * See also:
+ *   kiro_trb_is_setup, kiro_trb_reshape, kiro_trb_adopt, kiro_trb_clone
+ */
+int kiro_trb_reshape (KiroTrb* trb, uint64_t element_size, uint64_t element_count);
+
+
+/**
+ * kiro_trb_clone - Clones the given memory into the internal memory
+ * @trb: KIRO TRB to perform the operation on
+ * @source: Pointer to the source memory to clone from
+ * Description:
+ *   Interprets the given memory as a pointer to another KIRO TRB and
+ *   tries to copy that memory into its own.
+ * Notes:
+ *   The given memory is treated as a correct KIRO TRB memory block,
+ *   including a consistend memory header. That header is read and
+ *   then cloned into the internal memory according to the headers
+ *   information.
+ *   If the given memory is not a consistent KIRO TRB memory block,
+ *   the behavior of this function is undefined.
+ *   Returns 0 if the buffer was cloned and -1 if memory allocation
+ *   failed.
+ * See also:
+ *   kiro_trb_reshape, kiro_trb_adopt
+ */
+int kiro_trb_clone (KiroTrb* trb, void* source);
+
+
+/**
+ * kiro_trb_push - Adds an element into the buffer
+ * @trb: KIRO TRB to perform the operation on
+ * @source: Pointer to the memory of the element to add
+ * Description:
+ *   Copies the given element and adds it into the buffer
+ * Notes:
+ *   This function will read n-Bytes from the given address according
+ *   to the setup element_size. The read memory is copied directly
+ *   into the internal memory structure.
+ *   Returns 0 on success, -1 on failure.
+ *   In case of failure, no internal memory will change as if the
+ *   call to kiro_trb_push has never happened.
+ * See also:
+ *   kiro_trb_dma_push, kiro_trb_get_element_size, kiro_trb_clone,
+ *   kiro_trb_adopt
+ */
+int kiro_trb_push (KiroTrb* trb, void* source);
+
+
+/**
+ * kiro_trb_refresh - Re-reads the TRBs memory header
+ * @trb: KIRO TRB to perform the operation on
+ * Description:
+ *   Re-reads the internal memory header and sets up all pointers
+ *   and counters in accordance to these information
+ * Notes:
+ *   This function is used in case the TRBs memory got changed
+ *   directly (For example, by a DMA operation) to make the TRB
+ *   aware of the changes to its memory. Only the buffers memory
+ *   header is examined and changes are made according to these
+ *   informations.
+ * See also:
+ *   kiro_trb_get_raw_buffer, kiro_trb_push_dma, kiro_trb_adopt
+ */
+void kiro_trb_refresh (KiroTrb* trb);
+
+
+/**
+ * kiro_trb_adopt - Adopts the given memory into the TRB
+ * @trb: KIRO TRB to perform the operation on
+ * @source: Pointer to the source memory to adopt
+ * Description:
+ *   Interprets the given memory as a pointer to another KIRO TRB and
+ *   takes ownership over the memory.
+ * Notes:
+ *   The given memory is treated as a correct KIRO TRB memory block,
+ *   including a consistend memory header. That header is read and
+ *   the TRB sets up all internal structures in accordance to that
+ *   header.
+ *   If the given memory is not a consistent KIRO TRB memory block,
+ *   the behavior of this function is undefined.
+ *   The TRB takes full ownership of the given memory and may free
+ *   it at will.
+ * See also:
+ *   kiro_trb_clone, kiro_trb_reshape
+ */
+void kiro_trb_adopt (KiroTrb* trb, void* source);
+
+G_END_DECLS
+
+#endif //__KIRO_TRB_H
\ No newline at end of file
-- 
cgit v1.2.3