feat: 移植腾讯云物联网开发平台 C SDK

This commit is contained in:
fancyxu
2022-07-01 11:06:09 +08:00
parent 2be1169b0b
commit 0acc079ed6
195 changed files with 36646 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
file(GLOB src
${CMAKE_CURRENT_SOURCE_DIR}/network/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/timer/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/os/${PLATFORM}/*.c
)
set(inc ${CMAKE_CURRENT_SOURCE_DIR}/network/inc/)
set(src_platform ${src_platform} ${src} PARENT_SCOPE)
set(inc_platform ${inc_platform} ${inc} PARENT_SCOPE)

View File

@@ -0,0 +1,5 @@
file(GLOB src ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c)
set(inc ${CMAKE_CURRENT_SOURCE_DIR}/inc/)
set(src_platform ${src_platform} ${src} PARENT_SCOPE)
set(inc_platform ${inc_platform} ${inc} PARENT_SCOPE)

View File

@@ -0,0 +1,205 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_at_client.h
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-05-06
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-05-06 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#ifndef IOT_HUB_DEVICE_C_SDK_PLATFORM_AT_CLIENT_INC_QCLOUD_IOT_AT_CLIENT_H_
#define IOT_HUB_DEVICE_C_SDK_PLATFORM_AT_CLIENT_INC_QCLOUD_IOT_AT_CLIENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "qcloud_iot_platform.h"
#define QCLOUD_AT_PARSE_THREAD_NAME "at_parse"
#define QCLOUD_AT_PARSE_THREAD_STACK_SIZE (4096)
#define QCLOUD_AT_PARSE_THREAD_PRIORITY THREAD_PRIORITY_HIGH
#define QCLOUD_AT_URC_THREAD_NAME "at_urc"
#define QCLOUD_AT_URC_THREAD_STACK_SIZE QCLOUD_AT_PARSE_THREAD_STACK_SIZE
#define QCLOUD_AT_URC_THREAD_PRIORITY THREAD_PRIORITY_HIGH
#define QCLOUD_AT_MAX_URC_QUEUE_LEN (16)
typedef enum {
QCLOUD_AT_RET_SUCCESS = 0,
QCLOUD_AT_RET_INITTED = 1,
QCLOUD_AT_ERR_FAILURE = -1,
QCLOUD_AT_ERR_NO_INIT = -2,
QCLOUD_AT_ERR_TIMEOUT = -3,
QCLOUD_AT_ERR_SEND_FAIL = -4,
QCLOUD_AT_ERR_RESP_FAIL = -5,
QCLOUD_AT_ERR_BUFF_SHORT = -5,
} QCloudATErrCode;
/**
* @brief AT urc.
*
*/
typedef struct {
const char *urc_prefix;
OnUrcHandler urc_handle;
} QcloudATUrc;
/**
* @brief Send data to at module.
*
*/
typedef int (*QcloudATSendDataFunc)(const void *data, size_t data_len);
/**
* @brief AT init status.
*
*/
typedef enum {
QCLOUD_AT_STATUS_NO_INIT = 0,
QCLOUD_AT_STATUS_INIT = 1,
} QcloudATStatus;
/**
* @brief AT response status.
*
*/
typedef enum {
QCLOUD_AT_RESP_STATUS_IDLE = 0, /* no change resp status */
QCLOUD_AT_RESP_STATUS_WAIT = 1, /* AT response wait */
QCLOUD_AT_RESP_STATUS_OK = 2, /* AT response OK */
QCLOUD_AT_RESP_STATUS_ERROR = -1, /* AT response ERROR */
} QcloudATRespStatus;
/**
* @brief AT response.
*
*/
typedef struct {
const char *expect;
uint8_t *recv_buf; /* recv data from at buffer */
uint32_t recv_len; /* recv data length */
QcloudATRespStatus status;
} QcloudATResp;
/**
* @brief AT URC Recv handle.
*
*/
typedef struct {
QcloudATUrc *urc;
char *urc_handle_buf;
uint32_t urc_recv_len;
} QcloudATUrcRecv;
/**
* @brief AT client.
*
*/
typedef struct {
QcloudATStatus status;
QcloudATSendDataFunc at_send_func;
// recv data
void *recv_pool;
void *recv_queue;
char *recv_buf;
uint32_t recv_buf_size;
uint32_t recv_len;
// urc
QcloudATUrc *urc_table;
uint32_t urc_table_size;
void *urc_recv_pool;
void *urc_recv_queue;
void *urc_lock;
// resp
QcloudATResp resp;
void *resp_lock;
void *resp_sem;
} QcloudATClient;
/**
* @brief Parse data recv from at module.
*
* @param[in] client pointer to QcloudATClient
*/
void qcloud_iot_at_client_parser(void *client);
/**
* @brief Recv urc and callback.
*
* @param[in] client pointer to QcloudATClient
*/
void qcloud_iot_at_urc_handle(void *client);
/**
* @brief Init at client.
*
* @param[in] max_at_size max at buffer size
* @param[in] at_send_func send at function
* @return @see QCloudATErrCode
*/
int qcloud_iot_at_client_init(int max_at_size, QcloudATSendDataFunc at_send_func);
/**
* @brief Set at urc.
*
* @param[in] urc_table urc table
* @param[in] urc_table_size table size
*/
void qcloud_iot_at_client_set_urc(QcloudATUrc *urc_table, uint32_t urc_table_size);
/**
* @brief Send at command and wait for receiving expect response or data.
*
* @param[in] at_cmd at command
* @param[in] at_expect expect response or data length format
* @param[out] recv_buf recv data buffer
* @param[out] recv_len recv data length
* @param[in] timeout_ms wait timeout
* @return @see QCloudATErrCode
*/
int qcloud_iot_at_client_send_at_util_expect(const char *at_cmd, const char *at_expect, void *recv_buf,
uint32_t *recv_len, uint32_t timeout_ms);
/**
* @brief Send data to at module.
*
* @param[in] data
* @param[in] data_len
* @return 0 for success
*/
int qcloud_iot_at_client_send_data(const void *data, size_t data_len);
/**
* @brief Push data to at client queue.
*
* @param[in] recv_data recv data from uart
* @param[in] data_len recv data length
* @return 0 for success.
*/
int qcloud_iot_at_client_push_data(const void *recv_data, size_t data_len);
#ifdef __cplusplus
}
#endif
#endif // IOT_HUB_DEVICE_C_SDK_PLATFORM_AT_CLIENT_INC_QCLOUD_IOT_AT_CLIENT_H_

View File

