summaryrefslogtreecommitdiff
path: root/cesar/host/src/fcall.c
diff options
context:
space:
mode:
authorburet2008-04-25 09:08:24 +0000
committerburet2008-04-25 09:08:24 +0000
commite7d8a95df450338da2e8bea4ea2a416dec3562b8 (patch)
treef45a6fba5384ba106126ae153533321383e5fae0 /cesar/host/src/fcall.c
parent7925d5613b15c59c4d65322dfe684eb41bb0a220 (diff)
Proto fcall: re-organize host module and sub-modules.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@1911 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/host/src/fcall.c')
-rw-r--r--cesar/host/src/fcall.c482
1 files changed, 0 insertions, 482 deletions
diff --git a/cesar/host/src/fcall.c b/cesar/host/src/fcall.c
deleted file mode 100644
index 97fb83fd2e..0000000000
--- a/cesar/host/src/fcall.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/* Cesar project {{{
- *
- * Copyright (C) 2007 Spidcom
- *
- * <<<Licence>>>
- *
- * }}} */
-
-/**
- * \file fcall.c
- * \brief The 'function call' context management functions
- * \ingroup host
- *
- * This file provides 'function call' context management functions
- *
- * \todo
- */
-
-#include "common/std.h"
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include "host/fcall.h"
-#ifndef UNIT_TEST
-#include "lib/swap.h"
-#include "host/syscall.h"
-#else /* UNIT_TEST */
-#include <unistd.h>
-#include <arpa/inet.h>
-#endif /* UNIT_TEST */
-
-/**
- * initialize a static fcall context, called during station context creation.
- * \param fcall fcall context to initialize
- * \param station station which uses the fcall context
- * \return 0 if ok, -1 if failed with errno=
- * - EINVAL if fcall or station is NULL
- */
-int fcall_init(fcall_ctx_t *fcall, sci_ctx_t *sci)
-{
- DBG_ASSERT(fcall);
- DBG_ASSERT(sci);
- if((fcall == NULL)
- || (sci == NULL))
- {
- errno = EINVAL;
- return -1;
- }
-
- memset(fcall, '\0', sizeof(fcall_ctx_t));
- fcall->sci = sci;
- sci_register_callback(sci, SCI_MSG_TYPE_FUNCTION_CALL, fcall_recv, fcall);
- return 0;
-}
-
-/**
- * fcall callback function registering
- * \param fcall pointer to current fcall context
- * \param id function string id
- * \param function pointer to callback function
- * \return 0 if ok, -1 if fail with errno=
- * - EINVAL if fcall or id is NULL
- * - ENAMETOOLONG if id length is >= FUNCTION_CALL_ID_MAX_SIZE
- * - ENOSPC if max number of registred function is reached
- * - EEXIST if function is already registered
- */
-int fcall_register(
- fcall_ctx_t *fcall,
- char *id,
- int (* function)(fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data),
- void *data)
-{
- int index;
-
- DBG_ASSERT(fcall);
- DBG_ASSERT(id);
- DBG_ASSERT(function);
- if((fcall == NULL)
- || (id == NULL)
- || (function == NULL))
- {
- errno = EINVAL;
- return -1;
- }
-
- /* check id length */
- DBG_ASSERT(strlen(id) < FUNCTION_CALL_ID_MAX_SIZE);
- if(strlen(id) >= FUNCTION_CALL_ID_MAX_SIZE)
- {
- errno = ENAMETOOLONG;
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because id length is invalid", __FUNCTION__, errno);
- return -1;
- }
-
- /* check if there is free place */
- DBG_ASSERT(fcall->function_nb < FUNCTION_CALL_FUNCTION_MAX_NB);
- if(fcall->function_nb >= FUNCTION_CALL_FUNCTION_MAX_NB)
- {
- errno = ENOSPC;
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because there is no free space", __FUNCTION__, errno);
- return -1;
- }
-
- /* check if function is already registered */
- for(index = 0; index < fcall->function_nb; index++)
- {
- DBG_ASSERT(strcmp(fcall->function_table[index].id, id));
- if(!strcmp(fcall->function_table[index].id, id))
- {
- errno = EEXIST;
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because function is already registered", __FUNCTION__, errno);
- return -1;
- }
- }
-
- /* register the function */
- strcpy(fcall->function_table[fcall->function_nb].id, id);
- fcall->function_table[fcall->function_nb].function = function;
- fcall->function_table[fcall->function_nb].data = data;
-
- /* increment the number of function */
- fcall->function_nb++;
-
- return 0;
-}
-
-/**
- * fill a blank fcall header with needed parameter number
- * \param fcall current fcall context
- * \param msg sci message to fill header
- * \param flags flags of message
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if param or msg are NULL
- */
-int fcall_fill_hdr(
- fcall_ctx_t *fcall,
- sci_msg_t *msg,
- fcall_param_t *param,
- int flags)
-{
- DBG_ASSERT(fcall);
- DBG_ASSERT(msg);
- DBG_ASSERT(param);
- if((fcall == NULL)
- || (msg == NULL)
- || (param == NULL))
- {
- errno = EINVAL;
- return -1;
- }
-
- param->id[FUNCTION_CALL_ID_MAX_SIZE - 1] = '\0'; /* just for security */
- /* add the function id */
- if(sci_msg_push(msg, strlen(param->id) + 1) < (int)strlen(param->id) + 1)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot add function id", __FUNCTION__, errno);
- return -1;
- }
- memcpy(msg->data_begin, param->id, strlen(param->id) + 1);
-
- /* add fcall header */
- if(sci_msg_push(msg, sizeof(struct fcall_msg_hdr)) < (int)sizeof(struct fcall_msg_hdr))
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot add fcall header", __FUNCTION__, errno);
- return -1;
- }
- msg->hdr.fcall = (struct fcall_msg_hdr *)(msg->data_begin);
- /* fill it */
- msg->hdr.fcall->version = FUNCTION_CALL_VERSION;
- msg->hdr.fcall->type = FUNCTION_CALL_TYPE_RSP;
- msg->hdr.fcall->param_nb = param->param_nb;
- msg->hdr.fcall->msg_id = htons(param->msg_id);
- msg->hdr.fcall->flags = flags;
-
- return 0;
-}
-
-/**
- * send the return parameter list of asynchronous function call
- * \param fcall pointer to the current fcall context
- * \param pointer to returned parameter structure
- * \param msg pointer to returned parameter message buffer
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if fcall, param or msg is NULL
- * - errno set by sci_send()
- */
-int fcall_return(fcall_ctx_t *fcall, fcall_param_t *param, sci_msg_t *msg)
-{
- DBG_ASSERT(fcall);
- DBG_ASSERT(param);
- DBG_ASSERT(msg);
- if((fcall == NULL)
- || (param == NULL)
- || (msg == NULL))
- {
- errno = EINVAL;
- return -1;
- }
-
- /* fill the fcall msg header to prepare the answer */
- if(fcall_fill_hdr(fcall, msg, param, 0) < 0)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot fill fcall msg header", __FUNCTION__, errno);
- return -1;
- }
-
- /* now fill the sci header */
- if(sci_fill_hdr(fcall->sci, msg, SCI_MSG_TYPE_FUNCTION_CALL, 0) < 0)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot fill sci header", __FUNCTION__, errno);
- return -1;
- }
-
- station_log(fcall->sci->station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
- "%s id=%s, msg_id=%u, param_nb=%d", __FUNCTION__, param->id, param->msg_id, param->param_nb);
-
- /* send the message */
- if(sci_send(fcall->sci, msg) < 0)
- {
- station_log(fcall->sci->station, STATION_LOG_WARNING, STATION_LOGTYPE_FCALL, "%s failed to send fcall (errno=%d)", __FUNCTION__, errno);
- return -1;
- }
- else
- return 0;
-}
-
-/**
- * fill fcall body with all function parameters
- * sci_msg_push() is called each time a parameter is added
- * \param fcall current fcall context
- * \param msg sci message to fill body
- * \param param current fcall param context
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if param or msg are NULL
- * - ENOSPC if body overwhelm msg storage capacity
- */
-//int fcall_fill_body(
-// fcall_ctx_t *fcall,
-// sci_msg_t *msg,
-// fcall_param_t *param);
-
-/**
- * fill fcall full content: header + body inside a message
- * \param fcall current fcall context
- * \param msg sci message to fill
- * \param flags flags of message
- * \return 0 if ok, -1 if failed with errno:
- * - EINVAL if param or msg are NULL
- * - ENOSPC if body = header overwhelmed msg storage capacity
- */
-//int fcall_fill_msg(
-// fcall_ctx_t *fcall,
-// sci_msg_t *msg,
-// int flags);
-
-/**
- * fcall message processing function; called by sci_recv()
- * must be registred to sci layer with SCI_MSG_TYPE_FUNCTION_CALL type
- * \param fcall pointer to current fcall context
- * \param msg pointer to received message with sci pre-processing
- * \return 0 if ok, -1 if failed with errno=
- * - EINVAL if fcall or msg is NULL
- * - EPROTOTYPE if fcall type != FUNCTION_CALL_TYPE_REQ
- */
-int fcall_recv(sci_msg_t *msg, void *fcall_data)
-{
- int function_index, index;
- fcall_ctx_t *fcall;
- fcall_param_t param_recv, *param_ref;
- unsigned char return_flags = 0;
- int len = 0;
-
- fcall = (fcall_ctx_t *)fcall_data;
-
- DBG_ASSERT(fcall);
- DBG_ASSERT(msg);
- if((fcall == NULL)
- || (msg == NULL))
- {
- errno = EINVAL;
- return -1;
- }
-
- param_ref = &param_recv;
- fcall_param_init(&param_recv, "", 0);
-
- /* set header pointer in case of not already done */
- msg->hdr.fcall = (struct fcall_msg_hdr *)(msg->data_begin);
- /* check header content */
- DBG_ASSERT(msg->hdr.fcall->type == FUNCTION_CALL_TYPE_REQ);
- if(msg->hdr.fcall->type != FUNCTION_CALL_TYPE_REQ)
- {
- errno = EPROTOTYPE;
- station_log(fcall->sci->station, STATION_LOG_WARNING, STATION_LOGTYPE_FCALL,
- "%s: errno = %d: bad type %x", __FUNCTION__, errno, msg->hdr.fcall->type);
- return -1;
- }
-
- /* fill the param structure */
- /* get the parameter number */
- param_ref->param_nb = msg->hdr.fcall->param_nb;
- param_ref->msg_id = ntohs(msg->hdr.fcall->msg_id);
- if(sci_msg_pop(msg, sizeof(struct fcall_msg_hdr)) < (int)sizeof(struct fcall_msg_hdr))
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot get fcall header", __FUNCTION__, errno);
- return -1;
- }
-
- /* check function id len */
- DBG_ASSERT((strlen((char *)(msg->data_begin)) != 0)
- && (strlen((char *)(msg->data_begin)) < FUNCTION_CALL_ID_MAX_SIZE));
- if((strlen((char *)(msg->data_begin)) == 0)
- || (strlen((char *)(msg->data_begin)) >= FUNCTION_CALL_ID_MAX_SIZE))
- {
- errno = ENOENT;
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d: bad function id length", __FUNCTION__, errno);
- return -1;
- }
-
- /* init param structure */
- strcpy(param_ref->id, (char *)(msg->data_begin));
- len = (int)strlen((char *)(msg->data_begin)) + 1;
- if(sci_msg_pop(msg, len) < len)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot get data", __FUNCTION__, errno);
- return -1;
- }
-
- /* find the registred function */
- DBG_ASSERT(fcall->function_nb > 0);
- if(fcall->function_nb <= 0)
- {
- errno = ENOENT;
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot find registered function", __FUNCTION__, errno);
- return -1;
- }
- for(function_index = 0; function_index < fcall->function_nb; function_index++)
- {
- if(!strcmp(fcall->function_table[function_index].id, param_ref->id)
- && (fcall->function_table[function_index].function != NULL))
- break;
- }
- DBG_ASSERT(function_index < fcall->function_nb);
- if(function_index >= fcall->function_nb)
- {
- errno = ENOENT;
- station_log(fcall->sci->station, STATION_LOG_NOTICE, STATION_LOGTYPE_FCALL,
- "%s: errno = %d: function '%s' not registered", __FUNCTION__, errno, param_ref->id);
- return -1;
- }
-
- /* get all param */
- for(index = 0; index < param_ref->param_nb; index++)
- {
- DBG_ASSERT(msg->length != 0);
- if(msg->length == 0)
- {
- errno = ENOSPC;
- station_log(fcall->sci->station, STATION_LOG_WARNING, STATION_LOGTYPE_FCALL,
- "%s: errno = %d: no space into msg for param #%d", __FUNCTION__, errno, index);
- return -1;
- }
- param_ref->param_table[index].id = (char *)(msg->data_begin);
- len = (int)strlen((char *)(msg->data_begin)) + 1;
- if(sci_msg_pop(msg, len) < len)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot get data", __FUNCTION__, errno);
- return -1;
- }
- param_ref->param_table[index].length = (unsigned short *)(msg->data_begin);
- if(sci_msg_pop(msg, sizeof(unsigned short)) < (int)sizeof(unsigned short))
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot fill param length", __FUNCTION__, errno);
- return -1;
- }
- param_ref->param_table[index].data = msg->data_begin;
- if(sci_msg_pop(msg, ntohs(*param_ref->param_table[index].length)) < ntohs(*param_ref->param_table[index].length))
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot fill param data", __FUNCTION__, errno);
- return -1;
- }
- }
-
- DBG_ASSERT(msg->length <= 0);
- if(msg->length > 0)
- {
- station_log(fcall->sci->station, STATION_LOG_WARNING, STATION_LOGTYPE_FCALL,
- "%s: errno = %d: msg length > 0 (%d) after parameter extraction", __FUNCTION__, errno, msg->length);
- return -1;
- }
-
- /* call the function */
- station_log(fcall->sci->station, STATION_LOG_INFO, STATION_LOGTYPE_FCALL,
- "%s calling function '%s'(%p) with %d parameters",
- __FUNCTION__,
- fcall->function_table[function_index].id,
- fcall->function_table[function_index].function,
- param_ref->param_nb);
- if((*fcall->function_table[function_index].function)(
- fcall,
- &param_ref,
- &msg,
- fcall->function_table[function_index].data) < 0)
- {
- DBG_ASSERT(errno == 0);
- /* function returned error */
- param_ref->param_nb = 0;
- return_flags |= FUNCTION_CALL_FLAG_FAILED;
- station_log(fcall->sci->station, STATION_LOG_NOTICE, STATION_LOGTYPE_FCALL,
- "%s: errno = %d: function '%s' returned error", __FUNCTION__, errno, fcall->function_table[function_index].id);
- /* reset errno */
- errno = 0;
- }
- else
- {
- if(param_ref->is_async)
- {
- station_log(fcall->sci->station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
- "%s function '%s' returned from asynchronous call", __FUNCTION__, fcall->function_table[function_index].id);
- }
- else
- {
- station_log(fcall->sci->station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
- "%s function '%s' returned %d parameters (msg->length=%d)", __FUNCTION__, fcall->function_table[function_index].id, param_ref->param_nb, msg->length);
- }
- }
-
- if(param_ref->is_async)
- /* asynchronous call: return immediately */
- return 0;
-
- /* after function return, we get a param structure update with return results */
-
- /* be sure to have the same function name */
- strcpy(param_ref->id, fcall->function_table[function_index].id);
- /* fill the fcall msg header to prepare the answer */
- if(fcall_fill_hdr(fcall, msg, param_ref, return_flags) < 0)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot fill fcall msg header", __FUNCTION__, errno);
- return -1;
- }
-
- /* now fill the sci header */
- if(sci_fill_hdr(fcall->sci, msg, SCI_MSG_TYPE_FUNCTION_CALL, 0) < 0)
- {
- station_log(fcall->sci->station, STATION_LOG_ERROR, STATION_LOGTYPE_FCALL,
- "%s: errno = %d because cannot fill sci header", __FUNCTION__, errno);
- return -1;
- }
-
- /* send the message */
- if (sci_send(fcall->sci, msg) < 0)
- {
- station_log(fcall->sci->station, STATION_LOG_WARNING, STATION_LOGTYPE_FCALL, "%s failed to send fcall (errno=%d)", __FUNCTION__, errno);
- return -1;
- }
- else
- return 0;
-}
-
-void fcall_hdr_dump(struct fcall_msg_hdr *hdr, int fd, char *buffer, int size)
-{
- buffer[size - 1] = '\0';
- snprintf(buffer, size - 1, "fcall_hdr: version=%d, type=%d, param_nb=%d, flags=0x%x\n",
- hdr->version, hdr->type, hdr->param_nb, hdr->flags);
- write(fd, buffer, strlen(buffer));
-}