9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
338 lines
6.8 KiB
C
338 lines
6.8 KiB
C
#include "iotx_cm_internal.h"
|
|
|
|
#if defined(MQTT_COMM_ENABLED) || defined(MAL_ENABLED)
|
|
#include "iotx_cm_mqtt.h"
|
|
#endif
|
|
#ifdef COAP_COMM_ENABLED
|
|
#include "iotx_cm_coap.h"
|
|
#endif
|
|
|
|
static void *fd_lock = NULL;
|
|
static iotx_cm_connection_t *_cm_fd[CM_MAX_FD_NUM] = {NULL};
|
|
static int _get_fd(iotx_cm_connection_t *handle);
|
|
static int _recycle_fd(int fd);
|
|
static int inline _fd_is_valid(int fd);
|
|
static int inited_conn_num = 0;
|
|
|
|
#ifdef DEVICE_MODEL_MULTI_THREAD
|
|
static void *_iotx_cm_yield_thread_func(void *params);
|
|
static void *yield_thread = NULL;
|
|
static int yield_task_leave = 1;
|
|
#endif
|
|
|
|
const char ERR_INVALID_PARAMS[] = "invalid parameter";
|
|
int iotx_cm_open(iotx_cm_init_param_t *params)
|
|
{
|
|
int fd;
|
|
iotx_cm_connection_t *connection = NULL;
|
|
|
|
switch (params->protocol_type)
|
|
{
|
|
case IOTX_CM_PROTOCOL_TYPE_MQTT:
|
|
#if defined(MQTT_COMM_ENABLED) || defined(MAL_ENABLED)
|
|
connection = iotx_cm_open_mqtt(params);
|
|
#endif
|
|
break;
|
|
case IOTX_CM_PROTOCOL_TYPE_COAP:
|
|
#ifdef COAP_COMM_ENABLED
|
|
connection = iotx_cm_open_coap(params);
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (connection == NULL)
|
|
{
|
|
return STATE_DEV_MODEL_CM_OPEN_FAILED;
|
|
}
|
|
fd = _get_fd(connection);
|
|
if (fd < 0)
|
|
{
|
|
connection->close_func();
|
|
return fd;
|
|
}
|
|
connection->fd = fd;
|
|
return fd;
|
|
}
|
|
|
|
int iotx_cm_connect(int fd, uint32_t timeout)
|
|
{
|
|
iotx_cm_connect_fp connect_func;
|
|
int ret;
|
|
|
|
if (_fd_is_valid(fd) < 0)
|
|
{
|
|
return STATE_DEV_MODEL_CM_FD_ERROR;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
connect_func = _cm_fd[fd]->connect_func;
|
|
HAL_MutexUnlock(fd_lock);
|
|
|
|
iotx_event_post(IOTX_CONN_CLOUD);
|
|
|
|
ret = connect_func(timeout);
|
|
|
|
if (ret == 0)
|
|
{
|
|
inited_conn_num++;
|
|
if (inited_conn_num == 1)
|
|
{
|
|
|
|
#ifdef DEVICE_MODEL_MULTI_THREAD
|
|
int stack_used;
|
|
hal_os_thread_param_t task_parms = {0};
|
|
task_parms.stack_size = 6144;
|
|
task_parms.name = "cm_yield";
|
|
ret = HAL_ThreadCreate(&yield_thread, _iotx_cm_yield_thread_func, NULL,
|
|
&task_parms, &stack_used);
|
|
if (ret < 0)
|
|
{
|
|
inited_conn_num--;
|
|
}
|
|
#endif
|
|
}
|
|
iotx_event_post(IOTX_CONN_CLOUD_SUC);
|
|
}
|
|
else
|
|
{
|
|
iotx_event_post(IOTX_CONN_CLOUD_FAIL);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int _iotx_cm_yield(int fd, unsigned int timeout)
|
|
{
|
|
iotx_cm_yield_fp yield_func;
|
|
|
|
if (fd_lock == NULL)
|
|
{
|
|
return STATE_DEV_MODEL_INTERNAL_ERROR;
|
|
}
|
|
|
|
if (fd == -1)
|
|
{
|
|
int i;
|
|
for (i = 0; i < CM_MAX_FD_NUM; i++)
|
|
{
|
|
yield_func = NULL;
|
|
HAL_MutexLock(fd_lock);
|
|
if (_cm_fd[i] != NULL)
|
|
{
|
|
yield_func = _cm_fd[i]->yield_func;
|
|
}
|
|
HAL_MutexUnlock(fd_lock);
|
|
if (yield_func != NULL)
|
|
{
|
|
yield_func(timeout);
|
|
}
|
|
}
|
|
return STATE_SUCCESS;
|
|
}
|
|
|
|
if (_fd_is_valid(fd) < 0)
|
|
{
|
|
return STATE_DEV_MODEL_CM_FD_ERROR;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
yield_func = _cm_fd[fd]->yield_func;
|
|
HAL_MutexUnlock(fd_lock);
|
|
return yield_func(timeout);
|
|
}
|
|
|
|
#ifdef DEVICE_MODEL_MULTI_THREAD
|
|
static void *_iotx_cm_yield_thread_func(void *params)
|
|
{
|
|
yield_task_leave = 0;
|
|
while (inited_conn_num > 0)
|
|
{
|
|
_iotx_cm_yield(-1, CM_DEFAULT_YIELD_TIMEOUT);
|
|
}
|
|
yield_task_leave = 1;
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
int iotx_cm_yield(int fd, unsigned int timeout)
|
|
{
|
|
#ifdef DEVICE_MODEL_MULTI_THREAD
|
|
HAL_SleepMs(timeout);
|
|
return STATE_SUCCESS;
|
|
#else
|
|
return _iotx_cm_yield(fd, timeout);
|
|
#endif
|
|
}
|
|
|
|
int iotx_cm_sub(int fd, iotx_cm_ext_params_t *ext, const char *topic,
|
|
iotx_cm_data_handle_cb topic_handle_func, void *pcontext)
|
|
{
|
|
iotx_cm_sub_fp sub_func;
|
|
|
|
if (_fd_is_valid(fd) < 0)
|
|
{
|
|
return STATE_DEV_MODEL_CM_FD_ERROR;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
sub_func = _cm_fd[fd]->sub_func;
|
|
HAL_MutexUnlock(fd_lock);
|
|
return sub_func(ext, topic, topic_handle_func, pcontext);
|
|
}
|
|
|
|
int iotx_cm_unsub(int fd, const char *topic)
|
|
{
|
|
iotx_cm_unsub_fp unsub_func;
|
|
|
|
if (_fd_is_valid(fd) < 0)
|
|
{
|
|
return STATE_DEV_MODEL_CM_FD_ERROR;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
unsub_func = _cm_fd[fd]->unsub_func;
|
|
HAL_MutexUnlock(fd_lock);
|
|
return unsub_func(topic);
|
|
}
|
|
|
|
int iotx_cm_pub(int fd, iotx_cm_ext_params_t *ext, const char *topic, const char *payload, unsigned int payload_len)
|
|
{
|
|
iotx_cm_pub_fp pub_func;
|
|
|
|
if (_fd_is_valid(fd) < 0)
|
|
{
|
|
return STATE_DEV_MODEL_CM_FD_ERROR;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
pub_func = _cm_fd[fd]->pub_func;
|
|
HAL_MutexUnlock(fd_lock);
|
|
return pub_func(ext, topic, payload, payload_len);
|
|
}
|
|
|
|
int iotx_cm_close(int fd)
|
|
{
|
|
iotx_cm_close_fp close_func;
|
|
|
|
if (_fd_is_valid(fd) < 0)
|
|
{
|
|
return STATE_DEV_MODEL_CM_FD_ERROR;
|
|
}
|
|
|
|
if (inited_conn_num > 0)
|
|
{
|
|
inited_conn_num--;
|
|
}
|
|
|
|
if (inited_conn_num == 0)
|
|
{
|
|
#ifdef DEVICE_MODEL_MULTI_THREAD
|
|
while (!yield_task_leave)
|
|
{
|
|
HAL_SleepMs(10);
|
|
}
|
|
yield_thread = NULL;
|
|
#endif
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
close_func = _cm_fd[fd]->close_func;
|
|
HAL_MutexUnlock(fd_lock);
|
|
|
|
if (close_func == NULL)
|
|
{
|
|
return FAIL_RETURN;
|
|
}
|
|
if (close_func() != 0)
|
|
{
|
|
return FAIL_RETURN;
|
|
}
|
|
if (_recycle_fd(fd) != 0)
|
|
{
|
|
return FAIL_RETURN;
|
|
}
|
|
|
|
if (inited_conn_num == 0)
|
|
{
|
|
if (fd_lock != NULL)
|
|
{
|
|
HAL_MutexDestroy(fd_lock);
|
|
fd_lock = NULL;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int inline _fd_is_valid(int fd)
|
|
{
|
|
int ret;
|
|
|
|
if (fd_lock == NULL)
|
|
{
|
|
return NULL_VALUE_ERROR;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
ret = (fd >= 0 && fd < CM_MAX_FD_NUM && _cm_fd[fd] != NULL) ? 0 : -1;
|
|
HAL_MutexUnlock(fd_lock);
|
|
return ret;
|
|
}
|
|
|
|
static int _recycle_fd(int fd)
|
|
{
|
|
if (fd_lock == NULL)
|
|
{
|
|
fd_lock = HAL_MutexCreate();
|
|
if (fd_lock == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (fd < 0 || fd > CM_MAX_FD_NUM - 1)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
_cm_fd[fd] = NULL;
|
|
HAL_MutexUnlock(fd_lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int _get_fd(iotx_cm_connection_t *handle)
|
|
{
|
|
int i;
|
|
if (handle == NULL)
|
|
{
|
|
return NULL_VALUE_ERROR;
|
|
}
|
|
|
|
if (fd_lock == NULL)
|
|
{
|
|
fd_lock = HAL_MutexCreate();
|
|
if (fd_lock == NULL)
|
|
{
|
|
return STATE_SYS_DEPEND_MUTEX_CREATE;
|
|
}
|
|
}
|
|
|
|
HAL_MutexLock(fd_lock);
|
|
for (i = 0; i < CM_MAX_FD_NUM; i++)
|
|
{
|
|
if (_cm_fd[i] == NULL)
|
|
{
|
|
_cm_fd[i] = handle;
|
|
HAL_MutexUnlock(fd_lock);
|
|
return i;
|
|
}
|
|
}
|
|
HAL_MutexUnlock(fd_lock);
|
|
|
|
return STATE_DEV_MODEL_CM_FD_NOT_FOUND;
|
|
}
|