@@ -0,0 +1,256 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_at_client.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-05-06
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-05-06 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_at_client.h"
/**
* @brief Only one client is support.
*
*/
static QcloudATClient sg_client;
/**
* @brief Init at client.
*
* @param[in] max_at_size max at buffer size
* @param[in] at_send_func send at function
* @return @see QCloudATErrCode
*/
int qcloud_iot_at_client_init(int max_at_size, QcloudATSendDataFunc at_send_func)
{
if (QCLOUD_AT_STATUS_INIT == sg_client.status) {
return QCLOUD_AT_RET_INITTED;
}
sg_client.status = QCLOUD_AT_STATUS_INIT;
int rc;
QcloudATClient *client = &sg_client;
client->at_send_func = at_send_func;
client->recv_pool = HAL_Malloc(max_at_size);
if (!client->recv_pool) {
goto exit;
}
client->recv_queue = HAL_MailQueueInit(client->recv_pool, 1, max_at_size);
if (!client->recv_queue) {
goto exit;
}
client->recv_buf = HAL_Malloc(max_at_size);
if (!client->recv_buf) {
goto exit;
}
client->recv_buf_size = max_at_size;
client->recv_len = 0;
client->urc_table = NULL;
client->urc_table_size = 0;
client->urc_recv_pool = HAL_Malloc(sizeof(QcloudATUrcRecv) * QCLOUD_AT_MAX_URC_QUEUE_LEN);
if (!client->urc_recv_pool) {
goto exit;
}
client->urc_recv_queue =
HAL_MailQueueInit(client->urc_recv_pool, sizeof(QcloudATUrcRecv), QCLOUD_AT_MAX_URC_QUEUE_LEN);
if (!client->urc_recv_queue) {
goto exit;
}
client->resp.expect = NULL;
client->resp.status = QCLOUD_AT_RESP_STATUS_IDLE;
client->resp_lock = HAL_MutexCreate();
if (!client->resp_lock) {
goto exit;
}
client->resp_sem = HAL_SemaphoreCreate();
if (!client->resp_sem) {
goto exit;
}
static ThreadParams sg_qcloud_at_parse_thread_params = {0};
static void *sg_qcloud_at_parse_thread_stack;
if (!sg_qcloud_at_parse_thread_stack) {
sg_qcloud_at_parse_thread_stack = HAL_Malloc(QCLOUD_AT_PARSE_THREAD_STACK_SIZE);
if (!sg_qcloud_at_parse_thread_stack) {
goto exit;
}
}
sg_qcloud_at_parse_thread_params.user_arg = client;
sg_qcloud_at_parse_thread_params.stack_base = sg_qcloud_at_parse_thread_stack;
sg_qcloud_at_parse_thread_params.stack_size = QCLOUD_AT_PARSE_THREAD_STACK_SIZE;
sg_qcloud_at_parse_thread_params.thread_name = QCLOUD_AT_PARSE_THREAD_NAME;
sg_qcloud_at_parse_thread_params.priority = QCLOUD_AT_PARSE_THREAD_PRIORITY;
sg_qcloud_at_parse_thread_params.thread_func = qcloud_iot_at_client_parser;
rc = HAL_ThreadCreate(&sg_qcloud_at_parse_thread_params);
if (rc) {
goto exit;
}
static ThreadParams sg_qcloud_at_urc_thread_params = {0};
static void *sg_qcloud_at_urc_thread_stack;
if (!sg_qcloud_at_urc_thread_stack) {
sg_qcloud_at_urc_thread_stack = HAL_Malloc(QCLOUD_AT_URC_THREAD_STACK_SIZE);
if (!sg_qcloud_at_urc_thread_stack) {
goto exit;
}
}
sg_qcloud_at_urc_thread_params.user_arg = client;
sg_qcloud_at_urc_thread_params.stack_base = sg_qcloud_at_urc_thread_stack;
sg_qcloud_at_urc_thread_params.stack_size = QCLOUD_AT_URC_THREAD_STACK_SIZE;
sg_qcloud_at_urc_thread_params.thread_name = QCLOUD_AT_URC_THREAD_NAME;
sg_qcloud_at_urc_thread_params.priority = QCLOUD_AT_URC_THREAD_PRIORITY;
sg_qcloud_at_urc_thread_params.thread_func = qcloud_iot_at_urc_handle;
rc = HAL_ThreadCreate(&sg_qcloud_at_urc_thread_params);
if (rc) {
HAL_ThreadDestroy(sg_qcloud_at_parse_thread_params.thread_id);
goto exit;
}
return QCLOUD_AT_RET_SUCCESS;
exit:
HAL_MailQueueDeinit(client->recv_queue);
HAL_Free(client->recv_pool);
HAL_Free(client->recv_buf);
HAL_MutexDestroy(client->resp_lock);
HAL_SemaphoreDestroy(client->resp_sem);
HAL_MailQueueDeinit(client->urc_recv_queue);
HAL_Free(client->urc_recv_pool);
memset(client, 0, sizeof(QcloudATClient));
return QCLOUD_AT_ERR_FAILURE;
}
/**
* @brief Set at urc.
*
* @param[in] urc_table urc table
* @param[in] urc_table_size table size
*/
void qcloud_iot_at_client_set_urc(QcloudATUrc *urc_table, uint32_t urc_table_size)
{
sg_client.urc_table = urc_table;
sg_client.urc_table_size = urc_table_size;
}
/**
* @brief Send at command and wait for receiving expect response.
*
* @param[in] at_cmd at command
* @param[in] at_expect expect response
* @param[in] timeout_ms wait timeout
* @return @see QCloudATErrCode
*/
/**
* @brief Send at command and wait for receiving expect response or data.
*
* @param[in] at_cmd at command
* @param[in] at_expect expect response or data length format
* @param[out] recv_buf recv data buffer
* @param[out] recv_len recv data length
* @param[in] timeout_ms wait timeout
* @return @see QCloudATErrCode
*/
int qcloud_iot_at_client_send_at_util_expect(const char *at_cmd, const char *at_expect, void *recv_buf,
uint32_t *recv_len, uint32_t timeout_ms)
{
QcloudATClient *client = &sg_client;
if (QCLOUD_AT_STATUS_NO_INIT == client->status) {
return QCLOUD_AT_ERR_NO_INIT;
}
int rc;
HAL_MutexLock(client->resp_lock);
client->resp.expect = at_expect;
client->resp.recv_buf = recv_buf;
client->resp.recv_len = 0;
client->resp.status = QCLOUD_AT_RESP_STATUS_WAIT;
rc = client->at_send_func(at_cmd, strlen(at_cmd));
if (rc) {
rc = QCLOUD_AT_ERR_SEND_FAIL;
goto exit;
}
rc = HAL_SemaphoreWait(client->resp_sem, timeout_ms);
if (rc) {
rc = QCLOUD_AT_ERR_TIMEOUT;
goto exit;
}
if (client->resp.status != QCLOUD_AT_RESP_STATUS_OK) {
rc = QCLOUD_AT_ERR_RESP_FAIL;
}
*recv_len = client->resp.recv_len;
exit:
client->resp.expect = NULL;
client->resp.status = QCLOUD_AT_RESP_STATUS_IDLE;
HAL_MutexUnlock(client->resp_lock);
return rc;
}
/**
* @brief Send data to at module.
*
* @param[in] data
* @param[in] data_len
* @return 0 for success
*/
int qcloud_iot_at_client_send_data(const void *data, size_t data_len)
{
QcloudATClient *client = &sg_client;
if (QCLOUD_AT_STATUS_NO_INIT == client->status) {
return QCLOUD_AT_ERR_NO_INIT;
}
return client->at_send_func(data, data_len);
}
/**
* @brief Push data to at client queue.
*
* @param[in] recv_data recv data from uart
* @param[in] data_len recv data length
* @return 0 for success.
*/
int qcloud_iot_at_client_push_data(const void *recv_data, size_t data_len)
{
int rc = 0;
QcloudATClient *client = &sg_client;
if (QCLOUD_AT_STATUS_NO_INIT == client->status) {
return QCLOUD_AT_ERR_NO_INIT;
}
for (size_t i = 0; i < data_len; i++) {
rc = HAL_MailQueueSend(client->recv_queue, (uint8_t *)recv_data + i, 1);
if (rc) {
return QCLOUD_AT_ERR_FAILURE;
}
}
return QCLOUD_AT_RET_SUCCESS;
}

