summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/common/tests/tests8
-rw-r--r--cesar/host/sci/cesar/Module1
-rw-r--r--cesar/host/sci/cesar/inc/context.h43
-rw-r--r--cesar/host/sci/cesar/inc/sci.h42
-rw-r--r--cesar/host/sci/cesar/inc/sci_msg.h22
-rw-r--r--cesar/host/sci/cesar/src/sci.c207
-rw-r--r--cesar/host/sci/cesar/test/Config1
-rw-r--r--cesar/host/sci/cesar/test/Makefile8
-rw-r--r--cesar/host/sci/cesar/test/src/test_sci_cesar.c337
-rw-r--r--cesar/host/sci/inc/sci_msg.h52
-rw-r--r--cesar/host/sci/maximus/Module2
-rw-r--r--cesar/host/sci/maximus/inc/context.h36
-rw-r--r--cesar/host/sci/maximus/inc/sci_msg.h22
-rw-r--r--cesar/host/sci/maximus/src/sci.c23
-rw-r--r--cesar/host/sci/sci.h120
-rw-r--r--cesar/host/sci/src/sci_msg.c (renamed from cesar/host/sci/maximus/src/sci_msg.c)23
-rw-r--r--cesar/host/test/Makefile2
-rw-r--r--cesar/host/test/src/test_host.c3
-rw-r--r--cesar/host/test/src/test_sci.c55
-rw-r--r--cesar/host/test/src/test_sci_msg.c45
-rw-r--r--cesar/interface/Module2
-rw-r--r--cesar/interface/fcall/Module2
-rw-r--r--cesar/interface/fcall/inc/context.h30
-rw-r--r--cesar/interface/fcall/inc/interface_fcall.h26
-rw-r--r--cesar/interface/fcall/interface_fcall.h44
-rw-r--r--cesar/interface/fcall/src/interface_fcall.c148
-rw-r--r--cesar/interface/fcall/test/Config2
-rw-r--r--cesar/interface/fcall/test/Makefile8
-rw-r--r--cesar/interface/fcall/test/src/test_interface_fcall.c292
-rw-r--r--cesar/interface/forward.h19
-rw-r--r--cesar/interface/interface.h4
-rwxr-xr-xcesar/maximus/test/test.sh14
32 files changed, 1343 insertions, 300 deletions
diff --git a/cesar/common/tests/tests b/cesar/common/tests/tests
index b186a35328..79f9b75e7f 100644
--- a/cesar/common/tests/tests
+++ b/cesar/common/tests/tests
@@ -292,6 +292,14 @@ host/test:
make: make COV=y
./obj/test_host
+host/sci/cesar/test:
+make: make COV=y
+./obj/test_sci_cesar
+
+interface/fcall/test:
+make: make COV=y
+./obj/test_interface_fcall
+
hal/phy/test/bridgedma-proto/:
make: make synth
bridgedma-proto-proto: ./obj/synth/test-bridgedma-proto.elf
diff --git a/cesar/host/sci/cesar/Module b/cesar/host/sci/cesar/Module
index e69de29bb2..2cedb3682d 100644
--- a/cesar/host/sci/cesar/Module
+++ b/cesar/host/sci/cesar/Module
@@ -0,0 +1 @@
+SOURCES := sci.c ../../src/sci_msg.c \ No newline at end of file
diff --git a/cesar/host/sci/cesar/inc/context.h b/cesar/host/sci/cesar/inc/context.h
new file mode 100644
index 0000000000..fd0e9e13b0
--- /dev/null
+++ b/cesar/host/sci/cesar/inc/context.h
@@ -0,0 +1,43 @@
+#ifndef host_sci_cesar_inc_context_h
+#define host_sci_cesar_inc_context_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+ /**
+ * \file context.h
+ * \brief The sci comm. layer context structure for Gidel prototype.
+ * \ingroup host/sci/cesar
+ *
+ * This file descibe the content of sci context structure used by Gidel prototype sci layer
+ *
+ * \todo
+ */
+
+/** sci callback structure */
+struct sci_callback
+{
+ int (*function)(struct sci_msg *msg, void *data);
+ void *data;
+};
+
+/** send callback structure */
+struct send_callback
+{
+ void (*function)(void *ctx, u8 *mme, uint length);
+ void *data;
+};
+
+/** sci layer context */
+struct sci_ctx {
+ struct station_ctx *station; /** = NULL */
+ struct sci_callback msg_callback; /** sci callback function */
+ struct send_callback send_cb; /** send callback function */
+};
+
+#endif /* host_sci_cesar_inc_context_h */
diff --git a/cesar/host/sci/cesar/inc/sci.h b/cesar/host/sci/cesar/inc/sci.h
new file mode 100644
index 0000000000..31e1bc1f02
--- /dev/null
+++ b/cesar/host/sci/cesar/inc/sci.h
@@ -0,0 +1,42 @@
+#ifndef host_sci_cesar_inc_sci_h
+#define host_sci_cesar_inc_sci_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+ /**
+ * \file sci.h
+ * \brief The sci comm. layer structures for Gidel prototype.
+ * \ingroup host/sci/cesar
+ *
+ * This file descibe the content of sci structures used by Gidel prototype sci layer
+ *
+ * \todo
+ */
+
+/**
+ * register a send callback function to send a message
+ * \param sci current sci context
+ * \param function pointer to the callback function to send a message
+ * \param data user data to be included into callback function as 'data' parameter
+ * \return 0 if ok, -1 if failed
+ */
+int sci_register_send_callback(
+ sci_ctx_t *sci,
+ void(*function)(void *data, u8 *mme, uint length),
+ void *data);
+
+/**
+ * receive a sci message from interface fcall module and process the registered callback
+ * \param sci current sci context
+ * \param msg sci message
+ * \return 0 if ok, -1 if failed
+ */
+int sci_recv_msg(sci_ctx_t *sci, sci_msg_t *msg);
+
+#endif /* host_sci_cesar_inc_sci_h */
diff --git a/cesar/host/sci/cesar/inc/sci_msg.h b/cesar/host/sci/cesar/inc/sci_msg.h
deleted file mode 100644
index 64ea6c1c86..0000000000
--- a/cesar/host/sci/cesar/inc/sci_msg.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef host_sci_cesar_inc_sci_msg_h
-#define host_sci_cesar_inc_sci_msg_h
-
-/* Cesar project {{{
- *
- * Copyright (C) 2007 Spidcom
- *
- * <<<Licence>>>
- *
- * }}} */
-
- /**
- * \file sci_msg.h
- * \brief The sci comm. layer messages structures for Gidel prototype.
- * \ingroup host/sci/cesar
- *
- * This file descibe the content of sci messages structures used by Gidel prototype sci layer
- *
- * \todo
- */
-
-#endif /* host_sci_cesar_inc_sci_msg_h */
diff --git a/cesar/host/sci/cesar/src/sci.c b/cesar/host/sci/cesar/src/sci.c
new file mode 100644
index 0000000000..49888a9fab
--- /dev/null
+++ b/cesar/host/sci/cesar/src/sci.c
@@ -0,0 +1,207 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+/**
+ * \file sci.c
+ * \brief The sci communication functions
+ * \ingroup host/sci/cesar
+ *
+ * This file provide sci communication functions
+ *
+ * \todo
+ */
+#include "common/std.h"
+#include "host/sci/sci.h"
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#ifndef UNIT_TEST
+#include "host/syscall.h"
+#include "lib/swap.h"
+#else /* UNIT_TEST */
+#include <unistd.h>
+#include <arpa/inet.h>
+#endif /* UNIT_TEST */
+
+/**
+ * initialize a static sci context, called during interface fcall context creation.
+ * \param sci sci context to initialize
+ * \param station must be set to NULL
+ * \return 0 if ok, -1 if failed with errno=
+ * - EINVAL if sci is NULL or if station is not NULL
+ */
+int sci_init(sci_ctx_t *sci, station_ctx_t *station)
+{
+ DBG_ASSERT(sci);
+ DBG_ASSERT(!station);
+ if((sci == NULL)
+ || (station != NULL))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* init structure */
+ memset(sci, '\0', sizeof(sci_ctx_t));
+
+ return 0;
+}
+
+/**
+ * register a callback function to process a message
+ * \param sci current sci context
+ * \param type must be set to 0
+ * \param function pointer to the callback function to process the received message
+ * \param data user data to be included into callback function as 'data' parameter,
+ * must be a pointer to the interface fcall context
+ * \return 0 if ok, -1 if failed with errno:
+ * - EINVAL if sci is null or type is not 0
+ */
+int sci_register_callback(
+ sci_ctx_t *sci,
+ sci_msg_type_t type,
+ int(*function)(sci_msg_t *msg, void *data),
+ void *data)
+{
+ DBG_ASSERT(sci);
+ DBG_ASSERT(type == SCI_MSG_TYPE_FUNCTION_CALL);
+ DBG_ASSERT(function);
+ if((sci == NULL)
+ || (type != SCI_MSG_TYPE_FUNCTION_CALL)
+ || (function == NULL))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ sci->msg_callback.function = function;
+ sci->msg_callback.data = data;
+
+ return 0;
+}
+
+/**
+ * this function is not used on Gidel prototype
+ * \param sci current sci context
+ * \param msg sci message to fill header
+ * \param type type of message
+ * \param flags flags of message
+ * \return -1 with errno:
+ * - ENOSYS
+ */
+int sci_fill_hdr(
+ sci_ctx_t *sci,
+ sci_msg_t *msg,
+ sci_msg_type_t type,
+ int flags)
+{
+ DBG_ASSERT(sci);
+ DBG_ASSERT(msg);
+ DBG_ASSERT(type == SCI_MSG_TYPE_FUNCTION_CALL);
+ if((sci == NULL)
+ || (msg == NULL)
+ || (type != SCI_MSG_TYPE_FUNCTION_CALL))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * sends a sci message to the interface fcall module
+ * \param sci current sci context
+ * \param msg sci message to send to the HLE
+ * \return length of sent data, -1 if failed with errno:
+ * - EINVAL if sci or msg are NULL
+ */
+int sci_send(sci_ctx_t *sci, sci_msg_t *msg)
+{
+ DBG_ASSERT(sci);
+ DBG_ASSERT(msg);
+ if((sci == NULL)
+ || (msg == NULL))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(sci->send_cb.function != NULL)
+ {
+ (*sci->send_cb.function)(sci->send_cb.data, msg->data_begin, msg->length);
+ }
+
+ return msg->length;
+}
+
+/**
+ * receive a sci message from interface fcall and process the registered host fcall callback
+ * \param sci current sci context
+ * \return 0 if ok, -1 if failed with errno:
+ * - EINVAL if sci is NULL
+ * - ENOSPC if msg length is > SCI_MSG_MAX_SIZE
+ */
+int sci_recv(sci_ctx_t *sci)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+/**
+ * register a send callback function to send a message
+ * \param sci current sci context
+ * \param function pointer to the callback function to send a message
+ * \param data user data to be included into callback function as 'data' parameter
+ * \return 0 if ok, -1 if failed
+ */
+int sci_register_send_callback(
+ sci_ctx_t *sci,
+ void(*function)(void *data, u8 *mme, uint length),
+ void *data)
+{
+ DBG_ASSERT(sci);
+ DBG_ASSERT(function);
+ if((sci == NULL)
+ || (function == NULL))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ sci->send_cb.function = function;
+ sci->send_cb.data = data;
+
+ return 0;
+}
+
+/**
+ * receive a sci message from interface fcall module and process the registered callback
+ * \param sci current sci context
+ * \param msg sci message
+ * \return 0 if ok, -1 if failed
+ */
+int sci_recv_msg(sci_ctx_t *sci, sci_msg_t *msg)
+{
+ DBG_ASSERT(sci);
+ DBG_ASSERT(msg);
+ if((sci == NULL)
+ || (msg == NULL))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* call the callback function */
+ if(sci->msg_callback.function != NULL)
+ {
+ return (*sci->msg_callback.function)(msg, sci->msg_callback.data);
+ }
+
+ return 0;
+}
diff --git a/cesar/host/sci/cesar/test/Config b/cesar/host/sci/cesar/test/Config
new file mode 100644
index 0000000000..2b84e7da6b
--- /dev/null
+++ b/cesar/host/sci/cesar/test/Config
@@ -0,0 +1 @@
+CONFIG_HOST_ASSERT = y \ No newline at end of file
diff --git a/cesar/host/sci/cesar/test/Makefile b/cesar/host/sci/cesar/test/Makefile
new file mode 100644
index 0000000000..283f414794
--- /dev/null
+++ b/cesar/host/sci/cesar/test/Makefile
@@ -0,0 +1,8 @@
+BASE = ../../../..
+EXTRA_HOST_CFLAGS+= -DUNIT_TEST
+EXTRA_HOST_CFLAGS+= -DSPARC_TEST
+HOST_PROGRAMS = test_sci_cesar
+test_sci_cesar_SOURCES = test_sci_cesar.c
+test_sci_cesar_MODULES = lib host/sci/cesar host/fcall host/netclock host/station host/system
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/host/sci/cesar/test/src/test_sci_cesar.c b/cesar/host/sci/cesar/test/src/test_sci_cesar.c
new file mode 100644
index 0000000000..db8c820af0
--- /dev/null
+++ b/cesar/host/sci/cesar/test/src/test_sci_cesar.c
@@ -0,0 +1,337 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file test_sci_cesar.c
+ * \brief Test the Gidel prototype host sci layer
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "host/sci/sci.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <errno.h>
+
+#define TEST_DATA_STR "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define TEST_RECV_STR "test_recv"
+
+u32 maximus_pending_isrs;
+
+static int _sci_callback(sci_msg_t *msg, void *data)
+{
+ dbg_assert_print((NULL != msg)
+ && (NULL == data)
+ && (strlen(TEST_RECV_STR) == msg->length)
+ && (0 == memcmp(msg->data_begin, TEST_RECV_STR, msg->length)),
+ "registered recv function: expected len = %d - len = %d",
+ strlen(TEST_RECV_STR),
+ msg->length);
+ return 0;
+}
+
+static void _send_callback(void *ctx, u8 *mme, uint length)
+{
+ dbg_assert_print((NULL == ctx)
+ && (NULL != mme)
+ && (strlen(TEST_DATA_STR) == length)
+ && (0 == memcmp(mme, TEST_DATA_STR, length)),
+ "registered send function: expected len = %d - len = %d",
+ strlen(TEST_DATA_STR),
+ length);
+}
+
+void sci_init_test_case(test_t t)
+{
+ sci_ctx_t sci;
+ station_ctx_t station;
+
+ test_case_begin(t, "init");
+
+ test_begin(t, "NULL sci")
+ {
+ test_fail_unless(
+ (sci_init(NULL, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "not NULL station")
+ {
+ test_fail_unless(
+ (sci_init(&sci, &station) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "check init call")
+ {
+ test_fail_unless(
+ (sci_init(&sci, NULL) >= 0)
+ && (errno != EINVAL)
+ );
+ } test_end;
+}
+
+void sci_register_callback_test_case(test_t t)
+{
+ sci_ctx_t sci;
+
+ test_case_begin(t, "register_callback");
+
+ sci_init(&sci, NULL);
+
+ test_begin(t, "sci = NULL")
+ {
+ test_fail_unless(
+ (sci_register_callback(NULL, 0, NULL, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "bad type = SCI_MSG_TYPE_NONE")
+ {
+ test_fail_unless(
+ (sci_register_callback(&sci, SCI_MSG_TYPE_NONE, NULL, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "registering NULL function")
+ {
+ test_fail_unless(
+ (sci_register_callback(&sci, SCI_MSG_TYPE_FUNCTION_CALL, NULL, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "registering test function")
+ {
+ test_fail_unless(
+ (sci_register_callback(&sci, SCI_MSG_TYPE_FUNCTION_CALL, _sci_callback, NULL) >= 0)
+ && (errno != EINVAL)
+ && (sci.msg_callback.function == _sci_callback)
+ && (sci.msg_callback.data == NULL));
+ } test_end;
+}
+
+void sci_register_send_callback_test_case(test_t t)
+{
+ sci_ctx_t sci;
+
+ test_case_begin(t, "register send callback");
+
+ sci_init(&sci, NULL);
+
+ test_begin(t, "sci = NULL")
+ {
+ test_fail_unless(
+ (sci_register_send_callback(NULL, &_send_callback, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "registering NULL function")
+ {
+ test_fail_unless(
+ (sci_register_send_callback(&sci, NULL, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "registering test function")
+ {
+ test_fail_unless(
+ (sci_register_send_callback(&sci, &_send_callback, NULL) >= 0)
+ && (errno != EINVAL)
+ && (sci.send_cb.function == _send_callback)
+ && (sci.send_cb.data == NULL));
+ } test_end;
+}
+
+void sci_fill_hdr_test_case(test_t t)
+{
+ sci_ctx_t sci;
+ sci_msg_t msg;
+
+ test_case_begin(t, "fill hdr");
+
+ sci_init(&sci, NULL);
+
+ test_begin(t, "check fill hdr")
+ {
+ test_fail_unless(
+ (sci_fill_hdr(&sci, &msg, SCI_MSG_TYPE_FUNCTION_CALL, 0) >= 0)
+ && (errno != EINVAL)
+ );
+ } test_end;
+}
+
+void sci_send_test_case(test_t t)
+{
+ sci_ctx_t sci;
+ unsigned char msg_buffer[256];
+ sci_msg_t msg;
+
+ test_case_begin(t, "send");
+
+ test_begin(t, "init msg")
+ {
+ test_fail_unless(
+ (0 == sci_msg_init(&msg, msg_buffer, 256))
+ && (EINVAL != errno)
+ );
+ } test_end;
+
+ sci_init(&sci, NULL);
+
+ test_begin(t, "sci = NULL")
+ {
+ test_fail_unless(
+ (sci_send(NULL, &msg) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "msg = NULL")
+ {
+ test_fail_unless(
+ (sci_send(&sci, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "check send")
+ {
+ test_fail_unless(
+ ((int)strlen(TEST_DATA_STR) == sci_msg_push(&msg, strlen(TEST_DATA_STR)))
+ && (EINVAL != errno)
+ && (ENOSPC != errno)
+ );
+ memcpy(msg.data_begin, TEST_DATA_STR, msg.length);
+ test_fail_unless(
+ (sci_register_send_callback(&sci, &_send_callback, NULL) >= 0)
+ && (sci_send(&sci, &msg) == msg.length)
+ && (errno != EINVAL)
+ );
+ } test_end;
+}
+
+void sci_recv_test_case(test_t t)
+{
+ sci_ctx_t sci;
+
+ test_case_begin(t, "recv");
+
+ sci_init(&sci, NULL);
+
+ test_begin(t, "check recv")
+ {
+ test_fail_unless(
+ (sci_recv(&sci) < 0)
+ && (errno == ENOSYS)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+}
+
+void sci_recv_msg_test_case(test_t t)
+{
+ sci_ctx_t sci;
+ unsigned char msg_buffer[256];
+ sci_msg_t msg;
+
+ test_case_begin(t, "recv msg");
+
+ test_begin(t, "init msg")
+ {
+ test_fail_unless(
+ (0 == sci_msg_init(&msg, msg_buffer, 256))
+ && (EINVAL != errno)
+ );
+ } test_end;
+
+ sci_init(&sci, NULL);
+
+ test_begin(t, "sci = NULL")
+ {
+ test_fail_unless(
+ (sci_recv_msg(NULL, &msg) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "msg = NULL")
+ {
+ test_fail_unless(
+ (sci_recv_msg(&sci, NULL) < 0)
+ && (errno == EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+
+ test_begin(t, "check recv msg")
+ {
+ test_fail_unless(
+ ((int)strlen(TEST_RECV_STR) == sci_msg_push(&msg, strlen(TEST_RECV_STR)))
+ && (EINVAL != errno)
+ && (ENOSPC != errno)
+ );
+ memcpy(msg.data_begin, TEST_RECV_STR, msg.length);
+ test_fail_unless(
+ (sci_register_callback(&sci, SCI_MSG_TYPE_FUNCTION_CALL, &_sci_callback, NULL) >= 0)
+ && (sci_recv_msg(&sci, &msg) >= 0)
+ && (errno != EINVAL)
+ );
+ // reset errno
+ errno = 0;
+ } test_end;
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init(t, argc, argv);
+
+ sci_init_test_case(t);
+ sci_register_callback_test_case(t);
+ sci_register_send_callback_test_case(t);
+ sci_fill_hdr_test_case(t);
+ sci_send_test_case(t);
+ sci_recv_test_case(t);
+ sci_recv_msg_test_case(t);
+
+ test_result(t);
+ return test_nb_failed(t) == 0 ? 0 : 1;
+}
diff --git a/cesar/host/sci/inc/sci_msg.h b/cesar/host/sci/inc/sci_msg.h
new file mode 100644
index 0000000000..1fdd4aa70c
--- /dev/null
+++ b/cesar/host/sci/inc/sci_msg.h
@@ -0,0 +1,52 @@
+#ifndef host_sci_maximus_inc_sci_msg_h
+#define host_sci_maximus_inc_sci_msg_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+ /**
+ * \file sci_msg.h
+ * \brief The sci comm. layer messages structures for fulminata.
+ * \ingroup host/sci/maximus
+ *
+ * This file descibe the content of sci messages structures used by fulminata sci layer
+ *
+ * \todo
+ */
+
+struct station_ctx;
+struct netclock_msg_hdr;
+struct fcall_msg_hdr;
+struct station_msg_hdr;
+struct phy_msg_hdr;
+struct ether_msg_hdr;
+
+/** common sci message header */
+#define sci_msg_hdr Sci_Msg_Header
+typedef struct sci_msg_hdr sci_msg_hdr_t;
+
+/** sci buffer structure */
+struct sci_msg
+{
+ struct sci_msg_hdr *sci_hdr; /** pointer to sci header */
+ union {
+ struct netclock_msg_hdr *netclock;
+ struct fcall_msg_hdr *fcall;
+ struct station_msg_hdr *station;
+ struct phy_msg_hdr *phy;
+ struct ether_msg_hdr *ether;
+ void *generic;
+ } hdr; /** pointer to msg subtype header */
+ unsigned char *data; /** data buffer */
+ unsigned char *data_begin; /** start of payload inside buffer */
+ unsigned char *data_end; /** end of payload */
+ int length; /** total length msg */
+ int max_size; /** maximum size of data buffer */
+};
+
+#endif /* host_sci_maximus_inc_sci_msg_h */
diff --git a/cesar/host/sci/maximus/Module b/cesar/host/sci/maximus/Module
index 0da4e6247e..f74edffdfb 100644
--- a/cesar/host/sci/maximus/Module
+++ b/cesar/host/sci/maximus/Module
@@ -1 +1 @@
-SOURCES := sci.c sci_msg.c socketcalls.c \ No newline at end of file
+SOURCES := sci.c ../../src/sci_msg.c socketcalls.c
diff --git a/cesar/host/sci/maximus/inc/context.h b/cesar/host/sci/maximus/inc/context.h
new file mode 100644
index 0000000000..3ba402eb63
--- /dev/null
+++ b/cesar/host/sci/maximus/inc/context.h
@@ -0,0 +1,36 @@
+#ifndef host_sci_maximus_inc_context_h
+#define host_sci_maximus_inc_context_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+ /**
+ * \file context.h
+ * \brief The sci comm. layer context structure for fulminata.
+ * \ingroup host/sci/maximus
+ *
+ * This file descibe the content of sci context structure used by fulminata sci layer
+ *
+ * \todo
+ */
+
+/** sci callback structure */
+struct sci_callback
+{
+ int (*function)(struct sci_msg *msg, void *data);
+ void *data;
+};
+
+/** sci layer context */
+struct sci_ctx {
+ struct station_ctx *station; /** currently used station context */
+ struct sci_callback msg_callback[SCI_MSG_TYPE_NB]; /** table of all callback functions */
+ int current_msg_id;
+};
+
+#endif /* host_sci_maximus_inc_context_h */
diff --git a/cesar/host/sci/maximus/inc/sci_msg.h b/cesar/host/sci/maximus/inc/sci_msg.h
deleted file mode 100644
index d8bfc28a25..0000000000
--- a/cesar/host/sci/maximus/inc/sci_msg.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef host_sci_maximus_inc_sci_msg_h
-#define host_sci_maximus_inc_sci_msg_h
-
-/* Cesar project {{{
- *
- * Copyright (C) 2007 Spidcom
- *
- * <<<Licence>>>
- *
- * }}} */
-
- /**
- * \file sci_msg.h
- * \brief The sci comm. layer messages structures for fulminata.
- * \ingroup host/sci/maximus
- *
- * This file descibe the content of sci messages structures used by fulminata sci layer
- *
- * \todo
- */
-
-#endif /* host_sci_maximus_inc_sci_msg_h */
diff --git a/cesar/host/sci/maximus/src/sci.c b/cesar/host/sci/maximus/src/sci.c
index b61f16a674..fbb6452ea8 100644
--- a/cesar/host/sci/maximus/src/sci.c
+++ b/cesar/host/sci/maximus/src/sci.c
@@ -30,19 +30,6 @@
#endif /* UNIT_TEST */
/**
- * sci context, called during station context creation.
- * \param station station which uses the sci context
- * \return the new sci context, NULL if station is NULL
- */
-sci_ctx_t *sci_new(station_ctx_t *station)
-{
- //sci_ctx_t *sci;
- /* maybe will not be implemented */
-
- return NULL;
-}
-
-/**
* initialize a static sci context, called during station context creation.
* \param sci sci context to initialize
* \param station station which uses the sci context
@@ -66,16 +53,6 @@ int sci_init(sci_ctx_t *sci, station_ctx_t *station)
return 0;
}
-
-/**
- * sci context destruction with memory freeing.
- * \param sci sci context to destroy
- */
-void sci_free(sci_ctx_t *sci)
-{
- /* maybe will not be implemented */
- return;
-}
/**
* register a callback function to process a message
diff --git a/cesar/host/sci/sci.h b/cesar/host/sci/sci.h
index 9bd35bcc2c..00db7db59b 100644
--- a/cesar/host/sci/sci.h
+++ b/cesar/host/sci/sci.h
@@ -25,17 +25,19 @@
#include "host/netclock/netclock.h"
#include "host/fcall/fcall.h"
#include "host/system/system.h"
+#include "host/sci/inc/sci_msg.h"
-struct station_ctx;
-struct netclock_msg_hdr;
-struct fcall_msg_hdr;
-struct station_msg_hdr;
-struct phy_msg_hdr;
-struct ether_msg_hdr;
+#ifdef SPARC_TEST
+#define __sparc__
+#endif /* SPARC_TEST */
-/** common sci message header */
-#define sci_msg_hdr Sci_Msg_Header
-typedef struct sci_msg_hdr sci_msg_hdr_t;
+#ifndef __sparc__
+#include "host/sci/maximus/inc/context.h"
+
+#else /* __sparc__ */
+#include "host/sci/cesar/inc/context.h"
+#include "host/sci/cesar/inc/sci.h"
+#endif /* __sparc__ */
/** type of sci message; used by sci msg header */
typedef enum Sci_Msg_Type sci_msg_type_t;
@@ -43,68 +45,12 @@ typedef enum Sci_Msg_Type sci_msg_type_t;
/** sci message ID */
typedef int sci_msg_id_t;
-/** sci buffer structure */
-struct sci_msg
-{
- struct sci_msg_hdr *sci_hdr; /** pointer to sci header */
- union {
- struct netclock_msg_hdr *netclock;
- struct fcall_msg_hdr *fcall;
- struct station_msg_hdr *station;
- struct phy_msg_hdr *phy;
- struct ether_msg_hdr *ether;
- void *generic;
- } hdr; /** pointer to msg subtype header */
- unsigned char *data; /** data buffer */
- unsigned char *data_begin; /** start of payload inside buffer */
- unsigned char *data_end; /** end of payload */
- int length; /** total length msg */
- int max_size; /** maximum size of data buffer */
-};
-
-//#define netclock_hdr s1._netclock_hdr
-//#define fcall_hdr s1._fcall_hdr
-//#define station_hdr s1._station_hdr
-//#define generic_hdr s1._generic_hdr
-
-
-/** sci callback structure */
-struct sci_callback
-{
- int (*function)(struct sci_msg *msg, void *data);
- void *data;
-};
-
-/** sci layer context */
-struct sci_ctx {
- struct station_ctx *station; /** currently used station context */
- struct sci_callback msg_callback[SCI_MSG_TYPE_NB]; /** table of all callback functions */
- int current_msg_id;
-};
-
-//BEGIN_DECLS
-
-/**
- * create a new sci message.
- * \param size max size of message
- * \return the new sci msg, NULL if failed, with errno
- * - EINVAL is size < sizeof(sci_msg_hdr_t) or > SCI_MSG_MAX_SIZE
- */
-sci_msg_t *sci_msg_new(int max_size);
-
-/**
- * sci message destruction with memory freeing.
- * \param msg msg context to destroy
- */
-void sci_msg_free(sci_msg_t *msg);
-
/**
* sci message init if a static msg structure is used (instead of dynamic).
* \param msg pointer to msg context to initialize
* \param buffer pointer to a data buffer with allocated space
* \param max_size buffer max size
- * \return 0 if ok, -1 if failed with errno=
- * - EINVAL if msg of buffer is NULL, or if size is < sizeof(sci_msg_hdr_t) or >= SCI_MSG_MAX_SIZE
+ * \return 0 if ok, -1 if failed
*/
int sci_msg_init(sci_msg_t *msg, unsigned char *buffer, int max_size);
@@ -112,9 +58,7 @@ int sci_msg_init(sci_msg_t *msg, unsigned char *buffer, int max_size);
* sci message adding of new data with pointers update.
* \param msg msg where to add data
* \param length length of data to add
- * \return length if ok, -1 if failed with errno=
- * - EINVAL if msg is NULL
- * - ENOSPC if length is bigger than free space into buffer
+ * \return length if ok, -1 if failed
*/
int sci_msg_push(sci_msg_t *msg, int length);
@@ -122,30 +66,15 @@ int sci_msg_push(sci_msg_t *msg, int length);
* sci message removing of data with pointers update.
* \param msg msg where to remove data
* \param length length of data to remove
- * \return number of bytes stored, -1 if failed with errno=
- * - EINVAL if msg or data is NULL
+ * \return number of bytes stored, -1 if failed
*/
int sci_msg_pop(sci_msg_t *msg, int length);
/**
- * sci context, called during station context creation.
- * \param station station which uses the sci context
- * \return the new sci context, NULL if station is NULL
- */
-sci_ctx_t *sci_new(struct station_ctx *station);
-
-/**
- * sci context destruction with memory freeing.
- * \param sci sci context to destroy
- */
-void sci_free(sci_ctx_t *sci);
-
-/**
* initialize a static sci context, called during station context creation.
* \param sci sci context to initialize
* \param station station which uses the sci context
- * \return 0 if ok, -1 if failed with errno=
- * - EINVAL if sci or station is NULL
+ * \return 0 if ok, -1 if failed
*/
int sci_init(sci_ctx_t *sci, struct station_ctx *station);
@@ -155,10 +84,8 @@ int sci_init(sci_ctx_t *sci, struct station_ctx *station);
* \param type message type index
* \param function pointer to the callback function to process the received message
* \param data user data to be included into callback function as 'data' parameter
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if sci is null or type is wrong
+ * \return 0 if ok, -1 if failed
*/
-
int sci_register_callback(
sci_ctx_t *sci,
sci_msg_type_t type,
@@ -172,9 +99,7 @@ int sci_register_callback(
* \param msg sci message to fill header
* \param type type of message
* \param flags flags of message
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if sci or msg are NULL, or if type or length are out of range
- * - ENOSPC if there is no space left for sci header
+ * \return 0 if ok, -1 if failed
*/
int sci_fill_hdr(
sci_ctx_t *sci,
@@ -186,24 +111,17 @@ int sci_fill_hdr(
* sends a sci message to output pipe
* \param sci current sci context
* \param msg sci message to send to the pipe
- * \return length of sent data, -1 if failed with errno:
- * - EINVAL if sci or msg are NULL
- * - all errno generated by write() sys call
+ * \return length of sent data, -1 if failed
*/
int sci_send(sci_ctx_t *sci, sci_msg_t *msg);
/**
* receive a sci message from input pipe and process the registred callback
* \param sci current sci context
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if sci is NULL
- * - ENOSPC if msg length is > SCI_MSG_MAX_SIZE
- * - all errno generated by read() sys call
+ * \return 0 if ok, -1 if failed
*/
int sci_recv(sci_ctx_t *sci);
void sci_msg_dump(sci_msg_t *msg, int fd, char *buffer, int size);
-//END_DECLS
-
#endif /*SCI_H_*/
diff --git a/cesar/host/sci/maximus/src/sci_msg.c b/cesar/host/sci/src/sci_msg.c
index f6a7271f14..b356adf6f0 100644
--- a/cesar/host/sci/maximus/src/sci_msg.c
+++ b/cesar/host/sci/src/sci_msg.c
@@ -28,28 +28,6 @@
#endif /* UNIT_TEST */
/**
- * create a new sci message.
- * \param size max size of message
- * \return the new sci msg, NULL if failed, with errno
- * - EINVAL is size < sizeof(sci_msg_hdr_t) or > SCI_MSG_MAX_SIZE
- */
-sci_msg_t *sci_msg_new(int max_size)
-{
- /* maybe will not be implemented */
- return NULL;
-}
-
-/**
- * sci message destruction with memory freeing.
- * \param msg msg context to destroy
- */
-void sci_msg_free(sci_msg_t *msg)
-{
- /* maybe will not be implemented */
- return;
-}
-
-/**
* sci message init if a static msg structure is used (instead of dynamic).
* \param msg pointer to msg context to initialize
* \param buffer pointer to a data buffer with allocated space
@@ -162,4 +140,3 @@ void sci_msg_dump(sci_msg_t *msg, int fd, char *buffer, int size)
write(fd, buffer, strlen(buffer));
return;
}
-
diff --git a/cesar/host/test/Makefile b/cesar/host/test/Makefile
index c933ff1c69..d041147f74 100644
--- a/cesar/host/test/Makefile
+++ b/cesar/host/test/Makefile
@@ -3,7 +3,7 @@ EXTRA_HOST_CFLAGS+= -DUNIT_TEST
HOST_PROGRAMS = test_host
test_host_SOURCES = test_host.c test_sci_msg.c test_sci.c \
test_fcall_param.c test_fcall.c test_probe.c test_netclock.c \
- test_station.c test_system.c #test_phy_hal.c
+ test_station.c test_system.c
test_host_MODULES = lib host
include $(BASE)/common/make/top.mk
diff --git a/cesar/host/test/src/test_host.c b/cesar/host/test/src/test_host.c
index a2b315f526..df88f0827b 100644
--- a/cesar/host/test/src/test_host.c
+++ b/cesar/host/test/src/test_host.c
@@ -28,8 +28,6 @@ void probe_test_suite (test_t t);
void netclock_test_suite (test_t t);
-void phy_all_test_suite (test_t t);
-
void sci_msg_test_suite (test_t t);
void sci_test_suite (test_t t);
@@ -52,7 +50,6 @@ main (int argc, char **argv)
probe_test_suite(t);
netclock_test_suite(t);
system_test_suite(t);
- //phy_hal_test_suite(t);
test_result(t);
return test_nb_failed(t) == 0 ? 0 : 1;
diff --git a/cesar/host/test/src/test_sci.c b/cesar/host/test/src/test_sci.c
index 952c01d1f6..8ffc1d06a3 100644
--- a/cesar/host/test/src/test_sci.c
+++ b/cesar/host/test/src/test_sci.c
@@ -24,33 +24,6 @@
extern char dump_buffer[];
-//void sci_new_test_case(test_t t)
-//{
-// sci_ctx_t *sci;
-// station_ctx_t *station;
-//
-// test_case_begin(t, "new");
-// station = station_new();
-//
-// test_begin(t, "NULL station")
-// {
-// test_fail_unless(
-// (sci_new(NULL) == NULL)
-// && (errno == EINVAL));
-// } test_end;
-//
-// test_begin(t, "check new")
-// {
-// sci = sci_new(station);
-// test_fail_unless(
-// (sci != NULL)
-// && (sci->station == station));
-// }
-//
-// sci_free(sci);
-// station_free(station);
-//}
-
void sci_init_test_case(test_t t)
{
sci_ctx_t sci;
@@ -88,32 +61,6 @@ void sci_init_test_case(test_t t)
return;
}
-//void sci_free_test_case(test_t t)
-//{
-// station_ctx_t *station
-// sci_ctx_t *sci;
-//
-// test_case_begin(t, "free");
-//
-// test_begin(t, "NULL sci")
-// {
-// sci_free(NULL); /* must not crash */
-// test_fail_if(0);
-// } test_end;
-//
-// station = station_new();
-// sci = sci_new(station);
-//
-// test_begin(t, "check station integrity")
-// {
-// sci_free(sci);
-// test_fail_unless(
-// (station->id != 0)); /* station has not been freed */
-// } test_end;
-//
-// station_free(station);
-//}
-
static int _sci_callback(sci_msg_t *msg, void *data)
{
return 0;
@@ -517,9 +464,7 @@ void sci_recv_test_case(test_t t)
void sci_test_suite(test_t t)
{
test_suite_begin(t, "sci");
- //sci_new_test_case(t);
sci_init_test_case(t);
- //sci_free_test_case(t);
sci_register_callback_test_case(t);
sci_fill_hdr_test_case(t);
sci_send_test_case(t);
diff --git a/cesar/host/test/src/test_sci_msg.c b/cesar/host/test/src/test_sci_msg.c
index 43c2f6d8b1..4f7b8ff86f 100644
--- a/cesar/host/test/src/test_sci_msg.c
+++ b/cesar/host/test/src/test_sci_msg.c
@@ -18,49 +18,6 @@
#include "lib/test.h"
#include "host/sci/sci.h"
-void sci_msg_new_test_case(test_t t)
-{
- sci_msg_t *msg;
- test_case_begin(t, "new");
-
- test_begin(t, "max_size < sizeof(sci_msg_hdr_t)")
- {
- test_fail_unless(
- (sci_msg_new(sizeof(sci_msg_hdr_t) - 1) == NULL)
- && (errno == EINVAL)
- );
- // reset errno
- errno = 0;
- } test_end;
-
- test_begin(t, "max_size >= SCI_MSG_MAX_SIZE")
- {
- test_fail_unless(
- (sci_msg_new(SCI_MSG_MAX_SIZE) == NULL)
- && (errno == EINVAL)
- );
- // reset errno
- errno = 0;
- } test_end;
-
- test_begin(t, "check new msg")
- {
- msg = sci_msg_new(256);
- test_fail_unless(
- (msg != NULL)
- && ((unsigned char *)msg->sci_hdr == NULL)
- && ((unsigned char *)msg->hdr.station == NULL)
- && (msg->data != NULL)
- && (msg->data_begin == msg->data + msg->max_size)
- && (msg->data_end == msg->data_begin)
- && (msg->length == 0)
- && (msg->max_size == 256)
- );
- } test_end;
-
- sci_msg_free(msg);
-}
-
void sci_msg_init_test_case(test_t t)
{
sci_msg_t msg;
@@ -247,11 +204,9 @@ void sci_msg_pop_test_case(test_t t)
return;
}
-
void sci_msg_test_suite(test_t t)
{
test_suite_begin(t, "sci_msg");
- //sci_msg_new_test_case(t);
sci_msg_init_test_case(t);
sci_msg_push_test_case(t);
sci_msg_pop_test_case(t);
diff --git a/cesar/interface/Module b/cesar/interface/Module
index a9298470e2..b115790d59 100644
--- a/cesar/interface/Module
+++ b/cesar/interface/Module
@@ -1,2 +1,2 @@
SOURCES=interface.c
-MODULES:=interface/sniffer
+MODULES:=interface/sniffer interface/fcall
diff --git a/cesar/interface/fcall/Module b/cesar/interface/fcall/Module
new file mode 100644
index 0000000000..7482a3db84
--- /dev/null
+++ b/cesar/interface/fcall/Module
@@ -0,0 +1,2 @@
+SOURCES := interface_fcall.c
+MODULES := host/sci/cesar host/fcall host/netclock host/station host/system \ No newline at end of file
diff --git a/cesar/interface/fcall/inc/context.h b/cesar/interface/fcall/inc/context.h
new file mode 100644
index 0000000000..7d5656a503
--- /dev/null
+++ b/cesar/interface/fcall/inc/context.h
@@ -0,0 +1,30 @@
+#ifndef interface_fcall_inc_context_h
+#define interface_fcall_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/fcall/inc/context.h
+ * \brief Context of the interface fcall module.
+ * \ingroup interface/fcall
+ *
+ */
+#include "interface/forward.h"
+#include "host/sci/sci.h"
+
+typedef u8* (*interface_buffer_work_get_cb_t) (interface_t *ctx);
+typedef void (*interface_fcall_send_message_cb_t) (void *user_data, u8 *message, uint length);
+
+typedef struct interface_fcall_t
+{
+ sci_ctx_t *sci_ctx; /** pointer to the SCI context */
+ interface_buffer_work_get_cb_t buffer_cb; /** get buffer function */
+ interface_fcall_send_message_cb_t send_cb; /** callback function to call when the interface fcall module needs to send a message */
+ void *user_data; /** data to provide on callback function */
+} interface_fcall_t;
+
+#endif /* interface_fcall_inc_context_h */
diff --git a/cesar/interface/fcall/inc/interface_fcall.h b/cesar/interface/fcall/inc/interface_fcall.h
new file mode 100644
index 0000000000..958773acdb
--- /dev/null
+++ b/cesar/interface/fcall/inc/interface_fcall.h
@@ -0,0 +1,26 @@
+#ifndef interface_fcall_inc_interface_fcall_h
+#define interface_fcall_inc_interface_fcall_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/fcall/inc/interface_fcall.h
+ * \brief Private interface fcall module functions.
+ * \ingroup interface/fcall
+ *
+ */
+
+/**
+ * request the interface module to send a MME
+ * \param data pointer to the interface fcall context
+ * \param mme the MME buffer
+ * \param length the MME length
+ */
+void
+interface_fcall_mme_send (void *data, u8 *mme, uint length);
+
+#endif /* interface_fcall_inc_interface_fcall_h */
diff --git a/cesar/interface/fcall/interface_fcall.h b/cesar/interface/fcall/interface_fcall.h
new file mode 100644
index 0000000000..5afdd997b3
--- /dev/null
+++ b/cesar/interface/fcall/interface_fcall.h
@@ -0,0 +1,44 @@
+#ifndef interface_fcall_interface_fcall_h
+#define interface_fcall_interface_fcall_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/fcall/interface_fcall.h
+ * \brief Public interface fcall module functions.
+ * \ingroup interface/fcall
+ *
+ */
+#include "interface/fcall/inc/context.h"
+
+/**
+ * initialise the interface fcall module and the callback functions
+ * \param cb the function to call when the interface fcall needs to send a message
+ * \param user_data the data to provide on callback function
+ */
+interface_fcall_t*
+interface_fcall_init (interface_buffer_work_get_cb_t buffer_cb,
+ interface_fcall_send_message_cb_t send_cb,
+ void *user_data);
+
+/**
+ * uninitalise the interface fcall module
+ * \param ctx the interface fcall context
+ */
+void
+interface_fcall_uninit (interface_fcall_t *ctx);
+
+/**
+ * process a received MME and request the interface module to send the MME response
+ * \param data pointer to the interface fcall context
+ * \param mme the MME buffer
+ * \param length the MME length
+ */
+void
+interface_fcall_mme_recv (void *data, u8 *mme, uint length);
+
+#endif /* interface_fcall_interface_fcall_h */
diff --git a/cesar/interface/fcall/src/interface_fcall.c b/cesar/interface/fcall/src/interface_fcall.c
new file mode 100644
index 0000000000..bf12a013eb
--- /dev/null
+++ b/cesar/interface/fcall/src/interface_fcall.c
@@ -0,0 +1,148 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+/**
+ * \file interface_fcall.c
+ * \brief The public interface fcall functions
+ * \ingroup interface/fcall
+ *
+ * \todo
+ */
+#include "common/std.h"
+#include "lib/dbg.h"
+#include "interface/fcall/inc/context.h"
+#include "interface/fcall/inc/interface_fcall.h"
+#include "common/defs/ethernet.h" // for 'ETH_PACKET_MIN_SIZE' and 'ETH_PACKET_MAX_SIZE'
+#include <errno.h>
+
+/**
+ * initialise the interface fcall module and the callback functions
+ * \param cb the function to call when the interface fcall needs to send a message
+ * \param user_data the data to provide on callback function
+ */
+interface_fcall_t*
+interface_fcall_init (interface_buffer_work_get_cb_t buffer_cb,
+ interface_fcall_send_message_cb_t send_cb,
+ void *user_data)
+{
+ static interface_fcall_t ctx;
+ sci_ctx_t sci_ctx;
+ station_ctx_t station_ctx;
+
+ dbg_assert_ptr(buffer_cb);
+ dbg_assert_ptr(send_cb);
+ dbg_assert_ptr(user_data);
+ if ((NULL == buffer_cb)
+ || (NULL == send_cb)
+ || (NULL == user_data))
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ memset(&ctx, '\0', sizeof(interface_fcall_t));
+ ctx.buffer_cb = buffer_cb;
+ ctx.send_cb = send_cb;
+ ctx.user_data = user_data;
+ if (sci_init(&sci_ctx, &station_ctx) < 0)
+ {
+ return NULL;
+ }
+ ctx.sci_ctx = &sci_ctx;
+ if (sci_register_send_callback(&sci_ctx, &interface_fcall_mme_send, (void*)&ctx) < 0)
+ {
+ return NULL;
+ }
+
+ return &ctx;
+}
+
+/**
+ * uninitalise the interface fcall module
+ * \param ctx the interface fcall context
+ */
+void
+interface_fcall_uninit (interface_fcall_t *ctx)
+{
+ dbg_assert_ptr(ctx);
+ if (NULL == ctx)
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ memset(ctx, '\0', sizeof(interface_fcall_t));
+}
+
+/**
+ * process a received MME and request the interface module to send the MME response
+ * \param ctx the interface fcall context
+ * \param mme the MME buffer
+ * \param length the MME length
+ */
+void
+interface_fcall_mme_recv (void *data, u8 *mme, uint length)
+{
+ unsigned char *sci_buffer = NULL; /** the receive buffer */
+ sci_msg_t msg;
+ interface_fcall_t *ctx = NULL;
+
+ dbg_assert_ptr(data);
+ dbg_assert_ptr(mme);
+ if ( (NULL == data)
+ || (NULL == mme) )
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ ctx = (interface_fcall_t*)data;
+ if (NULL != ctx->buffer_cb)
+ {
+ sci_buffer = (*ctx->buffer_cb)((interface_t*)ctx->user_data);
+ if (NULL == sci_buffer)
+ {
+ // wait and retry
+ return;
+ }
+ }
+ if (sci_msg_init(&msg, sci_buffer, SCI_MSG_MAX_SIZE) < 0)
+ {
+ return;
+ }
+ sci_recv_msg(ctx->sci_ctx, &msg);
+}
+
+/**
+ * request the interface module to send a MME
+ * \param data pointer to the interface fcall context
+ * \param mme the MME buffer
+ * \param length the MME length
+ */
+void
+interface_fcall_mme_send (void *data, u8 *mme, uint length)
+{
+ interface_fcall_t *ctx;
+
+ dbg_assert_ptr(data);
+ dbg_assert_ptr(mme);
+ if ((NULL == data)
+ || (NULL == mme))
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ ctx = (interface_fcall_t*)data;
+ if (NULL != ctx->send_cb)
+ {
+ (*ctx->send_cb)(ctx->user_data, mme, length);
+ }
+
+ return;
+}
diff --git a/cesar/interface/fcall/test/Config b/cesar/interface/fcall/test/Config
new file mode 100644
index 0000000000..20950daa9a
--- /dev/null
+++ b/cesar/interface/fcall/test/Config
@@ -0,0 +1,2 @@
+CONFIG_DEBUG = y
+CONFIG_DEBUG_FATAL_CATCH = y \ No newline at end of file
diff --git a/cesar/interface/fcall/test/Makefile b/cesar/interface/fcall/test/Makefile
new file mode 100644
index 0000000000..d5e7b70437
--- /dev/null
+++ b/cesar/interface/fcall/test/Makefile
@@ -0,0 +1,8 @@
+BASE = ../../..
+EXTRA_HOST_CFLAGS+= -DUNIT_TEST
+EXTRA_HOST_CFLAGS+= -DSPARC_TEST
+HOST_PROGRAMS = test_interface_fcall
+test_interface_fcall_SOURCES = test_interface_fcall.c
+test_interface_fcall_MODULES = lib interface/fcall
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/interface/fcall/test/src/test_interface_fcall.c b/cesar/interface/fcall/test/src/test_interface_fcall.c
new file mode 100644
index 0000000000..83e1418618
--- /dev/null
+++ b/cesar/interface/fcall/test/src/test_interface_fcall.c
@@ -0,0 +1,292 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file test_interface_fcall.c
+ * \brief Test the interface fcall functions.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "host/sci/sci.h"
+#include "host/station/station.h"
+#include "interface/fcall/interface_fcall.h"
+#include "interface/fcall/inc/interface_fcall.h"
+#include "interface/forward.h"
+#include "common/defs/ethernet.h" // for 'ETH_PACKET_MIN_SIZE' and 'ETH_PACKET_MAX_SIZE'
+#include <stdio.h> // for 'printf'
+#include <errno.h>
+
+u32 maximus_pending_isrs;
+interface_fcall_t *ctx;
+
+u8*
+interface_buffer_work_get_cb (interface_t *ctx)
+{
+ static u8 buffer[SCI_MSG_MAX_SIZE];
+ return buffer;
+}
+
+void
+interface_fcall_send_message_cb (void *user_data, u8 *message, uint length)
+{
+ return;
+}
+
+void
+interface_fcall_init_test_case(test_t t)
+{
+ int user_data = 123;
+
+ test_case_begin(t, "init");
+
+ test_begin(t, "NULL buffer cb")
+ {
+ dbg_fatal_try_begin
+ {
+ test_fail_unless(
+ (NULL == interface_fcall_init(NULL, &interface_fcall_send_message_cb, (void*)&user_data))
+ );
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("init with NULL buffer cb\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "NULL send cb")
+ {
+ dbg_fatal_try_begin
+ {
+ test_fail_unless(
+ (NULL == interface_fcall_init(&interface_buffer_work_get_cb, NULL, (void*)&user_data))
+ );
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("init with NULL send cb\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "NULL user data")
+ {
+ dbg_fatal_try_begin
+ {
+ test_fail_unless(
+ (NULL == interface_fcall_init(&interface_buffer_work_get_cb, &interface_fcall_send_message_cb, NULL))
+ );
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("init with NULL user data\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "check init")
+ {
+ ctx = interface_fcall_init(&interface_buffer_work_get_cb, &interface_fcall_send_message_cb, (void*)&user_data);
+/*
+ test_fail_unless(
+ (NULL != ctx)
+ && (EINVAL != errno)
+ && (ctx->buffer_cb = &interface_buffer_work_get_cb)
+ && (ctx->send_cb == &interface_fcall_send_message_cb)
+ && (ctx->user_data == &user_data)
+ && (ctx->sci_ctx != NULL)
+ );
+*/
+ } test_end;
+}
+
+void
+interface_fcall_mme_recv_test_case(test_t t)
+{
+ u8 mme[ETH_PACKET_MAX_SIZE];
+ uint length = ETH_PACKET_MAX_SIZE;
+
+ test_case_begin(t, "mme recv");
+
+ test_begin(t, "NULL data")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_recv (NULL, mme, length);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme recv with NULL data\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "NULL mme")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_recv (ctx, NULL, length);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme recv with NULL mme\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "length < ETH_PACKET_MIN_SIZE")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_recv (ctx, mme, 1);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme recv with length < ETH_PACKET_MIN_SIZE\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "length > ETH_PACKET_MAX_SIZE")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_recv (ctx, mme, length + 1);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme recv with length > ETH_PACKET_MAX_SIZE\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "check mme recv")
+ {
+/*
+ interface_fcall_mme_recv (ctx, mme, length);
+ test_fail_unless(
+ (errno != EINVAL)
+ );
+*/
+ } test_end;
+}
+
+void
+interface_fcall_mme_send_test_case(test_t t)
+{
+ u8 mme[ETH_PACKET_MAX_SIZE];
+ uint length = ETH_PACKET_MAX_SIZE;
+
+ test_case_begin(t, "mme send");
+
+ test_begin(t, "NULL data")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_send (NULL, mme, length);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme send with NULL data\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "NULL mme")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_send (ctx, NULL, length);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme send with NULL mme\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "length < ETH_PACKET_MIN_SIZE")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_send (ctx, mme, 1);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme send with length < ETH_PACKET_MIN_SIZE\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "length > ETH_PACKET_MAX_SIZE")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_mme_send (ctx, mme, length + 1);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("mme send with length > ETH_PACKET_MAX_SIZE\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "check mme send")
+ {
+/*
+ interface_fcall_mme_send (ctx, mme, length);
+ test_fail_unless(
+ (errno != EINVAL)
+ );
+*/
+ } test_end;
+}
+
+void
+interface_fcall_uninit_test_case(test_t t)
+{
+ test_case_begin(t, "uninit");
+
+ test_begin(t, "NULL ctx")
+ {
+ dbg_fatal_try_begin
+ {
+ interface_fcall_uninit(NULL);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ printf("uninit with NULL ctx\n%s\n", fatal_message);
+ }
+ dbg_fatal_try_end;
+ } test_end;
+
+ test_begin(t, "check uninit")
+ {
+/*
+ interface_fcall_uninit(ctx);
+ test_fail_unless(
+ (errno != EINVAL)
+ );
+*/
+ } test_end;
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init(t, argc, argv);
+
+ interface_fcall_init_test_case(t);
+ interface_fcall_mme_recv_test_case(t);
+ interface_fcall_mme_send_test_case(t);
+ interface_fcall_uninit_test_case(t);
+
+ test_result(t);
+ return test_nb_failed(t) == 0 ? 0 : 1;
+}
diff --git a/cesar/interface/forward.h b/cesar/interface/forward.h
new file mode 100644
index 0000000000..d3363cdd0d
--- /dev/null
+++ b/cesar/interface/forward.h
@@ -0,0 +1,19 @@
+#ifndef interface_forward_h
+#define interface_forward_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/forward.h
+ * \brief Interface context forward declaration.
+ * \ingroup interface
+ */
+
+/** Forward declaration. */
+typedef struct interface_t interface_t;
+
+#endif /* interface_forward_h */
diff --git a/cesar/interface/interface.h b/cesar/interface/interface.h
index 2ec5d0b65e..2a2b1e5656 100644
--- a/cesar/interface/interface.h
+++ b/cesar/interface/interface.h
@@ -21,12 +21,10 @@
#include "mac/sar/sar.h"
#include "interface/interface_module.h"
+#include "interface/forward.h"
#define INTERFACE_BUFFER_LIST_NUM_SLOTS 2
-/** Forward declaration. */
-typedef struct interface_t interface_t;
-
/**
* Function to call when the interface receives a new MME.
* \param ctx the interface context
diff --git a/cesar/maximus/test/test.sh b/cesar/maximus/test/test.sh
index f08eb69ad9..cb9230c473 100755
--- a/cesar/maximus/test/test.sh
+++ b/cesar/maximus/test/test.sh
@@ -65,6 +65,20 @@ make clean; make
obj/test_host
echo
+echo "*** Host SCI cesar unitary tests ***"
+echo
+cd $WORKSPACE/host/sci/cesar/test
+make clean; make
+obj/test_sci_cesar
+
+echo
+echo "*** Interface fcall unitary tests ***"
+echo
+cd $WORKSPACE/interface/fcall/test
+make clean; make
+obj/test_interface_fcall
+
+echo
echo "=> Python tests"
echo
cd $WORKSPACE/maximus/test