add new qloud-c-sdk component
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
file(GLOB src
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/network/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,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,267 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* @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 HAL_Device_linux.c
|
||||
* @brief Get and set device info
|
||||
* @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>fix code standard of IotReturnCode
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
/**
|
||||
* @brief Enable this macro (also control by cmake) to use static string buffer to store device info.To use specific
|
||||
* storing methods like files/flash, disable this macro and implement dedicated methods.
|
||||
*
|
||||
*/
|
||||
#ifdef DEBUG_DEV_INFO_USED
|
||||
|
||||
/**
|
||||
* @brief product Id
|
||||
*
|
||||
*/
|
||||
static char sg_product_id[MAX_SIZE_OF_PRODUCT_ID + 1] = "PRODUCT_ID";
|
||||
|
||||
/**
|
||||
* @brief device name
|
||||
*
|
||||
*/
|
||||
static char sg_device_name[MAX_SIZE_OF_DEVICE_NAME + 1] = "DEVICE_NAME";
|
||||
|
||||
#ifdef DEV_DYN_REG_ENABLED
|
||||
/**
|
||||
* @brief product secret for device dynamic Registration
|
||||
*
|
||||
*/
|
||||
static char sg_product_secret[MAX_SIZE_OF_PRODUCT_SECRET + 1] = "YOUR_PRODUCT_SECRET";
|
||||
#endif
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
|
||||
/**
|
||||
* @brief public cert file name of certificate device
|
||||
*
|
||||
*/
|
||||
static char sg_device_cert_file_name[MAX_SIZE_OF_DEVICE_CERT_FILE_NAME + 1] = "YOUR_DEVICE_NAME_cert.crt";
|
||||
|
||||
/**
|
||||
* @brief private key file name of certificate device
|
||||
*
|
||||
*/
|
||||
static char sg_device_privatekey_file_name[MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME + 1] = "YOUR_DEVICE_NAME_private.key";
|
||||
#else
|
||||
/**
|
||||
* @brief device secret of PSK device
|
||||
*
|
||||
*/
|
||||
static char sg_device_secret[MAX_SIZE_OF_DEVICE_SECRET + 1] = "IOT_PSK";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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 *dst, void *src, uint8_t max_len)
|
||||
{
|
||||
if (strlen(src) > max_len) {
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
memset(dst, '\0', max_len);
|
||||
strncpy(dst, src, max_len);
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save device info
|
||||
*
|
||||
* @param[in] dev_info device info to be saved
|
||||
* @return @see IotReturnCode
|
||||
*/
|
||||
int HAL_SetDevInfo(void *dev_info)
|
||||
{
|
||||
POINTER_SANITY_CHECK(dev_info, QCLOUD_ERR_DEV_INFO);
|
||||
int rc;
|
||||
DeviceInfo *device_info = (DeviceInfo *)dev_info;
|
||||
|
||||
#ifdef DEBUG_DEV_INFO_USED
|
||||
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
|
||||
|
||||
#ifdef DEV_DYN_REG_ENABLE
|
||||
rc |= device_info_copy(sg_product_secret, device_info->product_secret, MAX_SIZE_OF_PRODUCT_SECRET);
|
||||
#endif
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
rc |= device_info_copy(sg_device_cert_file_name, device_info->dev_cert_file_name,
|
||||
MAX_SIZE_OF_DEVICE_CERT_FILE_NAME); // set dev cert file name
|
||||
rc |= device_info_copy(sg_device_privatekey_file_name, device_info->dev_key_file_name,
|
||||
MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME); // set dev key file name
|
||||
#else
|
||||
rc |= device_info_copy(sg_device_secret, device_info->device_secret, MAX_SIZE_OF_DEVICE_SECRET); // set dev secret
|
||||
#endif
|
||||
|
||||
#else
|
||||
rc = iot_save_devinfo_to_json_file(device_info);
|
||||
#endif
|
||||
|
||||
if (rc) {
|
||||
Log_e("Set device info err");
|
||||
rc = QCLOUD_ERR_DEV_INFO;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get device info
|
||||
*
|
||||
* @param[in] dev_info buffer to save device info
|
||||
* @return @see IotReturnCode
|
||||
*/
|
||||
int HAL_GetDevInfo(void *dev_info)
|
||||
{
|
||||
POINTER_SANITY_CHECK(dev_info, QCLOUD_ERR_DEV_INFO);
|
||||
|
||||
int rc;
|
||||
DeviceInfo *device_info = (DeviceInfo *)dev_info;
|
||||
memset((char *)device_info, '\0', sizeof(DeviceInfo));
|
||||
|
||||
#ifdef DEBUG_DEV_INFO_USED
|
||||
rc = device_info_copy(device_info->product_id, sg_product_id, MAX_SIZE_OF_PRODUCT_ID); // get product ID
|
||||
rc |= device_info_copy(device_info->device_name, sg_device_name, MAX_SIZE_OF_DEVICE_NAME); // get dev name
|
||||
|
||||
#ifdef DEV_DYN_REG_ENABLED
|
||||
rc |=
|
||||
device_info_copy(device_info->product_secret, sg_product_secret, MAX_SIZE_OF_PRODUCT_SECRET); // get product ID
|
||||
#endif
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
rc |= device_info_copy(device_info->dev_cert_file_name, sg_device_cert_file_name,
|
||||
MAX_SIZE_OF_DEVICE_CERT_FILE_NAME); // get dev cert file name
|
||||
rc |= device_info_copy(device_info->dev_key_file_name, sg_device_privatekey_file_name,
|
||||
MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME); // get dev key file name
|
||||
#else
|
||||
rc |= device_info_copy(device_info->device_secret, sg_device_secret, MAX_SIZE_OF_DEVICE_SECRET); // get dev secret
|
||||
#endif
|
||||
|
||||
#else
|
||||
// get devinfo from file
|
||||
rc = HAL_GetDevInfoFromFile(sg_device_info_file, device_info);
|
||||
#endif
|
||||
|
||||
if (rc) {
|
||||
Log_e("Get device info err");
|
||||
rc = QCLOUD_ERR_DEV_INFO;
|
||||
}
|
||||
return rc;
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @file HAL_File_Linux.c
|
||||
* @author {hubert} ({hubertxxu@tencent.com})
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2022-01-11
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @par Change File:
|
||||
* <table>
|
||||
* Date Version Author Description
|
||||
* 2022-01-11 1.0 hubertxxu first commit
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
/**
|
||||
* @brief Functions for saving file into NVS(files/FLASH)
|
||||
* @param[in] filename file path name
|
||||
* @param[in] write_buffer source need write buffer
|
||||
* @param[in] len length of file to save
|
||||
* @return length of data save when success, or 0 for failure
|
||||
*/
|
||||
size_t HAL_File_Save(const char *filename, const char *write_buffer, size_t write_len)
|
||||
{
|
||||
FILE *fp;
|
||||
size_t len;
|
||||
|
||||
if ((fp = fopen(filename, "a+")) == NULL) {
|
||||
Log_e("fail to open file %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = fwrite((void *)write_buffer, 1, write_len, fp);
|
||||
Log_d("write %ld of %ld to %s file", len, write_len, filename);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Functions for reading file from NVS(files/FLASH)
|
||||
* @param[in] filename file path name
|
||||
* @param[in] buf destination log buffer
|
||||
* @param[in] len length of log to read
|
||||
* @return length of data read when success, or 0 for failure
|
||||
*/
|
||||
size_t HAL_File_Read(const char *filename, char *buff, size_t read_len)
|
||||
{
|
||||
FILE *fp;
|
||||
size_t len;
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
Log_e("fail to open file %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = fread((void *)buff, 1, read_len, fp);
|
||||
Log_d("read %ld of %ld from %s file", len, read_len, filename);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 remove(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_Get_Size(const char *filename)
|
||||
{
|
||||
long length;
|
||||
FILE *fp;
|
||||
|
||||
/* check if file exists */
|
||||
if (access(filename, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
Log_e("fail to open file %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
length = ftell(fp);
|
||||
fclose(fp);
|
||||
|
||||
return length > 0 ? (size_t)length : 0;
|
||||
}
|
@@ -0,0 +1,462 @@
|
||||
/**
|
||||
* @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 HAL_OS_linux.c
|
||||
* @brief Linux os api
|
||||
* @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-08 <td>1.1 <td>fancyxu <td>fix code standard of IotReturnCode
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <memory.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/msg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
/**
|
||||
* @brief Mutex create.
|
||||
*
|
||||
* @return pointer to mutex
|
||||
*/
|
||||
void *HAL_MutexCreate(void)
|
||||
{
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
int err_num;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @ref https://manpages.debian.org/jessie/glibc-doc/pthread_mutex_lock.3.en.html
|
||||
*
|
||||
* If the mutex is already locked by the calling thread, the behavior of pthread_mutex_lock depends on the
|
||||
* kind of the mutex. If the mutex is of the ``fast'' kind, the calling thread is suspended until the mutex is
|
||||
* unlocked, thus effectively causing the calling thread to deadlock. If the mutex is of the ``error checking''
|
||||
* kind, pthread_mutex_lock returns immediately with the error code EDEADLK. If the mutex is of the ``recursive''
|
||||
* kind, pthread_mutex_lock succeeds and returns immediately, recording the number of times the calling thread has
|
||||
* locked the mutex. An equal number of pthread_mutex_unlock operations must be performed before the mutex returns
|
||||
* to the unlocked state.
|
||||
*
|
||||
*/
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
|
||||
pthread_mutex_t *mutex = (pthread_mutex_t *)HAL_Malloc(sizeof(pthread_mutex_t));
|
||||
if (!mutex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err_num = pthread_mutex_init(mutex, &attr);
|
||||
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
|
||||
if (err_num) {
|
||||
HAL_Printf("%s: create mutex failed\n", __FUNCTION__);
|
||||
HAL_Free(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mutex;
|
||||
#else
|
||||
return (void *)0xFFFFFFFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex destroy.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
*/
|
||||
void HAL_MutexDestroy(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
int err_num = pthread_mutex_destroy((pthread_mutex_t *)mutex);
|
||||
if (err_num) {
|
||||
HAL_Printf("%s: destroy mutex failed\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
HAL_Free(mutex);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex lock.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
*/
|
||||
void HAL_MutexLock(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
int err_num = pthread_mutex_lock((pthread_mutex_t *)mutex);
|
||||
if (err_num) {
|
||||
HAL_Printf("%s: lock mutex failed\n", __FUNCTION__);
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex try lock.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_MutexTryLock(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return -1;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
return pthread_mutex_trylock((pthread_mutex_t *)mutex);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex unlock.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
*/
|
||||
void HAL_MutexUnlock(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
int err_num;
|
||||
if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)mutex))) {
|
||||
HAL_Printf("%s: unlock mutex failed\n", __FUNCTION__);
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Malloc from heap.
|
||||
*
|
||||
* @param[in] size size to malloc
|
||||
* @return pointer to buffer, NULL for failed.
|
||||
*/
|
||||
void *HAL_Malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free buffer malloced by HAL_Malloc.
|
||||
*
|
||||
* @param[in] ptr
|
||||
*/
|
||||
void HAL_Free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Sleep for ms
|
||||
*
|
||||
* @param[in] ms ms to sleep
|
||||
*/
|
||||
void HAL_SleepMs(uint32_t ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
}
|
||||
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
|
||||
/**
|
||||
* @brief platform-dependent thread routine/entry function
|
||||
*
|
||||
* @param[in,out] ptr
|
||||
* @return NULL
|
||||
*/
|
||||
static void *_HAL_thread_func_wrapper_(void *ptr)
|
||||
{
|
||||
ThreadParams *params = (ThreadParams *)ptr;
|
||||
|
||||
params->thread_func(params->user_arg);
|
||||
|
||||
pthread_detach(pthread_self());
|
||||
pthread_exit(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent thread create function
|
||||
*
|
||||
* @param[in,out] params params to create thread @see ThreadParams
|
||||
* @return @see IotReturnCode
|
||||
*/
|
||||
int HAL_ThreadCreate(ThreadParams *params)
|
||||
{
|
||||
if (params == NULL)
|
||||
return QCLOUD_ERR_INVAL;
|
||||
|
||||
int rc = pthread_create((pthread_t *)¶ms->thread_id, NULL, _HAL_thread_func_wrapper_, (void *)params);
|
||||
if (rc) {
|
||||
HAL_Printf("%s: pthread_create failed: %d\n", __FUNCTION__, rc);
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent thread destroy function.
|
||||
*
|
||||
*/
|
||||
void HAL_ThreadDestroy(void *thread_id) {}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent semaphore create function.
|
||||
*
|
||||
* @return pointer to semaphore
|
||||
*/
|
||||
void *HAL_SemaphoreCreate(void)
|
||||
{
|
||||
sem_t *sem = (sem_t *)malloc(sizeof(sem_t));
|
||||
if (!sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sem_init(sem, 0, 0)) {
|
||||
free(sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent semaphore destory function.
|
||||
*
|
||||
* @param[in] sem pointer to semaphore
|
||||
*/
|
||||
void HAL_SemaphoreDestroy(void *sem)
|
||||
{
|
||||
sem_destroy((sem_t *)sem);
|
||||
free(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent semaphore post function.
|
||||
*
|
||||
* @param[in] sem pointer to semaphore
|
||||
*/
|
||||
void HAL_SemaphorePost(void *sem)
|
||||
{
|
||||
sem_post((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)
|
||||
{
|
||||
#define PLATFORM_WAIT_INFINITE (~0)
|
||||
|
||||
if (PLATFORM_WAIT_INFINITE == timeout_ms) {
|
||||
sem_wait(sem);
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
} else {
|
||||
struct timespec ts;
|
||||
int s;
|
||||
/* Restart if interrupted by handler */
|
||||
do {
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
s = 0;
|
||||
ts.tv_nsec += (timeout_ms % 1000) * 1000000;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
s = 1;
|
||||
}
|
||||
|
||||
ts.tv_sec += timeout_ms / 1000 + s;
|
||||
|
||||
} while (((s = sem_timedwait(sem, &ts)) != 0) && errno == EINTR);
|
||||
|
||||
return s ? QCLOUD_ERR_FAILURE : QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
#undef PLATFORM_WAIT_INFINITE
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mail queue handle in linux.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int msg_id;
|
||||
size_t msg_size;
|
||||
} MailQueueHandle;
|
||||
|
||||
/**
|
||||
* @brief Mail buffer in linux.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
long int type;
|
||||
uint8_t data[2048];
|
||||
} MailBuffer;
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
static key_t sg_mail_key = 1234;
|
||||
|
||||
MailQueueHandle *handle = HAL_Malloc(sizeof(MailQueueHandle));
|
||||
if (!handle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->msg_id = msgget(sg_mail_key++, 0666 | IPC_CREAT);
|
||||
if (handle->msg_id == -1) {
|
||||
HAL_Free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->msg_size = mail_size;
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent mail queue deinit function.
|
||||
*
|
||||
* @param[in] mail_q pointer to mail queue
|
||||
*/
|
||||
void HAL_MailQueueDeinit(void *mail_q)
|
||||
{
|
||||
MailQueueHandle *handle = (MailQueueHandle *)mail_q;
|
||||
msgctl(handle->msg_id, IPC_RMID, 0);
|
||||
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, void *buf, size_t size)
|
||||
{
|
||||
MailQueueHandle *handle = (MailQueueHandle *)mail_q;
|
||||
MailBuffer data;
|
||||
memset(&data, 0, sizeof(MailBuffer));
|
||||
data.type = 1;
|
||||
memcpy(data.data, buf, size);
|
||||
return msgsnd(handle->msg_id, &data, size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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, int timeout_ms)
|
||||
{
|
||||
MailQueueHandle *handle = (MailQueueHandle *)mail_q;
|
||||
MailBuffer data;
|
||||
memset(&data, 0, sizeof(MailBuffer));
|
||||
data.type = 1;
|
||||
*size = handle->msg_size;
|
||||
int rc = msgrcv(handle->msg_id, &data, handle->msg_size, 0, 0);
|
||||
memcpy(buf, data.data, handle->msg_size);
|
||||
return rc < 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* @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 HAL_TCP_linux.c
|
||||
* @brief Linux tcp api
|
||||
* @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>refactor for support tls, change port to str format
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "qcloud_iot_platform.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)
|
||||
{
|
||||
// to avoid process crash when writing to a broken socket
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
int rc;
|
||||
int fd = 0;
|
||||
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
rc = getaddrinfo(host, port, &hints, &addr_list);
|
||||
if (rc) {
|
||||
Log_e("getaddrinfo(%s:%s) error: %s", STRING_PTR_PRINT_SANITY_CHECK(host), STRING_PTR_PRINT_SANITY_CHECK(port),
|
||||
rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
|
||||
return QCLOUD_ERR_TCP_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
for (cur = addr_list; cur; cur = cur->ai_next) {
|
||||
fd = (int)socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
|
||||
if (fd < 0) {
|
||||
rc = QCLOUD_ERR_TCP_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
|
||||
if (rc) {
|
||||
Log_e("set socket non block faliled %d", rc);
|
||||
close(fd);
|
||||
rc = QCLOUD_ERR_TCP_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = connect(fd, cur->ai_addr, cur->ai_addrlen);
|
||||
if (!rc) {
|
||||
rc = fd;
|
||||
break;
|
||||
}
|
||||
|
||||
if (errno == EINPROGRESS) {
|
||||
// IO select to wait for connect result
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT / 1000;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
fd_set sets;
|
||||
FD_ZERO(&sets);
|
||||
FD_SET(fd, &sets);
|
||||
|
||||
rc = select(fd + 1, NULL, &sets, NULL, &timeout);
|
||||
if (rc > 0) {
|
||||
int so_error;
|
||||
socklen_t len = sizeof(so_error);
|
||||
getsockopt(fd, SOL_SOCKET, SO_ERROR, &so_error, &len);
|
||||
if (FD_ISSET(fd, &sets) && so_error == 0) {
|
||||
rc = fd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
rc = QCLOUD_ERR_TCP_CONNECT;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr_list);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TCP disconnect
|
||||
*
|
||||
* @param[in] fd socket fd
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_TCP_Disconnect(int fd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Shutdown both send and receive operations. */
|
||||
rc = shutdown(fd, 2);
|
||||
if (rc) {
|
||||
Log_e("shutdown error: %s", strerror(errno));
|
||||
}
|
||||
|
||||
rc = close(fd);
|
||||
if (rc) {
|
||||
Log_e("closesocket error: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 uint8_t *buf, uint32_t len, uint32_t timeout_ms, size_t *written_len)
|
||||
{
|
||||
int rc = 0;
|
||||
uint32_t len_sent;
|
||||
Timer timer_send;
|
||||
fd_set sets;
|
||||
struct timeval timeout;
|
||||
|
||||
HAL_Timer_CountdownMs(&timer_send, timeout_ms);
|
||||
len_sent = 0;
|
||||
|
||||
/* send one time if timeout_ms is value 0 */
|
||||
while ((len_sent < len) && !HAL_Timer_Expired(&timer_send)) {
|
||||
timeout.tv_sec = HAL_Timer_Remain(&timer_send) / 1000;
|
||||
timeout.tv_usec = HAL_Timer_Remain(&timer_send) % 1000 * 1000;
|
||||
|
||||
FD_ZERO(&sets);
|
||||
FD_SET(fd, &sets);
|
||||
|
||||
rc = select(fd + 1, NULL, &sets, NULL, &timeout);
|
||||
if (!rc) {
|
||||
rc = QCLOUD_ERR_TCP_WRITE_TIMEOUT;
|
||||
Log_e("select-write timeout %d", (int)fd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
if (EINTR != errno) {
|
||||
rc = QCLOUD_ERR_TCP_WRITE_FAIL;
|
||||
Log_e("select-write fail: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
Log_e("EINTR be caught");
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = send(fd, buf + len_sent, len - len_sent, 0);
|
||||
if (rc < 0) {
|
||||
if (EINTR == errno) {
|
||||
Log_e("EINTR be caught");
|
||||
continue;
|
||||
}
|
||||
rc = (EPIPE == errno || ECONNRESET == errno) ? QCLOUD_ERR_TCP_PEER_SHUTDOWN : QCLOUD_ERR_TCP_WRITE_FAIL;
|
||||
Log_e("send fail: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
len_sent += rc;
|
||||
}
|
||||
|
||||
*written_len = (size_t)len_sent;
|
||||
// We always know hom much should write.
|
||||
return len_sent == len ? QCLOUD_RET_SUCCESS : rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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, uint8_t *buf, uint32_t len, uint32_t timeout_ms, size_t *read_len)
|
||||
{
|
||||
int rc;
|
||||
uint32_t len_recv;
|
||||
Timer timer_recv;
|
||||
fd_set sets;
|
||||
struct timeval timeout;
|
||||
|
||||
HAL_Timer_CountdownMs(&timer_recv, timeout_ms);
|
||||
len_recv = 0;
|
||||
|
||||
do {
|
||||
FD_ZERO(&sets);
|
||||
FD_SET(fd, &sets);
|
||||
|
||||
timeout.tv_sec = HAL_Timer_Remain(&timer_recv) / 1000;
|
||||
timeout.tv_usec = HAL_Timer_Remain(&timer_recv) % 1000 * 1000;
|
||||
|
||||
rc = select(fd + 1, &sets, NULL, NULL, &timeout);
|
||||
if (!rc) {
|
||||
rc = QCLOUD_ERR_TCP_READ_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
if (EINTR != errno) {
|
||||
rc = QCLOUD_ERR_TCP_READ_FAIL;
|
||||
Log_e("select-recv fail: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
Log_e("EINTR be caught");
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = recv(fd, buf + len_recv, len - len_recv, 0);
|
||||
if (rc <= 0) {
|
||||
if (!rc) {
|
||||
Log_e("connection is closed by server");
|
||||
rc = QCLOUD_ERR_TCP_PEER_SHUTDOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EINTR == errno) {
|
||||
Log_e("EINTR be caught");
|
||||
continue;
|
||||
}
|
||||
Log_e("recv error: %s", strerror(errno));
|
||||
rc = (EPIPE == errno || ECONNRESET == errno) ? QCLOUD_ERR_TCP_PEER_SHUTDOWN : QCLOUD_ERR_TCP_READ_FAIL;
|
||||
break;
|
||||
}
|
||||
len_recv += rc;
|
||||
} while (len_recv < len);
|
||||
|
||||
*read_len = (size_t)len_recv;
|
||||
|
||||
if (rc == QCLOUD_ERR_TCP_READ_TIMEOUT && len_recv == 0) {
|
||||
rc = QCLOUD_ERR_TCP_NOTHING_TO_READ;
|
||||
}
|
||||
// We always don't know hom much should read.
|
||||
return (len_recv > 0) ? QCLOUD_RET_SUCCESS : rc;
|
||||
}
|
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* @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 HAL_Timer_linux.c
|
||||
* @brief Linux timer function
|
||||
* @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
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
#define HAL_TIMESPEC_TO_TIMEVAL(ts, tv) \
|
||||
{ \
|
||||
tv.tv_sec = ts.tv_sec; \
|
||||
tv.tv_usec = ts.tv_nsec / 1000; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if timer expired.
|
||||
*
|
||||
* @param[in] timer @see Timer
|
||||
* @return true expired
|
||||
* @return false no expired
|
||||
*/
|
||||
bool HAL_Timer_Expired(Timer *timer)
|
||||
{
|
||||
struct timeval now, res;
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
HAL_TIMESPEC_TO_TIMEVAL(ts, now);
|
||||
timersub(&timer->end_time, &now, &res);
|
||||
return res.tv_sec < 0 || (res.tv_sec == 0 && res.tv_usec <= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Countdown ms.
|
||||
*
|
||||
* @param[in,out] timer @see Timer
|
||||
* @param[in] timeout_ms ms to count down
|
||||
*/
|
||||
void HAL_Timer_CountdownMs(Timer *timer, unsigned int timeout_ms)
|
||||
{
|
||||
struct timeval now;
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
HAL_TIMESPEC_TO_TIMEVAL(ts, now);
|
||||
struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
|
||||
timeradd(&now, &interval, &timer->end_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Countdown second
|
||||
*
|
||||
* @param[in,out] timer @see Timer
|
||||
* @param[in] timeout second to count down
|
||||
*/
|
||||
void HAL_Timer_Countdown(Timer *timer, unsigned int timeout)
|
||||
{
|
||||
struct timeval now;
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
HAL_TIMESPEC_TO_TIMEVAL(ts, now);
|
||||
struct timeval interval = {timeout, 0};
|
||||
timeradd(&now, &interval, &timer->end_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Timer remain ms.
|
||||
*
|
||||
* @param[in] timer @see Timer
|
||||
* @return ms
|
||||
*/
|
||||
uint32_t HAL_Timer_Remain(Timer *timer)
|
||||
{
|
||||
struct timeval now, res;
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
HAL_TIMESPEC_TO_TIMEVAL(ts, now);
|
||||
timersub(&timer->end_time, &now, &res);
|
||||
return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief time format string
|
||||
*
|
||||
* @return time format string, such as "2021-05-31 15:58:46"
|
||||
*/
|
||||
char *HAL_Timer_Current(void)
|
||||
{
|
||||
static char time_str[20];
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
time_t now_time = tv.tv_sec;
|
||||
|
||||
struct tm tm_tmp = *localtime(&now_time);
|
||||
strftime(time_str, sizeof(time_str), "%F %T", &tm_tmp);
|
||||
return time_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current utf timestamp of second
|
||||
*
|
||||
* @return timestamp
|
||||
*/
|
||||
uint32_t HAL_Timer_CurrentSec(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get utc time ms timestamp.
|
||||
*
|
||||
* @return timestamp
|
||||
*/
|
||||
uint64_t HAL_Timer_CurrentMs(void)
|
||||
{
|
||||
struct timeval time_val = {0};
|
||||
uint64_t time_ms;
|
||||
|
||||
gettimeofday(&time_val, NULL);
|
||||
time_ms = time_val.tv_sec * 1000 + time_val.tv_usec / 1000;
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set system time using second timestamp
|
||||
*
|
||||
* @param[in] timestamp_sec timestamp to set
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_Timer_SetSystimeSec(uint32_t timestamp_sec)
|
||||
{
|
||||
struct timeval stime;
|
||||
stime.tv_sec = timestamp_sec;
|
||||
stime.tv_usec = 0;
|
||||
return settimeofday(&stime, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set system time using ms timestamp
|
||||
*
|
||||
* @param[in] timestamp_ms
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_Timer_SetSystimeMs(uint64_t timestamp_ms)
|
||||
{
|
||||
struct timeval stime;
|
||||
stime.tv_sec = (timestamp_ms / 1000);
|
||||
stime.tv_usec = ((timestamp_ms % 1000) * 1000);
|
||||
return settimeofday(&stime, NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* @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 HAL_Device_linux.c
|
||||
* @brief Get and set device info
|
||||
* @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>fix code standard of IotReturnCode
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
/**
|
||||
* @brief Enable this macro (also control by cmake) to use static string buffer to store device info.To use specific
|
||||
* storing methods like files/flash, disable this macro and implement dedicated methods.
|
||||
*
|
||||
*/
|
||||
#ifdef DEBUG_DEV_INFO_USED
|
||||
|
||||
/**
|
||||
* @brief product Id
|
||||
*
|
||||
*/
|
||||
static char sg_product_id[MAX_SIZE_OF_PRODUCT_ID + 1] = "FWR8PGACUS";
|
||||
|
||||
/**
|
||||
* @brief device name
|
||||
*
|
||||
*/
|
||||
static char sg_device_name[MAX_SIZE_OF_DEVICE_NAME + 1] = "dev001";
|
||||
|
||||
#ifdef DEV_DYN_REG_ENABLED
|
||||
/**
|
||||
* @brief product secret for device dynamic Registration
|
||||
*
|
||||
*/
|
||||
static char sg_product_secret[MAX_SIZE_OF_PRODUCT_SECRET + 1] = "YOUR_PRODUCT_SECRET";
|
||||
#endif
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
|
||||
/**
|
||||
* @brief public cert file name of certificate device
|
||||
*
|
||||
*/
|
||||
static char sg_device_cert_file_name[MAX_SIZE_OF_DEVICE_CERT_FILE_NAME + 1] = "YOUR_DEVICE_NAME_cert.crt";
|
||||
|
||||
/**
|
||||
* @brief private key file name of certificate device
|
||||
*
|
||||
*/
|
||||
static char sg_device_privatekey_file_name[MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME + 1] = "YOUR_DEVICE_NAME_private.key";
|
||||
#else
|
||||
/**
|
||||
* @brief device secret of PSK device
|
||||
*
|
||||
*/
|
||||
static char sg_device_secret[MAX_SIZE_OF_DEVICE_SECRET + 1] = "XIBjgofTv/QEQTlRTDQnGg==";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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 *dst, void *src, uint8_t max_len)
|
||||
{
|
||||
if (strlen(src) > max_len) {
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
memset(dst, '\0', max_len);
|
||||
strncpy(dst, src, max_len);
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save device info
|
||||
*
|
||||
* @param[in] dev_info device info to be saved
|
||||
* @return @see IotReturnCode
|
||||
*/
|
||||
int HAL_SetDevInfo(void *dev_info)
|
||||
{
|
||||
POINTER_SANITY_CHECK(dev_info, QCLOUD_ERR_DEV_INFO);
|
||||
int rc;
|
||||
DeviceInfo *device_info = (DeviceInfo *)dev_info;
|
||||
|
||||
#ifdef DEBUG_DEV_INFO_USED
|
||||
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
|
||||
|
||||
#ifdef DEV_DYN_REG_ENABLE
|
||||
rc |= device_info_copy(sg_product_secret, device_info->product_secret, MAX_SIZE_OF_PRODUCT_SECRET);
|
||||
#endif
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
rc |= device_info_copy(sg_device_cert_file_name, device_info->dev_cert_file_name,
|
||||
MAX_SIZE_OF_DEVICE_CERT_FILE_NAME); // set dev cert file name
|
||||
rc |= device_info_copy(sg_device_privatekey_file_name, device_info->dev_key_file_name,
|
||||
MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME); // set dev key file name
|
||||
#else
|
||||
rc |= device_info_copy(sg_device_secret, device_info->device_secret, MAX_SIZE_OF_DEVICE_SECRET); // set dev secret
|
||||
#endif
|
||||
|
||||
#else
|
||||
rc = iot_save_devinfo_to_json_file(device_info);
|
||||
#endif
|
||||
|
||||
if (rc) {
|
||||
Log_e("Set device info err");
|
||||
rc = QCLOUD_ERR_DEV_INFO;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get device info
|
||||
*
|
||||
* @param[in] dev_info buffer to save device info
|
||||
* @return @see IotReturnCode
|
||||
*/
|
||||
int HAL_GetDevInfo(void *dev_info)
|
||||
{
|
||||
POINTER_SANITY_CHECK(dev_info, QCLOUD_ERR_DEV_INFO);
|
||||
|
||||
int rc;
|
||||
DeviceInfo *device_info = (DeviceInfo *)dev_info;
|
||||
memset((char *)device_info, '\0', sizeof(DeviceInfo));
|
||||
|
||||
#ifdef DEBUG_DEV_INFO_USED
|
||||
rc = device_info_copy(device_info->product_id, sg_product_id, MAX_SIZE_OF_PRODUCT_ID); // get product ID
|
||||
rc |= device_info_copy(device_info->device_name, sg_device_name, MAX_SIZE_OF_DEVICE_NAME); // get dev name
|
||||
|
||||
#ifdef DEV_DYN_REG_ENABLED
|
||||
rc |=
|
||||
device_info_copy(device_info->product_secret, sg_product_secret, MAX_SIZE_OF_PRODUCT_SECRET); // get product ID
|
||||
#endif
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
rc |= device_info_copy(device_info->dev_cert_file_name, sg_device_cert_file_name,
|
||||
MAX_SIZE_OF_DEVICE_CERT_FILE_NAME); // get dev cert file name
|
||||
rc |= device_info_copy(device_info->dev_key_file_name, sg_device_privatekey_file_name,
|
||||
MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME); // get dev key file name
|
||||
#else
|
||||
rc |= device_info_copy(device_info->device_secret, sg_device_secret, MAX_SIZE_OF_DEVICE_SECRET); // get dev secret
|
||||
#endif
|
||||
|
||||
#else
|
||||
// get devinfo from file
|
||||
rc = HAL_GetDevInfoFromFile(sg_device_info_file, device_info);
|
||||
#endif
|
||||
|
||||
if (rc) {
|
||||
Log_e("Get device info err");
|
||||
rc = QCLOUD_ERR_DEV_INFO;
|
||||
}
|
||||
return rc;
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @file HAL_File_Linux.c
|
||||
* @author {hubert} ({hubertxxu@tencent.com})
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2022-01-11
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @par Change File:
|
||||
* <table>
|
||||
* Date Version Author Description
|
||||
* 2022-01-11 1.0 hubertxxu first commit
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
/**
|
||||
* @brief Functions for saving file into NVS(files/FLASH)
|
||||
* @param[in] filename file path name
|
||||
* @param[in] write_buffer source need write buffer
|
||||
* @param[in] len length of file to save
|
||||
* @return length of data save when success, or 0 for failure
|
||||
*/
|
||||
size_t HAL_File_Save(const char *filename, const char *write_buffer, size_t write_len)
|
||||
{
|
||||
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] len length of log to read
|
||||
* @return length of data read when success, or 0 for failure
|
||||
*/
|
||||
size_t HAL_File_Read(const char *filename, char *buff, size_t read_len)
|
||||
{
|
||||
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_Get_Size(const char *filename)
|
||||
{
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,392 @@
|
||||
/**
|
||||
* @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 HAL_OS_linux.c
|
||||
* @brief Linux os api
|
||||
* @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-08 <td>1.1 <td>fancyxu <td>fix code standard of IotReturnCode
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
/**
|
||||
* @brief Mutex create.
|
||||
*
|
||||
* @return pointer to mutex
|
||||
*/
|
||||
void *HAL_MutexCreate(void)
|
||||
{
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
k_err_t ret;
|
||||
|
||||
k_mutex_t *mutex = (k_mutex_t *)HAL_Malloc(sizeof(k_mutex_t));
|
||||
if (!mutex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = tos_mutex_create(mutex);
|
||||
if (ret != K_ERR_NONE) {
|
||||
HAL_Free(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mutex;
|
||||
#else
|
||||
return (void *)0xFFFFFFFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex destroy.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
*/
|
||||
void HAL_MutexDestroy(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
k_err_t err = tos_mutex_destroy((k_mutex_t *)mutex);
|
||||
if (err != K_ERR_NONE) {
|
||||
}
|
||||
|
||||
HAL_Free(mutex);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex lock.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
*/
|
||||
void HAL_MutexLock(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
k_err_t err = tos_mutex_pend((k_mutex_t *)mutex);
|
||||
if (err != K_ERR_NONE && err != K_ERR_MUTEX_NESTING) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex try lock.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_MutexTryLock(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return -1;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
k_err_t err = tos_mutex_pend_timed((k_mutex_t *)mutex, 0);
|
||||
if (err != K_ERR_NONE && err != K_ERR_MUTEX_NESTING) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mutex unlock.
|
||||
*
|
||||
* @param[in,out] mutex pointer to mutex
|
||||
*/
|
||||
void HAL_MutexUnlock(void *mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
k_err_t err = tos_mutex_post((k_mutex_t *)mutex);
|
||||
if (err != K_ERR_NONE && err != K_ERR_MUTEX_NESTING) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
if (ptr)
|
||||
tos_mmheap_free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Sleep for ms
|
||||
*
|
||||
* @param[in] ms ms to sleep
|
||||
*/
|
||||
void HAL_SleepMs(uint32_t ms)
|
||||
{
|
||||
tos_sleep_ms(ms);
|
||||
}
|
||||
|
||||
#ifdef MULTITHREAD_ENABLED
|
||||
|
||||
/**
|
||||
* @brief platform-dependent thread create function
|
||||
*
|
||||
* @param[in,out] params params to create thread @see ThreadParams
|
||||
* @return @see IotReturnCode
|
||||
*/
|
||||
int HAL_ThreadCreate(ThreadParams *params)
|
||||
{
|
||||
if (params == NULL)
|
||||
return QCLOUD_ERR_INVAL;
|
||||
|
||||
k_err_t err;
|
||||
|
||||
params->thread_id = (k_task_t *)HAL_Malloc(sizeof(k_task_t *));
|
||||
if (params->thread_id == NULL) {
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
err = tos_task_create((k_task_t *)¶ms->thread_id, params->thread_name, params->thread_func, (void *)params->user_arg,
|
||||
params->priority, (k_stack_t *)params->stack_base, (size_t)params->stack_size, 0);
|
||||
if (err != K_ERR_NONE) {
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent thread destroy function.
|
||||
*
|
||||
*/
|
||||
void HAL_ThreadDestroy(void *thread_id) {
|
||||
|
||||
tos_task_destroy((k_task_t *)thread_id);
|
||||
|
||||
HAL_Free(thread_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent semaphore create function.
|
||||
*
|
||||
* @return pointer to semaphore
|
||||
*/
|
||||
void *HAL_SemaphoreCreate(void)
|
||||
{
|
||||
k_sem_t *sem = (k_sem_t *)HAL_Malloc(sizeof(k_sem_t));
|
||||
if (!sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tos_sem_create(sem, 0)) {
|
||||
HAL_Free(sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent semaphore destory function.
|
||||
*
|
||||
* @param[in] sem pointer to semaphore
|
||||
*/
|
||||
void HAL_SemaphoreDestroy(void *sem)
|
||||
{
|
||||
tos_sem_destroy((k_sem_t *)sem);
|
||||
HAL_Free(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief platform-dependent semaphore post function.
|
||||
*
|
||||
* @param[in] sem pointer to semaphore
|
||||
*/
|
||||
void HAL_SemaphorePost(void *sem)
|
||||
{
|
||||
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)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
err = tos_sem_pend(sem, timeout_ms);
|
||||
|
||||
return err == K_ERR_NONE ? QCLOUD_RET_SUCCESS : QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mail buffer in tos.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
long int type;
|
||||
uint8_t data[2048];
|
||||
} MailBuffer;
|
||||
|
||||
/**
|
||||
* @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_err_t err;
|
||||
k_mail_q_t *mail_q;
|
||||
|
||||
mail_q = HAL_Malloc(sizeof(k_mail_q_t));
|
||||
if (!mail_q) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = tos_mail_q_create(mail_q, pool, mail_count, mail_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
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)
|
||||
{
|
||||
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, void *buf, size_t size)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
err = tos_mail_q_post(mail_q, buf, size);
|
||||
|
||||
return err == K_ERR_NONE ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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, int timeout_ms)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
err = tos_mail_q_pend((k_mail_q_t *)mail_q, buf, size, timeout_ms);
|
||||
|
||||
return err == K_ERR_NONE ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @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 HAL_TCP_linux.c
|
||||
* @brief Linux tcp api
|
||||
* @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>refactor for support tls, change port to str format
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include "sal_module_wrapper.h"
|
||||
#include "qcloud_iot_platform.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 rc;
|
||||
int fd = 0;
|
||||
char host_ip[32];
|
||||
|
||||
rc = tos_sal_module_parse_domain(host, host_ip, 32);
|
||||
if (rc < 0) {
|
||||
return QCLOUD_ERR_TCP_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
fd = tos_sal_module_connect(host_ip, port, TOS_SAL_PROTO_TCP);
|
||||
if (fd < 0) {
|
||||
return QCLOUD_ERR_TCP_CONNECT;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TCP disconnect
|
||||
*
|
||||
* @param[in] fd socket fd
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_TCP_Disconnect(int fd)
|
||||
{
|
||||
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 uint8_t *buf, uint32_t len, uint32_t timeout_ms, size_t *written_len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = tos_sal_module_send(fd, buf, len);
|
||||
if (ret < 0) {
|
||||
ret = QCLOUD_ERR_TCP_WRITE_FAIL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(int *)written_len = ret;
|
||||
// We always know hom much should write.
|
||||
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, uint8_t *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;
|
||||
} else if (ret == 0) {
|
||||
return QCLOUD_ERR_TCP_NOTHING_TO_READ;
|
||||
}
|
||||
|
||||
*(int *)read_len = ret;
|
||||
|
||||
// We always don't know hom much should read.
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @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 HAL_Timer_linux.c
|
||||
* @brief Linux timer function
|
||||
* @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
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
#include "qcloud_iot_platform.h"
|
||||
|
||||
#define HAL_TIMESPEC_TO_TIMEVAL(ts, tv) \
|
||||
{ \
|
||||
tv.tv_sec = ts.tv_sec; \
|
||||
tv.tv_usec = ts.tv_nsec / 1000; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if timer expired.
|
||||
*
|
||||
* @param[in] timer @see Timer
|
||||
* @return true expired
|
||||
* @return false no expired
|
||||
*/
|
||||
bool HAL_Timer_Expired(Timer *timer)
|
||||
{
|
||||
k_tick_t now;
|
||||
|
||||
now = tos_systick_get();
|
||||
|
||||
return now >= timer->end_time ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Countdown ms.
|
||||
*
|
||||
* @param[in,out] timer @see Timer
|
||||
* @param[in] timeout_ms ms to count down
|
||||
*/
|
||||
void HAL_Timer_CountdownMs(Timer *timer, unsigned int timeout_ms)
|
||||
{
|
||||
k_tick_t tick;
|
||||
k_tick_t now;
|
||||
|
||||
tick = tos_millisec2tick(timeout_ms);
|
||||
now = tos_systick_get();
|
||||
|
||||
timer->end_time = now + tick;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Countdown second
|
||||
*
|
||||
* @param[in,out] timer @see Timer
|
||||
* @param[in] timeout second to count down
|
||||
*/
|
||||
void HAL_Timer_Countdown(Timer *timer, unsigned int timeout)
|
||||
{
|
||||
k_tick_t now;
|
||||
k_tick_t tick;
|
||||
|
||||
tick = timeout * TOS_CFG_CPU_TICK_PER_SECOND;
|
||||
now = tos_systick_get();
|
||||
|
||||
timer->end_time = now + tick;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Timer remain ms.
|
||||
*
|
||||
* @param[in] timer @see Timer
|
||||
* @return ms
|
||||
*/
|
||||
uint32_t HAL_Timer_Remain(Timer *timer)
|
||||
{
|
||||
k_tick_t now;
|
||||
|
||||
now = tos_systick_get();
|
||||
if (now >= timer->end_time) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
now = tos_systick_get();
|
||||
|
||||
return (k_time_t)(((timer->end_time) - now + TOS_CFG_CPU_TICK_PER_SECOND - 1) / TOS_CFG_CPU_TICK_PER_SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief time format string
|
||||
*
|
||||
* @return time format string, such as "2021-05-31 15:58:46"
|
||||
*/
|
||||
char *HAL_Timer_Current(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current utf timestamp of second
|
||||
*
|
||||
* @return timestamp
|
||||
*/
|
||||
uint32_t HAL_Timer_CurrentSec(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get utc time ms timestamp.
|
||||
*
|
||||
* @return timestamp
|
||||
*/
|
||||
uint64_t HAL_Timer_CurrentMs(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set system time using second timestamp
|
||||
*
|
||||
* @param[in] timestamp_sec timestamp to set
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_Timer_SetSystimeSec(uint32_t timestamp_sec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set system time using ms timestamp
|
||||
*
|
||||
* @param[in] timestamp_ms
|
||||
* @return 0 for success
|
||||
*/
|
||||
int HAL_Timer_SetSystimeMs(uint64_t timestamp_ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user