View File

@@ -0,0 +1,259 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_at_client_parse.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-04-27
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-04-27 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_at_client.h"
#include <string.h>
/**
* @brief Max recv timeout.
*
*/
#define MAX_RECV_TIMEOUT 0xffffffffUL
/**
* @brief Get expect len from expect.
*
* @param[in] client pointer to QcloudATClient
*/
static void _at_client_get_expect_len(QcloudATClient *client, uint32_t *expect_len)
{
int len = 0;
if (sscanf(client->recv_buf, client->resp.expect, &len) == 1 &&
client->recv_buf[client->recv_len - 1] == client->resp.expect[strlen(client->resp.expect) - 1]) {
*expect_len = len + client->recv_len;
client->resp.recv_len = len;
}
}
/**
* @brief Read one line for at recv queue.
*
* @param[in] client pointer to QcloudATClient
* @return @see QCloudATErrCode
*/
static int _at_client_readline(QcloudATClient *client)
{
int rc, read_len = 0;
char ch = 0, last_ch = 0;
size_t read_size = 1;
uint32_t expect_len = 0;
memset(client->recv_buf, 0, client->recv_buf_size);
client->recv_len = 0;
while (1) {
rc = HAL_MailQueueRecv(client->recv_queue, &ch, &read_size, MAX_RECV_TIMEOUT);
if (rc) {
Log_e("recv from queue fail, %d", rc);
return QCLOUD_AT_ERR_BUFF_SHORT;
}
if (read_len >= client->recv_buf_size) {
Log_e("read line failed. The line data length is out of buffer size(%d)!", client->recv_buf_size);
client->recv_len = 0;
return QCLOUD_AT_ERR_BUFF_SHORT;
}
client->recv_buf[read_len++] = ch;
client->recv_len = read_len;
// check if using expect string to get length
if (client->resp.recv_buf) {
if (!client->resp.recv_len) {
_at_client_get_expect_len(client, &expect_len);
}
if (expect_len) {
if (expect_len == client->recv_len) {
break;
}
continue;
}
}
if ((ch == '\n' && last_ch == '\r')) {
break;
}
last_ch = ch;
}
client->recv_buf[read_len] = '\0';
return QCLOUD_AT_RET_SUCCESS;
}
/**
* @brief Check urc table.
*
* @param[in] client pointer to QcloudATClient
* @return @see QCloudATErrCode
*/
static int _at_client_check_urc(QcloudATClient *client)
{
int i;
size_t urc_len;
QcloudATUrc *urc;
for (i = 0; i < client->urc_table_size; i++) {
urc = &client->urc_table[i];
urc_len = strlen(urc->urc_prefix);
if (client->recv_len < urc_len) {
continue;
}
if (!strncmp(urc->urc_prefix, client->recv_buf, urc_len)) {
QcloudATUrcRecv urc_recv;
urc_recv.urc = urc;
urc_recv.urc_recv_len = client->recv_len;
urc_recv.urc_handle_buf = HAL_Malloc(client->recv_len + 1);
if (!urc_recv.urc_handle_buf) {
Log_e("malloc urc_handle_buf error.");
return QCLOUD_AT_ERR_FAILURE;
}
memcpy(urc_recv.urc_handle_buf, client->recv_buf, client->recv_len);
urc_recv.urc_handle_buf[client->recv_len] = '\0';
return HAL_MailQueueSend(client->urc_recv_queue, &urc_recv, sizeof(QcloudATUrcRecv));
}
}
return QCLOUD_AT_ERR_FAILURE;
}
/**
* @brief Check at response.
*
* @param[in] client pointer to QcloudATClient
*/
static int _at_client_check_common_resp(QcloudATClient *client)
{
if (!strncmp(client->recv_buf, "OK", 2) && !client->resp.expect) {
client->resp.status = QCLOUD_AT_RESP_STATUS_OK;
return QCLOUD_AT_RET_SUCCESS;
}
if (strstr(client->recv_buf, "ERROR") || !strncmp(client->recv_buf, "FAIL", 4)) {
client->resp.status = QCLOUD_AT_RESP_STATUS_ERROR;
return QCLOUD_AT_ERR_RESP_FAIL;
}
return QCLOUD_AT_ERR_FAILURE;
}
/**
* @brief Check expect response.
*
* @param[in] client pointer to QcloudATClient
* @return @see QCloudATErrCode
*/
static int _at_client_check_expect(QcloudATClient *client)
{
if (!client->resp.expect) {
return QCLOUD_AT_ERR_FAILURE;
}
if (client->resp.recv_buf && client->resp.recv_len) {
memcpy(client->resp.recv_buf, client->recv_buf + client->recv_len - client->resp.recv_len,
client->resp.recv_len);
client->resp.status = QCLOUD_AT_RESP_STATUS_OK;
return QCLOUD_AT_RET_SUCCESS;
}
if (strncmp(client->resp.expect, client->recv_buf, strlen(client->resp.expect))) {
return QCLOUD_AT_ERR_FAILURE;
}
client->resp.status = QCLOUD_AT_RESP_STATUS_OK;
return QCLOUD_AT_RET_SUCCESS;
}
/**
* @brief Parse data recv from at module.
*
* @param[in] client pointer to QcloudATClient
*/
void qcloud_iot_at_client_parser(void *client)
{
int rc;
QcloudATClient *at_client = (QcloudATClient *)client;
while (1) {
rc = _at_client_readline(at_client);
if (rc) {
continue;
}
printf("AT recv <--:%.*s\r\n", at_client->recv_len, at_client->recv_buf);
rc = _at_client_check_urc(at_client);
if (!rc) {
continue;
}
if (QCLOUD_AT_RESP_STATUS_WAIT != at_client->resp.status) {
continue;
}
rc = _at_client_check_expect(at_client);
if (!rc) {
HAL_SemaphorePost(at_client->resp_sem);
continue;
}
rc = _at_client_check_common_resp(at_client);
switch (rc) {
case QCLOUD_AT_RET_SUCCESS:
// if expect, ignore "OK"
if (at_client->resp.expect) {
break;
}
case QCLOUD_AT_ERR_RESP_FAIL:
HAL_SemaphorePost(at_client->resp_sem);
break;
default:
// Log_w("ignore %.*s", at_client->recv_len, at_client->recv_buf);
break;
}
}
}
/**
* @brief Recv urc and callback.
*
* @param[in] client pointer to QcloudATClient
*/
void qcloud_iot_at_urc_handle(void *client)
{
QcloudATClient *at_client = (QcloudATClient *)client;
QcloudATUrcRecv urc_recv;
size_t recv_size = sizeof(QcloudATUrcRecv);
while (1) {
int rc = HAL_MailQueueRecv(at_client->urc_recv_queue, &urc_recv, &recv_size, MAX_RECV_TIMEOUT);
if (rc) {
continue;
}
urc_recv.urc->urc_handle(urc_recv.urc_handle_buf, urc_recv.urc_recv_len);
HAL_Free(urc_recv.urc_handle_buf);
}
}

