diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | kiro-client.c | 59 | ||||
| -rw-r--r-- | kiro-client.h | 3 | ||||
| -rw-r--r-- | kiro-rdma.h | 50 | ||||
| -rw-r--r-- | kiro-server.c | 272 | ||||
| -rw-r--r-- | kiro-server.h | 25 | ||||
| -rw-r--r-- | kiro-trb.h | 2 | ||||
| -rw-r--r-- | test-client.c | 14 | ||||
| -rw-r--r-- | test-server.c | 156 | 
9 files changed, 404 insertions, 179 deletions
| @@ -1,6 +1,6 @@  CC=gcc  CFLAGS=-std=c99 -Wall -g -gdwarf-2 $(shell pkg-config --cflags gobject-2.0) -LDFLAGS= -lrdmacm -libverbs -lpthread $(shell pkg-config --libs gobject-2.0) +LDFLAGS=-lm -lrdmacm -libverbs -lpthread $(shell pkg-config --libs gobject-2.0)  .PHONY : all diff --git a/kiro-client.c b/kiro-client.c index 3df870f..7c328a5 100644 --- a/kiro-client.c +++ b/kiro-client.c @@ -53,9 +53,7 @@ struct _KiroClientPrivate {      /* (Not accessible by properties) */      struct rdma_event_channel   *ec;        // Main Event Channel      struct rdma_cm_id           *conn;      // Connection to the Server -    KiroTrb                     *buffer;    // Ring Buffer used to hold data from server -  }; @@ -66,7 +64,6 @@ static void kiro_client_init (KiroClient *self)  {      KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);      memset(priv, 0, sizeof(&priv)); -    priv->buffer = g_object_new(KIRO_TYPE_TRB, NULL);  }  static void @@ -74,7 +71,7 @@ kiro_client_finalize (GObject *object)  {      KiroClient *self = KIRO_CLIENT(object);      KiroClientPrivate * priv = KIRO_CLIENT_GET_PRIVATE(self); -    g_object_unref(priv->buffer); +    //PASS  }  static void @@ -135,7 +132,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)      if(!ctx->cf_mr_recv || !ctx->cf_mr_send)      {          printf("Failed to allocate Control Flow Memory Container.\n"); -        kiro_destroy_connection_context(ctx); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } @@ -145,7 +142,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)      if(!ctx->cf_mr_recv || !ctx->cf_mr_send)      {          printf("Failed to register control message memory.\n"); -        kiro_destroy_connection_context(ctx); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } @@ -155,7 +152,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)      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); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } @@ -163,7 +160,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)      if(rdma_connect(priv->conn, NULL))      {          printf("Failed to establish connection to the server.\n"); -        kiro_destroy_connection_context(ctx); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } @@ -175,20 +172,20 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)      {          printf("Failure waiting for POST from server.\n");          rdma_disconnect(priv->conn); -        kiro_destroy_connection_context(ctx); +        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 TRB Size is: %u\n",ctx->peer_mr.length); +    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); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } @@ -208,7 +205,7 @@ int kiro_client_sync (KiroClient *self)      {          printf("Failed to read from server.\n");          rdma_disconnect(priv->conn); -        kiro_destroy_connection_context(ctx); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } @@ -218,30 +215,42 @@ int kiro_client_sync (KiroClient *self)      {          printf("Failure reading from server.\n");          rdma_disconnect(priv->conn); -        kiro_destroy_connection_context(ctx); +        kiro_destroy_connection_context(&ctx);          rdma_destroy_ep(priv->conn);          return -1;      } -    if(!kiro_trb_is_setup(priv->buffer)) -    { -        //First time setup -        kiro_trb_adopt(priv->buffer, ctx->rdma_mr->mem); -    } -    else -    { -        //Refresh -        kiro_trb_refresh(priv->buffer); -    } -     -    printf("Buffer successfully read from server.\n"); +    printf("Memory successfully read from server.\n");      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/kiro-client.h b/kiro-client.h index 61e5676..e3e60de 100644 --- a/kiro-client.h +++ b/kiro-client.h @@ -81,6 +81,9 @@ int         kiro_client_connect             (KiroClient* client, char* dest_addr  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 diff --git a/kiro-rdma.h b/kiro-rdma.h index 25040c8..696c880 100644 --- a/kiro-rdma.h +++ b/kiro-rdma.h @@ -156,20 +156,52 @@ static void kiro_destroy_rdma_memory (struct kiro_rdma_mem *krm)  } -static void kiro_destroy_connection_context (struct kiro_connection_context *ctx) +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 kiro_connection **conn) +{ +    if(!(*conn)) +        return; +     +    if(!(*conn)->id) +        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); -    if(ctx->rdma_mr) -        kiro_destroy_rdma_memory(ctx->rdma_mr); +    rdma_disconnect((*conn)->id); +    struct kiro_connection_context *ctx = (struct kiro_connection_context *)((*conn)->id->context); +    if(ctx) +        kiro_destroy_connection_context(&ctx); -    free(ctx); -    ctx = NULL; +    rdma_destroy_ep((*conn)->id); +    free(*conn); +    *conn = NULL;  } diff --git a/kiro-server.c b/kiro-server.c index 1ed47f8..c017b07 100644 --- a/kiro-server.c +++ b/kiro-server.c @@ -29,6 +29,7 @@  #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" @@ -52,8 +53,6 @@ struct _KiroServerPrivate {      struct rdma_event_channel   *ec;        // Main Event Channel      struct rdma_cm_id           *base;      // Base-Listening-Connection      struct kiro_connection      *client;    // Connection to the client -    KiroTrb                     *buffer;    // Memory Container -      }; @@ -65,23 +64,16 @@ static void kiro_server_init (KiroServer *self)  {      KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self);      memset(priv, 0, sizeof(&priv)); -     -    priv->buffer = g_object_new(KIRO_TYPE_TRB, NULL); -    kiro_trb_reshape(priv->buffer, sizeof(uint64_t), 1000); -    uint64_t a = 0xAFFED00F; -    uint64_t b = 0x1337BEEF; -    kiro_trb_push(priv->buffer, &a); -    kiro_trb_push(priv->buffer, &b);  } +  static void  kiro_server_finalize (GObject *object)  { -    KiroServer *self = KIRO_SERVER(object); -    KiroServerPrivate * priv = KIRO_SERVER_GET_PRIVATE(self); -    g_object_unref(priv->buffer); +    //PASS  } +  static void  kiro_server_class_init (KiroServerClass *klass)  { @@ -90,8 +82,103 @@ kiro_server_class_init (KiroServerClass *klass)  } +static int connect_client (struct kiro_connection *client) +{ +    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->id); +        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->id->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE); +    ctx->cf_mr_send = kiro_create_rdma_memory(client->id->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->id->context = ctx; +     +    if(rdma_post_recv(client->id, 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->id, NULL)) +    { +        printf("Failed to establish connection to the server.\n"); +        goto error; +    } +    printf("Client Connected.\n"); +    return 0; + + +error: +    rdma_reject(client->id, NULL, 0); +    kiro_destroy_connection_context(&ctx); +    rdma_destroy_id(client->id); +    return -1; +} + + +static int welcome_client (struct kiro_connection *client, void *mem, size_t mem_size) +{ +    struct kiro_connection_context *ctx = (struct kiro_connection_context *)(client->id->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->id, 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->id, 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->id, &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; +} + -int kiro_server_start (KiroServer *self, char *address, char *port) +int kiro_server_start (KiroServer *self, char *address, char *port, void* mem, size_t mem_size)  {      KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self); @@ -101,16 +188,21 @@ int kiro_server_start (KiroServer *self, char *address, char *port)          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 bind to address %s:%s\n",address, port); +        printf("Failed to create address information.");          return -1;      } -    printf("Bound to address %s:%s\n",address, port);      struct ibv_qp_init_attr qp_attr;      memset(&qp_attr, 0, sizeof(qp_attr)); @@ -128,6 +220,25 @@ int kiro_server_start (KiroServer *self, char *address, char *port)      }      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"); @@ -137,13 +248,10 @@ int kiro_server_start (KiroServer *self, char *address, char *port)      printf("Enpoint listening.\n"); -    // ---> *SNIP* -          priv->client = (struct kiro_connection *)calloc(1, sizeof(struct kiro_connection)); -    if(!priv->client) +    if(!(priv->client))      {          printf("Failed to create container for client connection.\n"); -        rdma_destroy_ep(priv->base);          return -1;      }      priv->client->identifier = 0; //First Client @@ -157,59 +265,20 @@ int kiro_server_start (KiroServer *self, char *address, char *port)      }      printf("Connection Request received.\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->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->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"); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); -        return -1; -    } -     -    ctx->cf_mr_recv = kiro_create_rdma_memory(priv->client->id->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE); -    ctx->cf_mr_send = kiro_create_rdma_memory(priv->client->id->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->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); -        return -1; -    } -    ctx->cf_mr_recv->size = ctx->cf_mr_send->size = sizeof(struct kiro_ctrl_msg); -    priv->client->id->context = ctx; -    if(rdma_post_recv(priv->client->id, priv->client, ctx->cf_mr_recv->mem, ctx->cf_mr_recv->size, ctx->cf_mr_recv->mr)) +    if(connect_client(priv->client))      { -        printf("Posting preemtive receive for connection failed.\n"); -        kiro_destroy_connection_context(ctx); +        printf("Client connection failed!\n");          rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id);          free(priv->client);          return -1;      } -    if(rdma_accept(priv->client->id, NULL)) +    if(welcome_client(priv->client, mem, mem_size))      { -        printf("Failed to establish connection to the server.\n"); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); +        printf("Failed to setup client communication.\n"); +        kiro_destroy_connection(&(priv->client)); +        rdma_destroy_id(priv->base);          return -1;      } @@ -224,88 +293,17 @@ int kiro_server_start (KiroServer *self, char *address, char *port)      if(rdma_migrate_id(priv->base, priv->ec))      {          printf("Was unable to migrate connection to new Event Channel.\n"); -        rdma_disconnect(priv->client->id); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); -        return -1; -    } -     -    printf("Client Connected.\n"); -     -         -    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"); -        rdma_disconnect(priv->client->id); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); -        return -1; -    } -     -    ctx->rdma_mr->mem = kiro_trb_get_raw_buffer(priv->buffer); -    ctx->rdma_mr->size = kiro_trb_get_raw_size(priv->buffer); -    ctx->rdma_mr->mr = rdma_reg_read(priv->client->id, ctx->rdma_mr->mem, ctx->rdma_mr->size); -    if(!ctx->rdma_mr->mr) -    { -        printf("Failed to register RDMA Memory Region.\n"); -        rdma_disconnect(priv->client->id); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); -        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(priv->client->id, priv->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"); -        rdma_disconnect(priv->client->id); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); +        kiro_destroy_connection(&(priv->client)); +        rdma_destroy_id(priv->base);          return -1;      } -    struct ibv_wc wc; -     -    if(rdma_get_send_comp(priv->client->id, &wc) < 0) -    { -        printf("Failed to post RDMA MRI to client.\n"); -        rdma_disconnect(priv->client->id); -        kiro_destroy_connection_context(ctx); -        rdma_destroy_ep(priv->base); -        rdma_destroy_ep(priv->client->id); -        free(priv->client); -        return -1; -    } -    printf("RDMA MRI sent to client.\n");      sleep(1);      return 0;  } -int kiro_server_sync (KiroServer *self) -{ -    //PASS -    return 0; -} - - - - - - diff --git a/kiro-server.h b/kiro-server.h index 1d85419..cb9b57c 100644 --- a/kiro-server.h +++ b/kiro-server.h @@ -76,7 +76,30 @@ GObject     kiro_server_new                 (void);  /* server functions */ -int         kiro_server_start               (KiroServer* server, char* bind_addr, char* bind_port); +/** + * 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 @@ -282,7 +282,7 @@ int kiro_trb_clone (KiroTrb* trb, void* source);   *   In case of failure, no internal memory will change as if the   *   call to kiro_trb_push has never happened.   * See also: - *   kiro_trb_push_dma, kiro_trb_get_element_size, kiro_trb_clone, + *   kiro_trb_dma_push, kiro_trb_get_element_size, kiro_trb_clone,   *   kiro_trb_adopt   */  int kiro_trb_push (KiroTrb* trb, void* source); diff --git a/test-client.c b/test-client.c index 0a318f1..5c78d42 100644 --- a/test-client.c +++ b/test-client.c @@ -4,10 +4,16 @@  #include "kiro-client.h" -int main(void) +int main ( int argc, char *argv[] )  { +    if (argc < 3) +    { +        printf("Not enough aruments. Usage: ./client <address> <port>\n"); +        return -1; +    }      KiroClient *client = g_object_new(KIRO_TYPE_CLIENT, NULL); -    kiro_client_connect(client, "192.168.11.61", "60010"); -    kiro_client_sync(client); -    return 0;  +    if(-1 != kiro_client_connect(client, argv[1], argv[2])) +        kiro_client_sync(client); +    g_object_unref(client); +    return 0;  }
\ No newline at end of file diff --git a/test-server.c b/test-server.c index 2b08f15..1becb31 100644 --- a/test-server.c +++ b/test-server.c @@ -2,11 +2,165 @@  #include <stdio.h>  #include <stdlib.h>  #include "kiro-server.h" +#include "kiro-trb.h" +#include <gmodule.h> +#include <gio/gio.h> +#include <string.h> +#include <math.h> + + + +static const char g_digits[10][20] = { +    /* 0 */ +    { 0x00, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0xff, 0x00, 0x00, 0xff, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0xff, 0xff, 0x00 }, +    /* 1 */ +    { 0x00, 0x00, 0xff, 0x00, +      0x00, 0xff, 0xff, 0x00, +      0x00, 0x00, 0xff, 0x00, +      0x00, 0x00, 0xff, 0x00, +      0x00, 0x00, 0xff, 0x00 }, +    /* 2 */ +    { 0x00, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0x00, 0xff, 0x00, +      0x00, 0xff, 0x00, 0x00, +      0xff, 0xff, 0xff, 0xff }, +    /* 3 */ +    { 0x00, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0x00, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0xff, 0xff, 0x00 }, +    /* 4 */ +    { 0xff, 0x00, 0x00, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0xff, 0xff, 0xff, 0xff, +      0x00, 0x00, 0x00, 0xff, +      0x00, 0x00, 0x00, 0xff }, +    /* 5 */ +    { 0xff, 0xff, 0xff, 0xff, +      0xff, 0x00, 0x00, 0x00, +      0x00, 0xff, 0xff, 0x00, +      0x00, 0x00, 0x00, 0xff, +      0xff, 0xff, 0xff, 0x00 }, +    /* 6 */ +    { 0x00, 0xff, 0xff, 0xff, +      0xff, 0x00, 0x00, 0x00, +      0xff, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0xff, 0xff, 0x00 }, +    /* 7 */ +    { 0xff, 0xff, 0xff, 0xff, +      0x00, 0x00, 0x00, 0xff, +      0x00, 0x00, 0xff, 0x00, +      0x00, 0xff, 0x00, 0x00, +      0xff, 0x00, 0x00, 0x00 }, +    /* 8 */ +    { 0x00, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0xff, 0xff, 0x00 }, +    /* 9 */ +    { 0x00, 0xff, 0xff, 0x00, +      0xff, 0x00, 0x00, 0xff, +      0x00, 0xff, 0xff, 0xff, +      0x00, 0x00, 0x00, 0xff, +      0xff, 0xff, 0xff, 0x00 } +}; + +static const guint DIGIT_WIDTH = 4; +static const guint DIGIT_HEIGHT = 5; + +static void +print_number (gchar *buffer, guint number, guint x, guint y, guint width) +{ +    for (int i = 0; i < DIGIT_WIDTH; i++) { +        for (int j = 0; j < DIGIT_HEIGHT; j++) { +            char val = (char) g_digits[number][j*DIGIT_WIDTH+i]; +            if(val != 0x00) { +                //This should make the frame counter appear in a bright yellow +                val = 0xBE; +            } +            buffer[(y+j)*width + (x+i)] = (guint8) val; +        } +    } +} + +static void +print_current_frame (gchar *buffer, guint number, guint width, guint height, GRand *rand) +{ +    guint divisor = 10000000; +    int x = 1; + +    while (divisor > 0) { +        print_number(buffer, number / divisor, x, 1, width); +        number = number % divisor; +        divisor = divisor / 10; +        x += DIGIT_WIDTH + 1; +    } + + +    //Rainbow pattern is the same for every row. Just calculate one single +    //Scanline, so we can reuse it and dont have to do the whole calculation +    //for every row again. +    char default_line[width]; +    for (int p = 0; p < width; p++) { +        default_line[p] = (char) ((p*256) / (width)); +    } + + +    //Use memcpy to quickly fill every row with the precalculated rainbow +    //pattern +    for (guint y = 16; y < height; y++) { +        guint index = y * width; +        memcpy(&buffer[index], &default_line[0], width); +    } + +    //This block will fill a square at the center of the image with normal +    //distributed random data +    const double mean = 128.0; +    const double std = 32.0; + +    for (guint y = (height/3); y < ((height*2)/3); y++) { +        guint row_start = y * width; +        for (guint i = (width/3); i < ((width*2)/3); i++) { +            int index = row_start + i; +            double u1 = g_rand_double(rand); +            double u2 = g_rand_double(rand); +            double r = sqrt(-2 * log(u1)) * cos(2 * G_PI * u2); +            buffer[index] = (guint8) (r * std + mean); +        } +    } +}  int main(void)  {      KiroServer *server = g_object_new(KIRO_TYPE_SERVER, NULL); -    kiro_server_start(server, "192.168.11.61", "60010"); +    KiroTrb *rb = g_object_new(KIRO_TYPE_TRB, NULL); +    kiro_trb_reshape(rb, 512*512, 1000); +    GRand *rand = g_rand_new(); +    if(0 > kiro_server_start(server, NULL, "60010", kiro_trb_get_raw_buffer(rb), kiro_trb_get_raw_size(rb))) +    { +        printf("Failed to start server properly.\n"); +        goto done; +    } + +    guint frame = 0; +    while(1) +    { +        print_current_frame(kiro_trb_dma_push(rb), frame, 512, 512, rand); +        frame++; +    } +     +done: +    g_rand_free(rand); +    g_object_unref(rb); +      return 0;   }
\ No newline at end of file | 
