feat: 移植腾讯云物联网开发平台 C SDK
This commit is contained in:
@@ -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)
|
@@ -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)
|
@@ -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_
|
@@ -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;
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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_
|
@@ -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);
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user