View File

@@ -0,0 +1,108 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file network_interface.h
* @brief header for network interface
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-05-28
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-05-28 <td>1.0 <td>fancyxu <td>first commit
* <tr><td>2021-07-09 <td>1.1 <td>fancyxu <td>support tls and change port to str format
* </table>
*/
#ifndef IOT_HUB_DEVICE_C_SDK_PLATFORM_NETWORK_INC_NETWORK_INTERFACE_H_
#define IOT_HUB_DEVICE_C_SDK_PLATFORM_NETWORK_INC_NETWORK_INTERFACE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include "qcloud_iot_platform.h"
#ifndef AUTH_WITH_NO_TLS
#include "qcloud_iot_tls_client.h"
#endif
/**
* @brief Type of network interface.
*
*/
typedef enum {
IOT_NETWORK_TYPE_TCP = 0,
IOT_NETWORK_TYPE_UDP,
IOT_NETWORK_TYPE_TLS,
IOT_NETWORK_TYPE_DTLS
} IotNetworkType;
/**
* @brief Define structure for network stack.
*
*/
typedef struct IotNetwork IotNetwork;
/**
* @brief Define structure for network stack.
*
* @note init/connect/read/write/disconnect/state
*
*/
struct IotNetwork {
int (*init)(IotNetwork *);
int (*connect)(IotNetwork *);
int (*read)(IotNetwork *, unsigned char *, size_t, uint32_t, size_t *);
int (*write)(IotNetwork *, unsigned char *, size_t, uint32_t, size_t *);
void (*disconnect)(IotNetwork *);
int (*is_connected)(IotNetwork *);
union {
int fd;
uintptr_t handle;
};
#ifndef AUTH_WITH_NO_TLS
SSLConnectParams ssl_connect_params;
#endif
const char * host; /**< server address */
const char * port; /**< server port */
IotNetworkType type;
};
/**
* @brief Init network, support tcp, tls(if AUTH_WITH_NO_TLS defined).
*
* @param[in,out] network pointer to network
* @return @see IotReturnCode
*/
int qcloud_iot_network_init(IotNetwork *network);
#ifdef __cplusplus
}
#endif
#endif // IOT_HUB_DEVICE_C_SDK_PLATFORM_NETWORK_INC_NETWORK_INTERFACE_H_

View File

