add new qloud-c-sdk component

This commit is contained in:
mculover666
2022-03-25 10:06:56 +08:00
parent 565cd29e94
commit a3ac2e56d8
166 changed files with 35027 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 *)&params->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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 *)&params->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

View File

@@ -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;
}

View File

@@ -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