/* --------------------------------------------------------------------------- * RemoteProcedureCalls.c - v0.1 (c) 2008 Micro-key bv * --------------------------------------------------------------------------- * Micro-key bv * Industrieweg 28, 9804 TG Noordhorn * Postbus 92, 9800 AB Zuidhorn * The Netherlands * Tel: +31 594 503020 * Fax: +31 594 505825 * Email: support@microkey.nl * Web: www.microkey.nl * --------------------------------------------------------------------------- * Description: * --------------------------------------------------------------------------- * Version(s): 0.1, Jan 29, 2008, FSc * Creation. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * System include files * --------------------------------------------------------------------------- */ #include /* --------------------------------------------------------------------------- * Application include files * --------------------------------------------------------------------------- */ #include "types.h" #include "RemoteProcedureCalls.h" #include "serial.h" #include "BusProtocol.h" #include "FreeRTOS.h" #include "queue.h" #include "mem_mod.h" /* --------------------------------------------------------------------------- * Local constant and macro definitions * --------------------------------------------------------------------------- */ #define RPC_DISPATCH_QUEUE_SIZE (10) extern memman *bpMessagePool; /* --------------------------------------------------------------------------- * Global variable definitions * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * Local variable definitions * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * Local function definitions * --------------------------------------------------------------------------- */ //static t_rpc_entity *lookupRpcEntry( int handle, UINT8 functionId ); /** \brief Initialises a Remote Procedure Call administration * * \returns Handle to Remote Procedure Call administration (0 = failure) */ int rpcInit() { t_rpc_admin *newAdmin = (t_rpc_admin *)pvPortMalloc( sizeof(t_rpc_admin) ); if (newAdmin != NULL) { newAdmin->firstEntry = NULL; newAdmin->lastEntry = NULL; } return (int)newAdmin; } /** \brief Deinitialises the Remote Procedure Call administration * * \param handle Handle to RPC-adminstration */ void rpcDeinit( int handle ) { t_rpc_admin *theAdmin = (t_rpc_admin *)handle; // Remove whole list if (theAdmin->firstEntry != NULL) { t_rpc_entity *entry = theAdmin->firstEntry; while (entry != NULL) { t_rpc_entity *nextEntry = entry->next; vPortFree( entry ); entry = nextEntry; } } // Remove admin vPortFree( (void *)handle ); } /** \brief Adds a Remote Procedure Call to the administration * * \param handle Handle to RPC-administration * \param functionId Identifier for RPC * \param nrOfParams Nr of parameters required by RPC-function */ void rpcAdd( int handle, UINT8 functionId, char * functionName, t_rpc_remote_procedure_call funcptr, UINT8 nrOfParams ) { t_rpc_entity *newEntry = (t_rpc_entity *)pvPortMalloc( sizeof(t_rpc_entity) ); t_rpc_admin *theAdmin = (t_rpc_admin *)handle; // fill entry newEntry->functionId = functionId; newEntry->functionName = functionName; newEntry->rpcFunction = funcptr; newEntry->nrOfParams = nrOfParams; newEntry->next = NULL; newEntry->previous = NULL; // Add to linked list if (theAdmin->firstEntry != NULL) { theAdmin->lastEntry->next = newEntry; newEntry->previous = theAdmin->lastEntry; theAdmin->lastEntry = newEntry; } else { theAdmin->firstEntry = newEntry; theAdmin->lastEntry = newEntry; } } /** \brief Removes a Remote Procedure Call to the administration * * \param handle Handle to RPC-administration * \param functionId Identifier for RPC-function */ void rpcRemove( int handle, UINT8 functionId ) { t_rpc_entity *entry = rpcLookupEntry(handle, functionId); t_rpc_admin *theAdmin = (t_rpc_admin *)handle; if (entry != NULL) { // rebuild linked list if (entry->next != NULL) { entry->next->previous = entry->previous; } else { theAdmin->lastEntry = entry->previous; } if (entry->previous != NULL) { entry->previous->next = entry->next; } else { theAdmin->firstEntry = entry->next; } // remove entry vPortFree( entry ); } } /** \brief Looks up a Remote Procedure Call to the administration * * \param handle Handle to RPC-administration * \param functionId Identifier for RPC-function * \retval Pointer to RPC-function (NULL when not found) */ t_rpc_remote_procedure_call rpcLookup( int handle, UINT8 functionId ) { t_rpc_remote_procedure_call result = NULL; t_rpc_entity *entry = rpcLookupEntry(handle, functionId); if (entry != NULL) { result = entry->rpcFunction; } return result; } /** \brief Executes a Remote Procedure Call * * \param handle Handle to RPC-administration * \param nrOfParams Nr of parameters in params-array * \param params Pointer to array with all parameters * \retval OK RPC request is send * \retval ERROR Unable to send RPC request */ RESULT rpcExecute( int handle, UINT8 functionId, UINT8 nrOfParams, const UINT32 *params ) { t_rpc_entity *entry = rpcLookupEntry(handle, functionId); if (entry != NULL) { // Dispatch function to rpcThread // execute function //result = entry->rpcFunction; return OK; } else { return ERROR; } } t_rpc_entity *rpcLookupEntry( int handle, UINT8 functionId ) { t_rpc_admin *theAdmin = (t_rpc_admin *)handle; t_rpc_entity *result = NULL; t_rpc_entity *iterator; iterator = theAdmin->firstEntry; while ((result == NULL) && (iterator != NULL)) { if (iterator->functionId == functionId) { result = iterator; } else { iterator = iterator->next; } } return result; } void rpcRequestHandler(t_bpmsg_message *msg, int ownHandler) { UINT8 index = 0; UINT8 count; UINT8 targetId, senderId, requestNr, functionId, nrOfParams; UINT32 *params; t_rpc_entity *rpcEntry; // Decode message targetId = msg->targetId; senderId = msg->senderId; requestNr = bpmsgGet8bit( msg->payload, &index); functionId = bpmsgGet8bit( msg->payload, &index); nrOfParams = bpmsgGet8bit( msg->payload, &index); BP_DEBUG_OUT('{'); BP_DEBUG_OUT('a' + functionId); // Allocate an array for the params if (nrOfParams > 0) { params = (UINT32 *)Memmod_Alloc( bpMessagePool ); if (params != NULL) { for (count = 0; count < nrOfParams; count++) { params[count] = bpmsgGet32bit(msg->payload, &index); } } else { // Error already indicated by heap_2.c return; } } else { params = NULL; } // Call RPC-function rpcEntry = rpcLookupEntry(ownHandler, functionId); if (rpcEntry != NULL) { BP_DEBUG_OUT('a' + functionId); // execute function rpcEntry->rpcFunction( senderId, targetId, requestNr, functionId, nrOfParams, params ); } if (params != NULL) { Memmod_Free( bpMessagePool, params ); } }