@@ -0,0 +1,259 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file network_interface.c
* @brief network interface for tcp/tls
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-05-31
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-05-31 <td>1.0 <td>fancyxu <td>first commit
* <tr><td>2021-07-09 <td>1.1 <td>fancyxu <td>support tls
* </table>
*/
#include "network_interface.h"
/**
* @brief TCP init, do nothing.
*
* @param[in,out] network pointer to network handle
* @return always ok
*/
static int _network_tcp_init(IotNetwork *network)
{
return QCLOUD_RET_SUCCESS;
}
/**
* @brief TCP connect.
*
* @param[in,out] network pointer to network handle
* @return @see IotReturnCode
*/
static int _network_tcp_connect(IotNetwork *network)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
network->fd = HAL_TCP_Connect(network->host, network->port);
if (network->fd < 0) {
Log_e("fail to connect with TCP server: %s:%s", STRING_PTR_PRINT_SANITY_CHECK(network->host),
STRING_PTR_PRINT_SANITY_CHECK(network->port));
return network->fd;
}
if (!strstr(network->host, "gateway.tencentdevices.com") &&
!strstr(network->host, "devicelog.iot.cloud.tencent.com")) { // reduce log info
Log_i("connected with TCP server: %s:%s", STRING_PTR_PRINT_SANITY_CHECK(network->host),
STRING_PTR_PRINT_SANITY_CHECK(network->port));
}
return QCLOUD_RET_SUCCESS;
}
/**
* @brief TCP read.
*
* @param[in,out] network pointer to network handle
* @param[out] data data buffer to be read in
* @param[in] datalen data buffer len
* @param[in] timeout_ms read timeout
* @param[out] read_len read data len
* @return @see IotReturnCode
*/
static int _network_tcp_read(IotNetwork *network, unsigned char *data, size_t datalen, uint32_t timeout_ms,
size_t *read_len)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
return HAL_TCP_Read(network->fd, data, (uint32_t)datalen, timeout_ms, read_len);
}
/**
* @brief TCP write.
*
* @param[in,out] network pointer to network handle
* @param[out] data data buffer to write
* @param[in] datalen data buffer len
* @param[in] timeout_ms write timeout
* @param[out] written_len len of written data
* @return @see IotReturnCode
*/
static int _network_tcp_write(IotNetwork *network, unsigned char *data, size_t datalen, uint32_t timeout_ms,
size_t *written_len)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
return HAL_TCP_Write(network->fd, data, datalen, timeout_ms, written_len);
}
/**
* @brief TCP disconnect
*
* @param[in,out] network pointer to network handle
*/
static void _network_tcp_disconnect(IotNetwork *network)
{
POINTER_SANITY_CHECK_RTN(network);
if (network->fd < 0) {
return;
}
HAL_TCP_Disconnect(network->fd);
network->fd = -1;
return;
}
/**
* @brief Return handle.
*
* @param[in] network pointer to network
* @return handle of network
*/
static int _is_network_tcp_connected(IotNetwork *network)
{
return network->fd > 0;
}
#ifndef AUTH_WITH_NO_TLS
/**
* @brief TLS init, do nothing.
*
* @param[in,out] network pointer to network handle
* @return always ok
*/
static int _network_tls_init(IotNetwork *network)
{
return QCLOUD_RET_SUCCESS;
}
/**
* @brief TLS connect.
*
* @param[in,out] network pointer to network handle
* @return @see IotReturnCode
*/
static int _network_tls_connect(IotNetwork *network)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
network->handle = qcloud_iot_tls_client_connect(&network->ssl_connect_params, network->host, network->port);
return network->handle ? QCLOUD_RET_SUCCESS : QCLOUD_ERR_SSL_CONNECT;
}
/**
* @brief TLS read.
*
* @param[in,out] network pointer to network handle
* @param[out] data data buffer to be read in
* @param[in] datalen data buffer len
* @param[in] timeout_ms read timeout
* @param[out] read_len read data len
* @return @see IotReturnCode
*/
static int _network_tls_read(IotNetwork *network, unsigned char *data, size_t datalen, uint32_t timeout_ms,
size_t *read_len)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
return qcloud_iot_tls_client_read(network->handle, data, datalen, timeout_ms, read_len);
}
/**
* @brief TLS write.
*
* @param[in,out] network pointer to network handle
* @param[out] data data buffer to write
* @param[in] datalen data buffer len
* @param[in] timeout_ms write timeout
* @param[out] written_len len of written data
* @return @see IotReturnCode
*/
static int _network_tls_write(IotNetwork *network, unsigned char *data, size_t datalen, uint32_t timeout_ms,
size_t *written_len)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
return qcloud_iot_tls_client_write(network->handle, data, datalen, timeout_ms, written_len);
}
/**
* @brief TLS disconnect
*
* @param[in,out] network pointer to network handle
*/
static void _network_tls_disconnect(IotNetwork *network)
{
POINTER_SANITY_CHECK_RTN(network);
qcloud_iot_tls_client_disconnect(network->handle);
network->handle = 0;
}
/**
* @brief Return handle.
*
* @param[in] network pointer to network
* @return handle of network
*/
static int _is_network_tls_connected(IotNetwork *network)
{
return network->handle;
}
#endif
/**
* @brief Init network, support tcp, tls(if AUTH_WITH_NO_TLS defined).
*
* @param[in,out] network pointer to network
* @return @see IotReturnCode
*/
int qcloud_iot_network_init(IotNetwork *network)
{
POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
switch (network->type) {
case IOT_NETWORK_TYPE_TCP:
network->init = _network_tcp_init;
network->connect = _network_tcp_connect;
network->read = _network_tcp_read;
network->write = _network_tcp_write;
network->disconnect = _network_tcp_disconnect;
network->is_connected = _is_network_tcp_connected;
network->fd = -1;
break;
#ifndef AUTH_WITH_NO_TLS
case IOT_NETWORK_TYPE_TLS:
network->init = _network_tls_init;
network->connect = _network_tls_connect;
network->read = _network_tls_read;
network->write = _network_tls_write;
network->disconnect = _network_tls_disconnect;
network->is_connected = _is_network_tls_connected;
network->handle = 0;
break;
#endif
default:
Log_e("unknown network type: %d", network->type);
return QCLOUD_ERR_INVAL;
}
return network->init(network);
}

View File

@@ -0,0 +1,112 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file HAL_Device_tencentos_tiny.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-01-24
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-01-24 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "qcloud_iot_platform.h"
#include "qcloud_iot_params_check.h"
/**
* @brief product Id
*
*/
static char sg_product_id[MAX_SIZE_OF_PRODUCT_ID + 1] = "Q5NNWVC2Z8";
/**
* @brief device name
*
*/
static char sg_device_name[MAX_SIZE_OF_DEVICE_NAME + 1] = "test1";
/**
* @brief device secret of PSK device
*
*/
static char sg_device_secret[MAX_SIZE_OF_DEVICE_SECRET + 1] = "jACrR7OalxdQfdJgEduZ3w==";
/**
* @brief Copy device info from src to dst
*
* @param[out] dst dst to copy
* @param[in] src srt to be copied
* @param[in] max_len max_len to be copy
* @return @see IotReturnCode
*/
static int device_info_copy(void *pdst, void *psrc, uint8_t max_len)
{
if (strlen(psrc) > max_len) {
return QCLOUD_ERR_FAILURE;
}
memset(pdst, '\0', max_len);
strncpy(pdst, psrc, max_len);
return QCLOUD_RET_SUCCESS;
}
/**
* @brief Save device info
*
* @param[in] device_info @see DeviceInfo
* @return @see IotReturnCode
*/
int HAL_SetDevInfo(DeviceInfo *device_info)
{
POINTER_SANITY_CHECK(device_info, QCLOUD_ERR_DEV_INFO);
int rc;
rc = device_info_copy(sg_product_id, device_info->product_id, MAX_SIZE_OF_PRODUCT_ID); // set product ID
rc |= device_info_copy(sg_device_name, device_info->device_name, MAX_SIZE_OF_DEVICE_NAME); // set dev name
rc |= device_info_copy(sg_device_secret, device_info->device_secret, MAX_SIZE_OF_DEVICE_SECRET); // set dev secret
if (rc) {
Log_e("Set device info err");
rc = QCLOUD_ERR_DEV_INFO;
}
return rc;
}
/**
* @brief Get device info
*
* @param[in] device_info @see DeviceInfo
* @return @see IotReturnCode
*/
int HAL_GetDevInfo(DeviceInfo *device_info)
{
POINTER_SANITY_CHECK(device_info, QCLOUD_ERR_DEV_INFO);
int ret;
memset(device_info, '\0', sizeof(DeviceInfo));
ret = device_info_copy(device_info->product_id, sg_product_id, MAX_SIZE_OF_PRODUCT_ID); // get product ID
ret |= device_info_copy(device_info->device_name, sg_device_name, MAX_SIZE_OF_DEVICE_NAME); // get dev name
ret |= device_info_copy(device_info->device_secret, sg_device_secret, MAX_SIZE_OF_DEVICE_SECRET); // get dev secret
if (QCLOUD_RET_SUCCESS != ret) {
Log_e("Get device info err");
ret = QCLOUD_ERR_DEV_INFO;
}
return ret;
}

