From cebc804ab815260f35f8d078b38061f1556101c2 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 9 Jul 2019 20:22:55 +0800 Subject: [PATCH] [wrappers/os] add zephyr wrapper Signed-off-by: Frank Li --- wrappers/os/zephyr/HAL_Zephyr.c | 546 ++++++++++++++++++++++++++++++++ 1 file changed, 546 insertions(+) create mode 100644 wrappers/os/zephyr/HAL_Zephyr.c diff --git a/wrappers/os/zephyr/HAL_Zephyr.c b/wrappers/os/zephyr/HAL_Zephyr.c new file mode 100644 index 000000000..2c41b4186 --- /dev/null +++ b/wrappers/os/zephyr/HAL_Zephyr.c @@ -0,0 +1,546 @@ +#include +#include +#include +#include + +#include "infra_types.h" +#include "infra_defs.h" +#include "infra_compat.h" +#include "wrappers_defs.h" +#include "stdarg.h" + +#include +#include "zephyr.h" + +#define hal_err(x) +#define hal_info(x) + +#define hal_err(...) +#define hal_info(...) + +#define PRODUCT_KEY "a1MZxOdcBnO" +#define PRODUCT_SECRET "h4I4dneEFp7EImTv" +#define DEVICE_NAME "test_01" +#define DEVICE_SECRET "t9GmMf2jb3LgWfXBaZD2r3aJrfVWBv56" + +/** + * @brief Deallocate memory block + * + * @param[in] ptr @n Pointer to a memory block previously allocated with platform_malloc. + * @return None. + * @see None. + * @note None. + */ +void HAL_Free(void *ptr) +{ + free(ptr); + return; +} + + +/** + * @brief Get device name from user's system persistent storage + * + * @param [ou] device_name: array to store device name, max length is IOTX_DEVICE_NAME_LEN + * @return the actual length of device name + */ +int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1]) +{ + int len = strlen(DEVICE_NAME); + memset(device_name, 0x0, IOTX_DEVICE_NAME_LEN); + + strncpy(device_name, DEVICE_NAME, len); + + return strlen(device_name); +} + + +/** + * @brief Get device secret from user's system persistent storage + * + * @param [ou] device_secret: array to store device secret, max length is IOTX_DEVICE_SECRET_LEN + * @return the actual length of device secret + */ +int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1]) +{ + int len = strlen(DEVICE_SECRET); + memset(device_secret, 0x0, IOTX_DEVICE_SECRET_LEN); + + strncpy(device_secret, DEVICE_SECRET, len); + + return len; +} + + +/** + * @brief Get firmware version + * + * @param [ou] version: array to store firmware version, max length is IOTX_FIRMWARE_VER_LEN + * @return the actual length of firmware version + */ +int HAL_GetFirmwareVersion(char *version) +{ + char *ver = "app-1.0.0-20180101.1000"; + int len = strlen(ver); + memset(version, 0x0, IOTX_FIRMWARE_VER_LEN); + strncpy(version, ver, IOTX_FIRMWARE_VER_LEN); + version[len] = '\0'; + return strlen(version); +} + + +/** + * @brief Get product key from user's system persistent storage + * + * @param [ou] product_key: array to store product key, max length is IOTX_PRODUCT_KEY_LEN + * @return the actual length of product key + */ +int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1]) +{ + int len = strlen(PRODUCT_KEY); + strncpy(product_key, PRODUCT_KEY, len); + return len; +} + + +int HAL_GetProductSecret(char product_secret[IOTX_PRODUCT_SECRET_LEN + 1]) +{ + int len = strlen(PRODUCT_SECRET); + strncpy(product_secret, PRODUCT_SECRET, len); + return len; +} + + +/** + * @brief Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. + * + * @param [in] size @n specify block size in bytes. + * @return A pointer to the beginning of the block. + * @see None. + * @note Block value is indeterminate. + */ +void *HAL_Malloc(uint32_t size) +{ + return malloc(size); +} + + +/** + * @brief Create a mutex. + * + * @retval NULL : Initialize mutex failed. + * @retval NOT_NULL : The mutex handle. + * @see None. + * @note None. + */ +void *HAL_MutexCreate(void) +{ + struct k_mutex *mutex = (struct k_mutex *)HAL_Malloc(sizeof(struct k_mutex)); + if (NULL == mutex) { + return NULL; + } + + k_mutex_init(mutex); + + return mutex; +} + + +/** + * @brief Destroy the specified mutex object, it will release related resource. + * + * @param [in] mutex @n The specified mutex. + * @return None. + * @see None. + * @note None. + */ +void HAL_MutexDestroy(void *mutex) +{ + if (!mutex) { + return; + } + + HAL_Free(mutex); +} + + +/** + * @brief Waits until the specified mutex is in the signaled state. + * + * @param [in] mutex @n the specified mutex. + * @return None. + * @see None. + * @note None. + */ +void HAL_MutexLock(void *mutex) +{ + k_mutex_lock(mutex, -1); + return; +} + + +/** + * @brief Releases ownership of the specified mutex object.. + * + * @param [in] mutex @n the specified mutex. + * @return None. + * @see None. + * @note None. + */ +void HAL_MutexUnlock(void *mutex) +{ + k_mutex_unlock(mutex); + return; +} + + +/** + * @brief Writes formatted data to stream. + * + * @param [in] fmt: @n String that contains the text to be written, it can optionally contain embedded format specifiers + that specifies how subsequent arguments are converted for output. + * @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers. + * @return None. + * @see None. + * @note None. + */ +void HAL_Printf(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + fflush(stdout); +} + + +uint32_t HAL_Random(uint32_t region) +{ + return (region > 0) ? (random() % region) : 0; +} + + +/** + * @brief Sleep thread itself. + * + * @param [in] ms @n the time interval for which execution is to be suspended, in milliseconds. + * @return None. + * @see None. + * @note None. + */ +void HAL_SleepMs(uint32_t ms) +{ + k_sleep(ms); + return; +} + + +/** + * @brief Writes formatted data to string. + * + * @param [out] str: @n String that holds written text. + * @param [in] len: @n Maximum length of character will be written + * @param [in] fmt: @n Format that contains the text to be written, it can optionally contain embedded format specifiers + that specifies how subsequent arguments are converted for output. + * @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers. + * @return bytes of character successfully written into string. + * @see None. + * @note None. + */ +int HAL_Snprintf(char *str, const int len, const char *fmt, ...) +{ + va_list args; + int rc; + + va_start(args, fmt); + rc = vsnprintf(str, len, fmt, args); + va_end(args); + + return rc; +} + + +void HAL_Srandom(uint32_t seed) +{ + srandom(seed); +} + + +/** + * @brief Destroy the specific TCP connection. + * + * @param [in] fd: @n Specify the TCP connection by handle. + * + * @return The result of destroy TCP connection. + * @retval < 0 : Fail. + * @retval 0 : Success. + */ + int HAL_TCP_Destroy(uintptr_t fd) +{ + int rc; + + /* Shutdown both send and receive operations. */ + rc = shutdown((int) fd, 2); + if (0 != rc) { + return -1; + } + + rc = close((int) fd); + if (0 != rc) { + return -1; + } + + return 0; +} + + +/** + * @brief Establish a TCP connection. + * + * @param [in] host: @n Specify the hostname(IP) of the TCP server + * @param [in] port: @n Specify the TCP port of TCP server + * + * @return The handle of TCP connection. + @retval (uintptr_t)(-1): Fail. + @retval All other values(0 included): Success, the value is handle of this TCP connection. + */ + uintptr_t HAL_TCP_Establish(const char *host, uint16_t port) +{ + struct addrinfo hints; + struct addrinfo *addrInfoList = NULL; + struct addrinfo *cur = NULL; + int fd = 0; + int rc = 0; + char service[6]; + + memset(&hints, 0, sizeof(hints)); + + hal_info("establish tcp connection with server(host='%s', port=[%u])", host, port); + + hints.ai_family = AF_INET; /* only IPv4 */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + sprintf(service, "%u", port); + + if ((rc = getaddrinfo(host, service, &hints, &addrInfoList)) != 0) { + hal_err("getaddrinfo error(%d), host = '%s', port = [%d]", rc, host, port); + return -1; + } + + for (cur = addrInfoList; cur != NULL; cur = cur->ai_next) { + if (cur->ai_family != AF_INET) { + hal_err("socket type error"); + rc = -1; + continue; + } + + fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (fd < 0) { + hal_err("create socket error"); + rc = -1; + continue; + } + + if (connect(fd, cur->ai_addr, cur->ai_addrlen) == 0) { + rc = fd; + break; + } + + close(fd); + hal_err("connect error"); + rc = -1; + } + + if (-1 == rc) { + hal_err("fail to establish tcp"); + } else { + hal_info("success to establish tcp, fd=%d", rc); + } + freeaddrinfo(addrInfoList); + + return (uintptr_t)rc; +} + + +/** + * @brief Read data from the specific TCP connection with timeout parameter. + * The API will return immediately if 'len' be received from the specific TCP connection. + * + * @param [in] fd @n A descriptor identifying a TCP connection. + * @param [out] buf @n A pointer to a buffer to receive incoming data. + * @param [out] len @n The length, in bytes, of the data pointed to by the 'buf' parameter. + * @param [in] timeout_ms @n Specify the timeout value in millisecond. In other words, the API block 'timeout_ms' millisecond maximumly. + * + * @retval -2 : TCP connection error occur. + * @retval -1 : TCP connection be closed by remote server. + * @retval 0 : No any data be received in 'timeout_ms' timeout period. + * @retval (0, len] : The total number of bytes be received in 'timeout_ms' timeout period. + + * @see None. + */ + int32_t HAL_TCP_Read(uintptr_t fd, char *buf, uint32_t len, uint32_t timeout_ms) +{ + int ret, err_code; + uint32_t len_recv; + uint64_t t_end, t_left; + fd_set sets; + struct timeval timeout; + + t_end = k_uptime_get() + timeout_ms; + len_recv = 0; + err_code = 0; + + do { + t_left = t_end - k_uptime_get(); + if (0 == t_left) { + break; + } + FD_ZERO(&sets); + FD_SET(fd, &sets); + + timeout.tv_sec = t_left / 1000; + timeout.tv_usec = (t_left % 1000) * 1000; + + ret = select(fd + 1, &sets, NULL, NULL, &timeout); + if (ret > 0) { + ret = recv(fd, buf + len_recv, len - len_recv, 0); + if (ret > 0) { + len_recv += ret; + } else if (0 == ret) { + hal_err("connection is closed"); + err_code = -1; + break; + } else { + if (EINTR == errno) { + hal_err("EINTR be caught"); + continue; + } + hal_err("recv fail"); + err_code = -2; + break; + } + } else if (0 == ret) { + break; + } else { + hal_err("select-recv fail"); + err_code = -2; + break; + } + } while ((len_recv < len)); + + /* priority to return data bytes if any data be received from TCP connection. */ + /* It will get error code on next calling */ + return (0 != len_recv) ? len_recv : err_code; +} + + +/** + * @brief Write data into the specific TCP connection. + * The API will return immediately if 'len' be written into the specific TCP connection. + * + * @param [in] fd @n A descriptor identifying a connection. + * @param [in] buf @n A pointer to a buffer containing the data to be transmitted. + * @param [in] len @n The length, in bytes, of the data pointed to by the 'buf' parameter. + * @param [in] timeout_ms @n Specify the timeout value in millisecond. In other words, the API block 'timeout_ms' millisecond maximumly. + * + * @retval < 0 : TCP connection error occur.. + * @retval 0 : No any data be write into the TCP connection in 'timeout_ms' timeout period. + * @retval (0, len] : The total number of bytes be written in 'timeout_ms' timeout period. + + * @see None. + */ + int32_t HAL_TCP_Write(uintptr_t fd, const char *buf, uint32_t len, uint32_t timeout_ms) +{ + int ret; + uint32_t len_sent; + uint64_t t_end, t_left; + fd_set sets; + + t_end = k_uptime_get() + timeout_ms; + len_sent = 0; + ret = 1; /* send one time if timeout_ms is value 0 */ + int net_err = 0; + + do { + t_left = t_end - k_uptime_get(); + + if (t_left>0) { + struct timeval timeout; + + FD_ZERO(&sets); + FD_SET(fd, &sets); + + timeout.tv_sec = t_left / 1000; + timeout.tv_usec = (t_left % 1000) * 1000; + + ret = select(fd + 1, NULL, &sets, NULL, &timeout); + if (ret > 0) { + if (0 == FD_ISSET(fd, &sets)) { + hal_err("Should NOT arrive"); + /* If timeout in next loop, it will not sent any data */ + ret = 0; + continue; + } + } else if (0 == ret) { + hal_err("select-write timeout %d", (int)fd); + break; + } else { + if (EINTR == errno) { + hal_err("EINTR be caught"); + continue; + } + + hal_err("select-write fail, ret = select() = %d", ret); + net_err = 1; + break; + } + } + + if (ret > 0) { + ret = send(fd, buf + len_sent, len - len_sent, 0); + if (ret > 0) { + len_sent += ret; + } else if (0 == ret) { + hal_err("No data be sent"); + } else { + if (EINTR == errno) { + hal_err("EINTR be caught"); + continue; + } + + hal_err("send fail, ret = send() = %d", ret); + net_err = 1; + break; + } + } + } while (!net_err && (len_sent < len) && (t_end - k_uptime_get() > 0)); + + if (net_err) { + return -1; + } else { + return len_sent; + } +} + + +/** + * @brief Retrieves the number of milliseconds that have elapsed since the system was boot. + * + * @return the number of milliseconds. + * @see None. + * @note None. + */ +uint64_t HAL_UptimeMs(void) +{ + return k_uptime_get(); +} + + +int HAL_Vsnprintf(char *str, const int len, const char *format, va_list ap) +{ + return vsnprintf(str, len, format, ap); +} + +