/*
* rpc_server.c
* ------------
* Remote procedure call server-side private API implementation.
*
* Copyright (c) 2016, NORDUnet A/S All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the NORDUnet nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cmsis_os.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-fmc.h"
#include "stm-uart.h"
/* stm32f4xx_hal_def.h and hal.h both define HAL_OK as an enum value */
#define HAL_OK HAL_OKAY
#include "hal.h"
/* declared in hal_internal.h */
extern hal_error_t hal_rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque);
extern hal_error_t hal_rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque);
#ifndef MAX_PKT_SIZE
#define MAX_PKT_SIZE 4096
#endif
typedef struct {
void *opaque;
size_t len;
uint8_t buf[MAX_PKT_SIZE];
} rpc_buffer_t;
osPoolDef(rpc_buffer_pool, 16, rpc_buffer_t);
osPoolId rpc_buffer_pool;
rpc_buffer_t *rpc_buffer_alloc(void)
{
rpc_buffer_t *rbuf = (rpc_buffer_t *)osPoolCAlloc(rpc_buffer_pool);
if (rbuf)
rbuf->len = sizeof(rbuf->buf);
return rbuf;
}
osMutexId uart_mutex;
osMutexDef(uart_mutex);
void dispatch_thread(void const *args)
{
rpc_buffer_t *ibuf = (rpc_buffer_t *)args;
rpc_buffer_t *obuf = rpc_buffer_alloc(); // NULL check
obuf->opaque = ibuf->opaque;
hal_rpc_server_dispatch(ibuf->buf, ibuf->len, obuf->buf, &obuf->len);
osPoolFree(rpc_buffer_pool, ibuf);
osMutexWait(uart_mutex, osWaitForever);
hal_rpc_sendto(obuf->buf, obuf->len, obuf->opaque);
osMutexRelease(uart_mutex);
osPoolFree(rpc_buffer_pool, obuf);
}
osThreadDef(dispatch_thread, osPriorityNormal, DEFAULT_STACK_SIZE);
void rpc_server_main(void)
{
hal_error_t ret;
while (1) {
rpc_buffer_t *ibuf = rpc_buffer_alloc(); // NULL check
// separate allocations for struct and block of memory?
ret = hal_rpc_recvfrom(ibuf->buf, &ibuf->len, &ibuf->opaque);
if (ret == HAL_OK) {
osThreadCreate(osThread(dispatch_thread), (void *)ibuf);
}
}
}
int main()
{
stm_init();
#ifdef TARGET_CRYPTECH_DEV_BRIDGE
// Blink blue LED for six seconds to not upset the Novena at boot.
led_on(LED_BLUE);
for (int i = 0; i < 12; i++) {
osDelay(500);
led_toggle(LED_BLUE);
}
#endif
// prepare fmc interface
fmc_init();
rpc_buffer_pool = osPoolCreate(osPool(rpc_buffer_pool));
uart_mutex = osMutexCreate(osMutex(uart_mutex));
#ifdef TARGET_CRYPTECH_ALPHA
// Launch other threads:
// - admin thread on USART1
// - csprng warm-up thread?
#endif
if (hal_rpc_server_init() != HAL_OK)
return 1;
rpc_server_main();
}