View File

@@ -0,0 +1,76 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file HAL_File_tencentos_tiny.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-04-07
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-04-07 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <stdio.h>
#include <stdlib.h>
#include "qcloud_iot_platform.h"
/**
* @brief Functions for saving file into NVS(files/FLASH)
* @param[in] filename file path name
* @param[in] buf source need write buffer
* @param[in] write_len length of file to write
* @return length of data save when success, or 0 for failure
*/
size_t HAL_File_Write(const char *filename, const void *buf, size_t write_len, size_t offset)
{
return write_len;
}
/**
* @brief Functions for reading file from NVS(files/FLASH)
* @param[in] filename file path name
* @param[in] buf destination log buffer
* @param[in] read_len length to read
* @return length of data read when success, or 0 for failure
*/
size_t HAL_File_Read(const char *filename, void *buf, size_t read_len, size_t offset)
{
return 0;
}
/**
* @brief Functions for deleting file in NVS(files/FLASH).
* @param[in] filename file path name
* @return 0 when success
*/
int HAL_File_Del(const char *filename)
{
return 0;
}
/**
* @brief Functions for reading the size of file in NVS(files/FLASH).
* @param[in] filename file path name
* @return 0 when nothing exist
*/
size_t HAL_File_GetSize(const char *filename)
{
return 0;
}

View File

@@ -0,0 +1,172 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file HAL_AT_Linux.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-04-21
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-04-21 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_platform.h"
#include "qcloud_iot_at_client.h"
#include "tos_hal.h"
#define YOUR_WIFI_SSID "youga_wifi"
#define YOUR_WIFI_PWD "Iot@2018"
static hal_uart_t sg_uart;
/**
* @brief At send function.
*
* @return 0 for success
*/
static int qcloud_iot_usr_at_send(const void *data, size_t data_len)
{
return tos_hal_uart_write(&sg_uart, data, data_len, 0xffffffff);
}
static int _esp8266_init(void)
{
const char *at_cmd_resp[][2] = {
{"AT+RESTORE\r\n", "ready"},
{"ATE0\r\n", NULL},
{"AT+CWMODE=1\r\n", NULL},
{"AT+CIPMODE=0\r\n", NULL},
};
int rc;
for (int i = 0; i < sizeof(at_cmd_resp) / sizeof(const char *) / 2; i++) {
int retry = 3;
do {
rc = HAL_Module_SendAtCmdWaitResp(at_cmd_resp[i][0], at_cmd_resp[i][1], 5000);
} while (rc && retry-- > 0);
if (rc) {
break;
}
}
return rc;
}
/**
* @brief Init at module.
*
* @return 0 for success
*/
int HAL_Module_Init(void)
{
// init at client
int rc = qcloud_iot_at_client_init(2048, qcloud_iot_usr_at_send);
if (rc < 0) {
Log_e("at client init fail");
return rc;
}
// init uart
rc = tos_hal_uart_init(&sg_uart, HAL_UART_PORT_2);
if (rc) {
return rc;
}
// init esp8266
return _esp8266_init();
}
/**
* @brief Deinit at module.
*
*/
void HAL_Module_Deinit(void)
{
return;
}
/**
* @brief Send at cmd to at module and wait for resp.
*
* @param[in] at_cmd at cmd
* @param[in] at_expect expect resp
* @param[in] timeout_ms wait timeout
* @return 0 for success
*/
int HAL_Module_SendAtCmdWaitResp(const char *at_cmd, const char *at_expect, uint32_t timeout_ms)
{
Log_d("at_cmd:%s", at_cmd);
return qcloud_iot_at_client_send_at_util_expect(at_cmd, at_expect, NULL, 0, timeout_ms);
}
/**
* @brief Send at cmd and waif for data.
*
* @param[in] at_cmd at cmd
* @param[in] at_expect expect resp
* @param[out] recv_buf recv data buffer
* @param[out] recv_len recv data length
* @param[in] timeout_ms wait timeout
* @return 0 for success
*/
int HAL_Module_SendAtCmdWaitRespWithData(const char *at_cmd, const char *at_expect, void *recv_buf, uint32_t *recv_len,
uint32_t timeout_ms)
{
return qcloud_iot_at_client_send_at_util_expect(at_cmd, at_expect, recv_buf, recv_len, timeout_ms);
}
/**
* @brief Send date to at module.
*
* @param[in] data data to send
* @param[in] data_len data length
* @return 0 for success
*/
int HAL_Module_SendAtData(const void *data, int data_len)
{
return qcloud_iot_at_client_send_data(data, data_len);
}
/**
* @brief Set urc.
*
* @param[in] urc irc string
* @param[in] urc_handler urc handler
* @return 0 for success
*/
int HAL_Module_SetUrc(const char *urc, OnUrcHandler urc_handler)
{
static QcloudATUrc sg_urc_table[10];
static int sg_urc_table_count;
sg_urc_table[sg_urc_table_count].urc_prefix = urc;
sg_urc_table[sg_urc_table_count].urc_handle = urc_handler;
sg_urc_table_count++;
qcloud_iot_at_client_set_urc(sg_urc_table, sg_urc_table_count);
return 0;
}
/**
* @brief connect network
*
* @return int 0 for success
*/
int HAL_Module_ConnectNetwork(void)
{
return HAL_Module_SendAtCmdWaitResp("AT+CWJAP=\"" YOUR_WIFI_SSID "\",\"" YOUR_WIFI_PWD "\"\r\n", "WIFI GOT IP",
10000);
}

View File

@@ -0,0 +1,373 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file HAL_OS_tencentos_tiny.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-01-24
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-01-24 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "qcloud_iot_platform.h"
#include "tos_k.h"
/**
* @brief Sleep for ms
*
* @param[in] ms ms to sleep
*/
void HAL_SleepMs(uint32_t ms)
{
(void)tos_sleep_hmsm(0, 0, 0, ms);
}
/**
* @brief Printf with format.
*
* @param[in] fmt format
*/
void HAL_Printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
}
/**
* @brief Snprintf with format.
*
* @param[out] str buffer to save
* @param[in] len buffer len
* @param[in] fmt format
* @return length of formatted string, >0 for success.
*/
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;
}
/**
* @brief Malloc from heap.
*
* @param[in] size size to malloc
* @return pointer to buffer, NULL for failed.
*/
void *HAL_Malloc(size_t size)
{
return tos_mmheap_alloc(size);
}
/**
* @brief Free buffer malloced by HAL_Malloc.
*
* @param[in] ptr
*/
void HAL_Free(void *ptr)
{
tos_mmheap_free(ptr);
}
/**
* @brief Mutex create.
*
* @return pointer to mutex
*/
void *HAL_MutexCreate(void)
{
k_mutex_t *mutex;
mutex = (k_mutex_t *)HAL_Malloc(sizeof(k_mutex_t));
if (!mutex) {
return K_NULL;
}
tos_mutex_create(mutex);
return (void *)mutex;
}
/**
* @brief Mutex destroy.
*
* @param[in,out] mutex pointer to mutex
*/
void HAL_MutexDestroy(void *mutex)
{
k_err_t rc;
if (!mutex) {
return;
}
if (K_ERR_NONE != (rc = tos_mutex_destroy((k_mutex_t *)mutex))) {
tos_kprintf("osal_mutex_destroy err, err:%d\n\r", rc);
} else {
HAL_Free((void *)mutex);
}
}
/**
* @brief Mutex lock.
*
* @param[in,out] mutex pointer to mutex
*/
void HAL_MutexLock(void *mutex)
{
k_err_t rc;
if (!mutex) {
return;
}
if (K_ERR_NONE != (rc = tos_mutex_pend((k_mutex_t *)mutex))) {
if (K_ERR_MUTEX_NESTING != rc && K_ERR_PEND_NOWAIT != rc) {
k_task_t *current_task = tos_task_curr_task_get();
tos_kprintf("%s osal_mutex_lock err, err:%d\n\r", current_task->name, rc);
}
}
}
/**
* @brief Mutex try lock.
*
* @param[in,out] mutex pointer to mutex
* @return 0 for success
*/
int HAL_MutexTryLock(void *mutex)
{
k_err_t rc;
if (!mutex) {
return -1;
}
if (K_ERR_NONE != (rc = tos_mutex_pend_timed((k_mutex_t *)mutex, 0))) {
if (K_ERR_MUTEX_NESTING != rc && K_ERR_PEND_NOWAIT != rc) {
tos_kprintf("osal_mutex_lock err, err:%d\n\r", rc);
return (int)rc;
}
}
return 0;
}
/**
* @brief Mutex unlock.
*
* @param[in,out] mutex pointer to mutex
*/
void HAL_MutexUnlock(void *mutex)
{
k_err_t rc;
if (!mutex) {
return;
}
if (K_ERR_NONE != (rc = tos_mutex_post((k_mutex_t *)mutex))) {
if (K_ERR_MUTEX_NESTING != rc && K_ERR_PEND_TIMEOUT != rc) {
tos_kprintf("osal_mutex_unlock err, err:%d\n\r", rc);
}
}
}
/**
* @brief platform-dependent thread create function
*
* @param[in,out] params params to create thread @see ThreadParams
* @return @see IotReturnCode
*/
int HAL_ThreadCreate(ThreadParams *params)
{
params->thread_id = HAL_Malloc(sizeof(k_task_t));
if (!params->thread_id) {
return QCLOUD_ERR_MALLOC;
}
k_prio_t priority = TOS_CFG_TASK_PRIO_MAX - 2;
switch (params->priority) {
case THREAD_PRIORITY_HIGH:
priority = 2;
break;
case THREAD_PRIORITY_MIDDLE:
priority = TOS_CFG_TASK_PRIO_MAX / 2;
break;
case THREAD_PRIORITY_LOW:
priority = TOS_CFG_TASK_PRIO_MAX - 2;
break;
}
return tos_task_create((k_task_t *)params->thread_id, params->thread_name, (k_task_entry_t)params->thread_func,
params->user_arg, priority, params->stack_base, params->stack_size, 20);
}
/**
* @brief platform-dependent thread destroy function.
*
*/
void HAL_ThreadDestroy(void *threadId)
{
// no use in sdk
tos_task_destroy((k_task_t *)threadId);
HAL_Free(threadId);
}
/**
* @brief platform-dependent semaphore create function.
*
* @return pointer to semaphore
*/
void *HAL_SemaphoreCreate(void)
{
k_sem_t *sem = (k_sem_t *)malloc(sizeof(k_sem_t));
if (!sem) {
return NULL;
}
if (0 != tos_sem_create(sem, 0)) {
free(sem);
return NULL;
}
return sem;
}
/**
* @brief platform-dependent semaphore destory function.
*
* @param[in] sem pointer to semaphore
*/
void HAL_SemaphoreDestroy(void *sem)
{
if (!sem) {
return;
}
tos_sem_destroy((k_sem_t *)sem);
free(sem);
}
/**
* @brief platform-dependent semaphore post function.
*
* @param[in] sem pointer to semaphore
*/
void HAL_SemaphorePost(void *sem)
{
if (!sem) {
return;
}
tos_sem_post((k_sem_t *)sem);
}
/**
* @brief platform-dependent semaphore wait function.
*
* @param[in] sem pointer to semaphore
* @param[in] timeout_ms wait timeout
* @return @see IotReturnCode
*/
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms)
{
if (!sem) {
return -1;
}
return tos_sem_pend((k_sem_t *)sem, timeout_ms);
}
/**
* @brief platform-dependent mail queue init function.
*
* @param[in] pool pool using in mail queue
* @param[in] mail_size mail size
* @param[in] mail_count mail count
* @return pointer to mail queue
*/
void *HAL_MailQueueInit(void *pool, size_t mail_size, int mail_count)
{
k_mail_q_t *mail_q = HAL_Malloc(sizeof(k_mail_q_t));
if (!mail_q) {
return NULL;
}
int rc = tos_mail_q_create(mail_q, pool, mail_count, mail_size);
if (rc) {
HAL_Free(mail_q);
return NULL;
}
return mail_q;
}
/**
* @brief platform-dependent mail queue deinit function.
*
* @param[in] mail_q pointer to mail queue
*/
void HAL_MailQueueDeinit(void *mail_q)
{
if (!mail_q) {
return;
}
tos_mail_q_destroy((k_mail_q_t *)mail_q);
HAL_Free(mail_q);
return;
}
/**
* @brief platform-dependent mail queue send function.
*
* @param[in] mail_q pointer to mail queue
* @param[in] buf data buf
* @param[in] size data size
* @return 0 for success
*/
int HAL_MailQueueSend(void *mail_q, const void *buf, size_t size)
{
if (!mail_q) {
return -1;
}
return tos_mail_q_post((k_mail_q_t *)mail_q, (void *)buf, size);
}
/**
* @brief platform-dependent mail queue send function.
*
* @param[in] mail_q pointer to mail queue
* @param[out] buf data buf
* @param[in] size data size
* @param[in] timeout_ms
* @return 0 for success
*/
int HAL_MailQueueRecv(void *mail_q, void *buf, size_t *size, uint32_t timeout_ms)
{
if (!mail_q) {
return -1;
}
return tos_mail_q_pend((k_mail_q_t *)mail_q, buf, size, timeout_ms);
}

View File

@@ -0,0 +1,119 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file HAL_TCP_module.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-01-24
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-01-24 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "qcloud_iot_common.h"
#include "tos_k.h"
#include "sal_module_wrapper.h"
/**
* @brief TCP connect in linux
*
* @param[in] host host to connect
* @param[out] port port to connect
* @return socket fd
*/
int HAL_TCP_Connect(const char *host, const char *port)
{
int fd;
Log_i("osal_tcp_connect entry, host=%s port=%d(%s)", host, port, port);
fd = tos_sal_module_connect(host, port, TOS_SAL_PROTO_TCP);
if (fd < 0) {
Log_i("net connect fail\n\r");
return -1;
}
return fd;
}
/**
* @brief TCP disconnect
*
* @param[in] fd socket fd
* @return 0 for success
*/
int HAL_TCP_Disconnect(int fd)
{
(void)tos_sal_module_close(fd);
return QCLOUD_RET_SUCCESS;
}
/**
* @brief TCP write
*
* @param[in] fd socket fd
* @param[in] buf buf to write
* @param[in] len buf len
* @param[in] timeout_ms timeout
* @param[out] written_len data written length
* @return @see IotReturnCode
*/
int HAL_TCP_Write(int fd, const unsigned char *buf, uint32_t len, uint32_t timeout_ms, size_t *written_len)
{
int ret;
ret = tos_sal_module_send(fd, buf, len);
if (ret < 0) {
return QCLOUD_ERR_TCP_WRITE_FAIL;
}
(*(int *)written_len) = ret;
return QCLOUD_RET_SUCCESS;
}
/**
* @brief TCP read.
*
* @param[in] fd socket fd
* @param[out] buf buffer to save read data
* @param[in] len buffer len
* @param[in] timeout_ms timeout
* @param[out] read_len length of data read
* @return @see IotReturnCode
*/
int HAL_TCP_Read(int fd, unsigned char *buf, uint32_t len, uint32_t timeout_ms, size_t *read_len)
{
int ret;
ret = tos_sal_module_recv_timeout(fd, buf, len, timeout_ms);
if (ret < 0) {
return QCLOUD_ERR_TCP_READ_FAIL;
}
if (ret == 0) {
return QCLOUD_ERR_TCP_NOTHING_TO_READ;
}
(*(int *)read_len) = ret;
return QCLOUD_RET_SUCCESS;
}

View File

@@ -0,0 +1,83 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2022 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file HAL_Timer_tencentos_tiny.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-01-24
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2022-01-24 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "qcloud_iot_platform.h"
#include "tos_k.h"
static uint64_t sg_time_stamp_ms;
static uint64_t _tos_get_systick_ms(void)
{
#if (TOS_CFG_CPU_TICK_PER_SECOND == 1000)
return tos_systick_get();
#else
k_tick_t tick = 0u;
tick = tos_systick_get() * 1000;
return ((tick + TOS_CFG_CPU_TICK_PER_SECOND - 1) / TOS_CFG_CPU_TICK_PER_SECOND);
#endif
}
/**
* @brief Get utc time ms timestamp.
*
* @return timestamp
*/
uint64_t HAL_Timer_CurrentMs(void)
{
return sg_time_stamp_ms + _tos_get_systick_ms();
}
/**
* @brief Time format string.
*
* @return time format string
*/
char *HAL_Timer_Current(void)
{
static char time_stamp[32];
HAL_Snprintf(time_stamp, sizeof(time_stamp), "%llu", HAL_Timer_CurrentMs() / 1000);
return time_stamp;
}
/**
* @brief Set system time using ms timestamp
*
* @param[in] timestamp_ms
* @return 0 for success
*/
int HAL_Timer_SetSystimeMs(uint64_t timestamp_ms)
{
sg_time_stamp_ms = timestamp_ms - _tos_get_systick_ms();
return 0;
}

View File

@@ -0,0 +1,84 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_timer.c
* @brief timer interface
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2022-04-07
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-04-07 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_timer.h"
/**
* @brief Return if timer expired.
*
* @param[in] timer @see QcloudIotTimer
* @return true expired
* @return false no expired
*/
bool IOT_Timer_Expired(QcloudIotTimer *timer)
{
return HAL_Timer_CurrentMs() > *timer ? 1 : 0;
}
/**
* @brief Countdown ms.
*
* @param[in,out] timer @see QcloudIotTimer
* @param[in] timeout_ms ms to count down
*/
void IOT_Timer_CountdownMs(QcloudIotTimer *timer, uint32_t timeout_ms)
{
*timer = HAL_Timer_CurrentMs() + timeout_ms;
}
/**
* @brief Countdown second
*
* @param[in,out] timer @see QcloudIotTimer
* @param[in] timeout second to count down
*/
void IOT_Timer_Countdown(QcloudIotTimer *timer, uint32_t timeout)
{
*timer = HAL_Timer_CurrentMs() + timeout * 1000;
}
/**
* @brief QcloudIotTimer remain ms.
*
* @param[in] timer @see QcloudIotTimer
* @return ms
*/
uint64_t IOT_Timer_Remain(QcloudIotTimer *timer)
{
return *timer <= HAL_Timer_CurrentMs() ? 0 : *timer - HAL_Timer_CurrentMs();
}
/**
* @brief Get current utf timestamp of second
*
* @return timestamp
*/
uint64_t IOT_Timer_CurrentSec(void)
{
return HAL_Timer_CurrentMs() / 1000;
}