support aliyun sdk on TencentOS tiny
sample: examples\aliyun_iotkit_csdk_mqtt project: board\TencentOS_tiny_EVB_MX_Plus\KEIL\aliyun_iotkit_csdk_mqtt
This commit is contained in:
45
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_api.c
vendored
Normal file
45
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_api.c
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "infra_config.h"
|
||||
|
||||
int at_conn_init(void);
|
||||
int at_parser_init(void);
|
||||
|
||||
/* See detail struct definition in at_wrapper.h */
|
||||
struct at_conn_input;
|
||||
struct at_mqtt_input;
|
||||
int at_conn_input(struct at_conn_input *param);
|
||||
int at_mqtt_input(struct at_mqtt_input *param);
|
||||
|
||||
int IOT_ATM_Init(void)
|
||||
{
|
||||
#ifdef AT_PARSER_ENABLED
|
||||
if (at_parser_init() < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AT_TCP_ENABLED
|
||||
if (at_conn_init() < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int IOT_ATM_Input(void * param)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
#if defined(AT_TCP_ENABLED)
|
||||
ret = at_conn_input((struct at_conn_input *)param);
|
||||
#elif defined(AT_MQTT_ENABLED)
|
||||
ret = at_mqtt_input((struct at_mqtt_input *)param);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
30
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_api.h
vendored
Normal file
30
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_api.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _AT_API_H_
|
||||
#define _AT_API_H_
|
||||
|
||||
/**
|
||||
* AT module initialization.
|
||||
* Call this function before example starts.
|
||||
* at_parser or at_tcp will be initialized if enabled.
|
||||
* @param[in] none
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int IOT_ATM_Init(void);
|
||||
|
||||
|
||||
/**
|
||||
* Hand received data to ATM layer.
|
||||
* Call this function in low-layer HAL.
|
||||
* @param[in] param pointer to input struct.
|
||||
* See struct at_conn_input and struct at_mqtt_input
|
||||
* in at_wrapper.h
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int IOT_ATM_Input(void * param);
|
||||
|
||||
#endif
|
281
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mbox.c
vendored
Normal file
281
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mbox.c
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "at_wrapper.h"
|
||||
|
||||
#include "at_conn_mbox.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *buffer;
|
||||
uint32_t length;
|
||||
uint32_t head;
|
||||
uint32_t tail;
|
||||
uint8_t full;
|
||||
} at_ringbuf_t;
|
||||
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
static at_ringbuf_t ringbufs[AT_CONN_NUM] = {{NULL, 0, 0, 0, 0}};
|
||||
#endif
|
||||
|
||||
static at_ringbuf_t *alloc_ringbuf(void)
|
||||
{
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
return HAL_Malloc(sizeof(at_ringbuf_t));
|
||||
#else
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AT_CONN_NUM; i++) {
|
||||
if (NULL == ringbufs[i].buffer) {
|
||||
return &ringbufs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void free_ringbuf(at_ringbuf_t *ringbuf)
|
||||
{
|
||||
if (ringbuf) {
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
HAL_Free(ringbuf);
|
||||
#else
|
||||
memset(ringbuf, 0, sizeof(at_ringbuf_t));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int at_ringbuf_available_read_space(at_ringbuf_t *ringbuf)
|
||||
{
|
||||
if (ringbuf->full)
|
||||
return ringbuf->length;
|
||||
|
||||
if (ringbuf->head == ringbuf->tail) {
|
||||
return 0;
|
||||
} else if (ringbuf->head < ringbuf->tail) {
|
||||
return ringbuf->tail - ringbuf->head;
|
||||
} else {
|
||||
return ringbuf->length - (ringbuf->head - ringbuf->tail);
|
||||
}
|
||||
}
|
||||
|
||||
static int at_ringbuf_full(at_ringbuf_t *ringbuf)
|
||||
{
|
||||
return ringbuf->full;
|
||||
}
|
||||
|
||||
static int at_ringbuf_empty(at_ringbuf_t *ringbuf)
|
||||
{
|
||||
return (at_ringbuf_available_read_space(ringbuf) == 0);
|
||||
}
|
||||
|
||||
static at_ringbuf_t *at_ringbuf_create(int length, void *buf)
|
||||
{
|
||||
at_ringbuf_t *ringbuf = NULL;
|
||||
|
||||
if (length < 2 || NULL == buf) {
|
||||
HAL_Printf("Error: ringbuf len MUST exceed one!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ringbuf = alloc_ringbuf();
|
||||
if (ringbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(ringbuf, 0, sizeof(at_ringbuf_t));
|
||||
|
||||
ringbuf->length = length;
|
||||
ringbuf->buffer = buf;
|
||||
|
||||
return ringbuf;
|
||||
}
|
||||
|
||||
static void at_ringbuf_clear_all(at_ringbuf_t *ringbuf)
|
||||
{
|
||||
ringbuf->head = ringbuf->tail = 0;
|
||||
}
|
||||
|
||||
static void at_ringbuf_destroy(at_ringbuf_t *ringbuf)
|
||||
{
|
||||
if (ringbuf) {
|
||||
if (ringbuf->buffer) {
|
||||
at_ringbuf_clear_all(ringbuf);
|
||||
|
||||
ringbuf->buffer = NULL;
|
||||
}
|
||||
free_ringbuf(ringbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static int at_ringbuf_write(at_ringbuf_t *ringbuf, void *data, int size)
|
||||
{
|
||||
uint32_t next;
|
||||
|
||||
if (ringbuf == NULL || data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (at_ringbuf_full(ringbuf)) {
|
||||
HAL_Printf("ringbuf full!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&(((void **) ringbuf->buffer)[ringbuf->tail]), data, size);
|
||||
next = (ringbuf->tail + 1) % (ringbuf->length);
|
||||
if (next == ringbuf->head) {
|
||||
ringbuf->full = 1;
|
||||
} else {
|
||||
ringbuf->tail = next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at_ringbuf_read(at_ringbuf_t *ringbuf, void *target,
|
||||
unsigned int ms, unsigned int *size)
|
||||
{
|
||||
*size = 0;
|
||||
|
||||
if (ringbuf == NULL || target == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: timeout handle */
|
||||
if (at_ringbuf_empty(ringbuf)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(((void **)target), &((void **)ringbuf->buffer)[ringbuf->head], sizeof(void *));
|
||||
((void **)ringbuf->buffer)[ringbuf->head] = NULL;
|
||||
*size = sizeof(void *);
|
||||
ringbuf->head = (ringbuf->head + 1) % (ringbuf->length);
|
||||
|
||||
if (ringbuf->full) {
|
||||
ringbuf->full = 0;
|
||||
ringbuf->tail = (ringbuf->tail + 1) % (ringbuf->length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************public interface***********************/
|
||||
int at_mbox_new(at_mbox_t *mb, int size, void *buf)
|
||||
{
|
||||
void *hdl = NULL;
|
||||
|
||||
if (NULL == mb || NULL == buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdl = at_ringbuf_create(size, buf);
|
||||
if (hdl == NULL) {
|
||||
return -1;
|
||||
}
|
||||
mb->hdl = hdl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void at_mbox_free(at_mbox_t *mb)
|
||||
{
|
||||
if ((mb != NULL)) {
|
||||
at_ringbuf_destroy((at_ringbuf_t *)mb->hdl);
|
||||
}
|
||||
}
|
||||
|
||||
void at_mbox_post(at_mbox_t *mb, void *msg)
|
||||
{
|
||||
at_ringbuf_write((at_ringbuf_t *)mb->hdl, &msg, sizeof(void *));
|
||||
}
|
||||
|
||||
int at_mbox_trypost(at_mbox_t *mb, void *msg)
|
||||
{
|
||||
if (at_ringbuf_write((at_ringbuf_t *)mb->hdl,
|
||||
&msg, sizeof(void *)) != 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int at_mbox_valid(at_mbox_t *mbox)
|
||||
{
|
||||
if (mbox == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mbox->hdl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t at_mbox_fetch(at_mbox_t *mb, void **msg, uint32_t timeout)
|
||||
{
|
||||
uint32_t begin_ms, end_ms, elapsed_ms;
|
||||
uint32_t len;
|
||||
uint32_t ret;
|
||||
|
||||
if (mb == NULL) {
|
||||
return AT_MBOX_TIMEOUT;
|
||||
}
|
||||
|
||||
begin_ms = HAL_UptimeMs();
|
||||
|
||||
if (timeout != 0UL) {
|
||||
if (at_ringbuf_read((at_ringbuf_t *)mb->hdl, msg, timeout, &len) == 0) {
|
||||
end_ms = HAL_UptimeMs();
|
||||
elapsed_ms = end_ms - begin_ms;
|
||||
ret = elapsed_ms;
|
||||
} else {
|
||||
ret = AT_MBOX_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
while (at_ringbuf_read((at_ringbuf_t *)mb->hdl, msg, AT_MBOX_TIMEOUT, &len) != 0);
|
||||
end_ms = HAL_UptimeMs();
|
||||
elapsed_ms = end_ms - begin_ms;
|
||||
|
||||
if (elapsed_ms == 0UL) {
|
||||
elapsed_ms = 1UL;
|
||||
}
|
||||
|
||||
ret = elapsed_ms;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t at_mbox_tryfetch(at_mbox_t *mb, void **msg)
|
||||
{
|
||||
uint32_t len;
|
||||
|
||||
if (mb == NULL) {
|
||||
return AT_MBOX_EMPTY;
|
||||
}
|
||||
|
||||
if (at_ringbuf_read((at_ringbuf_t *)mb->hdl, msg, 0u, &len) != 0) {
|
||||
return AT_MBOX_EMPTY;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int at_mbox_empty(at_mbox_t *mb)
|
||||
{
|
||||
if (mb == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return at_ringbuf_empty((at_ringbuf_t *)mb->hdl);
|
||||
}
|
||||
|
||||
void at_mbox_set_invalid(at_mbox_t *mb)
|
||||
{
|
||||
if (mb != NULL) {
|
||||
mb->hdl = NULL;
|
||||
}
|
||||
}
|
96
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mbox.h
vendored
Normal file
96
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mbox.h
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _AT_CONN_MBOX_H_
|
||||
#define _AT_CONN_MBOX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AT_CONN_NUM 3
|
||||
#define AT_MBOX_TIMEOUT (~0)
|
||||
#define AT_MBOX_EMPTY (~0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *hdl;
|
||||
} at_mbox_t;
|
||||
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Create a new mbox of specified size
|
||||
* @param mbox pointer to the mbox to create
|
||||
* @param size (minimum) number of messages in this mbox
|
||||
* @return 0 if successful, another err_t otherwise
|
||||
*/
|
||||
int at_mbox_new(at_mbox_t *mbox, int size, void *buf);
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Post a message to an mbox - may not fail
|
||||
* -> blocks if full, only used from tasks not from ISR
|
||||
* @param mbox mbox to posts the message
|
||||
* @param msg message to post (ATTENTION: can be NULL)
|
||||
*/
|
||||
void at_mbox_post(at_mbox_t *mbox, void *msg);
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Try to post a message to an mbox - may fail if full or ISR
|
||||
* @param mbox mbox to posts the message
|
||||
* @param msg message to post (ATTENTION: can be NULL)
|
||||
*/
|
||||
int at_mbox_trypost(at_mbox_t *mbox, void *msg);
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Wait for a new message to arrive in the mbox
|
||||
* @param mbox mbox to get a message from
|
||||
* @param msg pointer where the message is stored
|
||||
* @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever)
|
||||
* @return time (in milliseconds) waited for a message, may be 0 if not waited
|
||||
or SYS_ARCH_TIMEOUT on timeout
|
||||
* The returned time has to be accurate to prevent timer jitter!
|
||||
*/
|
||||
uint32_t at_mbox_fetch(at_mbox_t *mbox, void **msg, uint32_t timeout);
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Wait for a new message to arrive in the mbox
|
||||
* @param mbox mbox to get a message from
|
||||
* @param msg pointer where the message is stored
|
||||
* @return 0 (milliseconds) if a message has been received
|
||||
* or at_MBOX_EMPTY if the mailbox is empty
|
||||
*/
|
||||
uint32_t at_mbox_tryfetch(at_mbox_t *mbox, void **msg);
|
||||
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Delete an mbox
|
||||
* @param mbox mbox to delete
|
||||
*/
|
||||
void at_mbox_free(at_mbox_t *mbox);
|
||||
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid
|
||||
*/
|
||||
int at_mbox_valid(at_mbox_t *mbox);
|
||||
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Set an mbox invalid so that sys_mbox_valid returns 0
|
||||
*/
|
||||
void at_mbox_set_invalid(at_mbox_t *mbox);
|
||||
|
||||
/**
|
||||
* @ingroup sys_mbox
|
||||
* Set an mbox invalid so that sys_mbox_valid returns 0
|
||||
*/
|
||||
int at_mbox_empty(at_mbox_t *mb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_at_ARCH_H_*/
|
||||
|
||||
|
654
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mgmt.c
vendored
Normal file
654
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mgmt.c
vendored
Normal file
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "mqtt_api.h"
|
||||
#include "at_wrapper.h"
|
||||
|
||||
#include "at_conn_mbox.h"
|
||||
#include "at_conn_mgmt.h"
|
||||
|
||||
#define AT_DEFAULT_INPUTMBOX_SIZE 3
|
||||
#define AT_DEFAULT_PAYLOAD_SIZE (CONFIG_MQTT_MESSAGE_MAXLEN + CONFIG_MQTT_TOPIC_MAXLEN + 20)
|
||||
|
||||
#define AT_DEFAULT_SEND_TIMEOUT_MS 1000
|
||||
#define AT_DEFAULT_RECV_TIMEOUT_MS 1000
|
||||
|
||||
#define DNS_MAX_NAME_LENGTH 256
|
||||
#define AT_IP4_ANY_ADDR "0.0.0.0"
|
||||
#define IPV4_STR_MAX_LEN 16
|
||||
|
||||
#define AT_MAX_PAYLOAD_SIZE 1512
|
||||
|
||||
#define UNUSED_ATCONN -1
|
||||
|
||||
#ifdef AT_DEBUG_MODE
|
||||
#define AT_DEBUG(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define AT_ERROR(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#else
|
||||
#define AT_DEBUG(...)
|
||||
#define AT_ERROR(...)
|
||||
#endif
|
||||
|
||||
enum netconn_state {
|
||||
NETCONN_NONE = 0,
|
||||
NETCONN_WRITE,
|
||||
NETCONN_LISTEN,
|
||||
NETCONN_CONNECT,
|
||||
NETCONN_CLOSE
|
||||
};
|
||||
|
||||
/** Contains all internal pointers and states used for a socket */
|
||||
struct at_conn {
|
||||
/** connnection ID */
|
||||
int connid;
|
||||
/** type of the netconn (TCP) */
|
||||
enum netconn_type type;
|
||||
/** current state of the netconn */
|
||||
enum netconn_state state;
|
||||
/** remote port number */
|
||||
uint16_t remote_port;
|
||||
/** remote ip address */
|
||||
char remote_ip[IPV4_STR_MAX_LEN];
|
||||
/** data that was left from the previous read */
|
||||
void *lastdata;
|
||||
/** offset in the data that was left from the previous read */
|
||||
uint16_t lastoffset;
|
||||
/** mbox where received packets are stored until they are fetched
|
||||
by the neconn application thread. */
|
||||
at_mbox_t recvmbox;
|
||||
/** pointer buffer for mbox which is used by ringbuf module. */
|
||||
void *recvbuf[AT_DEFAULT_INPUTMBOX_SIZE];
|
||||
/** timeout to wait for sending data (which means enqueueing data for sending
|
||||
in internal buffers) in milliseconds */
|
||||
int send_timeout_ms;
|
||||
/** timeout in milliseconds to wait for new data to be received
|
||||
(or connections to arrive for listening netconns) */
|
||||
int recv_timeout_ms;
|
||||
};
|
||||
|
||||
typedef struct at_netbuf {
|
||||
void *payload;
|
||||
uint16_t len;
|
||||
uint16_t remote_port;
|
||||
char remote_ip[IPV4_STR_MAX_LEN];
|
||||
} at_netbuf_t;
|
||||
|
||||
/** The global array of available at */
|
||||
static struct at_conn atconnects[AT_CONN_NUM];
|
||||
static void *g_atconnmutex = NULL;
|
||||
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
static at_netbuf_t atnetbuf[AT_DEFAULT_INPUTMBOX_SIZE] =
|
||||
{{NULL, 0, 0, {'\0'}}};
|
||||
|
||||
typedef struct at_payload {
|
||||
uint8_t buf[AT_DEFAULT_PAYLOAD_SIZE];
|
||||
uint8_t used;
|
||||
} at_payload_t;
|
||||
|
||||
static at_payload_t atpayload[AT_DEFAULT_INPUTMBOX_SIZE] =
|
||||
{{{0}, 0}};
|
||||
#endif
|
||||
|
||||
static void *alloc_payload(int size)
|
||||
{
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
return HAL_Malloc(size);
|
||||
#else
|
||||
int i;
|
||||
|
||||
if (size <= 0 || size > AT_DEFAULT_PAYLOAD_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < AT_DEFAULT_INPUTMBOX_SIZE; i++) {
|
||||
if (0 == atpayload[i].used) {
|
||||
atpayload[i].used = 1;
|
||||
return atpayload[i].buf;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void free_payload(void *payload)
|
||||
{
|
||||
if (payload) {
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
HAL_Free(payload);
|
||||
#else
|
||||
memset(payload, 0, sizeof(at_payload_t));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static at_netbuf_t *alloc_atnetbuf(void)
|
||||
{
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
return HAL_Malloc(sizeof(at_netbuf_t));
|
||||
#else
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AT_DEFAULT_INPUTMBOX_SIZE; i++) {
|
||||
if (NULL == atnetbuf[i].payload) {
|
||||
return &atnetbuf[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void free_atnetbuf(at_netbuf_t *netbuf)
|
||||
{
|
||||
if (netbuf) {
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
HAL_Free(netbuf);
|
||||
#else
|
||||
memset(netbuf, 0, sizeof(at_netbuf_t));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static struct at_conn *get_conn(int c)
|
||||
{
|
||||
struct at_conn *conn = NULL;
|
||||
|
||||
if ((c < 0) || (c >= AT_CONN_NUM)) {
|
||||
AT_DEBUG("get_conn(%d): invalid", c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn = &atconnects[c];
|
||||
|
||||
if (UNUSED_ATCONN == conn->connid) {
|
||||
AT_DEBUG("get_conn(%d): not active", c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
static int at_newconn(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AT_CONN_NUM; i++) {
|
||||
if (atconnects[i].connid == UNUSED_ATCONN) {
|
||||
if (at_mbox_new(&atconnects[i].recvmbox,
|
||||
AT_DEFAULT_INPUTMBOX_SIZE,
|
||||
atconnects[i].recvbuf) != 0) {
|
||||
AT_ERROR("fai to new input mail box size %d \n", AT_DEFAULT_INPUTMBOX_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
atconnects[i].type = NETCONN_INVALID;
|
||||
atconnects[i].state = NETCONN_NONE;
|
||||
atconnects[i].lastdata = NULL;
|
||||
atconnects[i].lastoffset = 0;
|
||||
atconnects[i].connid = i;
|
||||
atconnects[i].send_timeout_ms = AT_DEFAULT_SEND_TIMEOUT_MS;
|
||||
atconnects[i].recv_timeout_ms = AT_DEFAULT_RECV_TIMEOUT_MS;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void at_drainconn(struct at_conn *conn)
|
||||
{
|
||||
at_netbuf_t *mem;
|
||||
|
||||
if (NULL == conn)
|
||||
return;
|
||||
|
||||
if (at_mbox_valid(&conn->recvmbox)) {
|
||||
while (at_mbox_tryfetch(&conn->recvmbox, (void **)(&mem)) != AT_MBOX_EMPTY) {
|
||||
if (mem != NULL) {
|
||||
if (mem->payload) {
|
||||
free_payload(mem->payload);
|
||||
mem->payload = NULL;
|
||||
}
|
||||
free_atnetbuf(mem);
|
||||
}
|
||||
}
|
||||
at_mbox_free(&conn->recvmbox);
|
||||
at_mbox_set_invalid(&conn->recvmbox);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int at_freeconn(struct at_conn *conn)
|
||||
{
|
||||
at_netbuf_t *buf = NULL;
|
||||
|
||||
if (NULL == conn)
|
||||
return -1;
|
||||
|
||||
if (NULL != conn->lastdata) {
|
||||
buf = (at_netbuf_t *) conn->lastdata;
|
||||
|
||||
if (buf->payload) {
|
||||
free_payload(buf->payload);
|
||||
buf->payload = NULL;
|
||||
}
|
||||
|
||||
free_atnetbuf(buf);
|
||||
}
|
||||
|
||||
conn->lastdata = NULL;
|
||||
conn->lastoffset = 0;
|
||||
|
||||
at_drainconn(conn);
|
||||
|
||||
conn->type = NETCONN_INVALID;
|
||||
conn->state = NETCONN_NONE;
|
||||
conn->connid = UNUSED_ATCONN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at_conn_fetch(struct at_conn *conn, at_netbuf_t **new_buf)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
void *buf = NULL;
|
||||
|
||||
if (NULL == conn || NULL == new_buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!at_mbox_valid(&conn->recvmbox)) {
|
||||
AT_ERROR("conn %d invalid recvmbox\n", conn->connid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = at_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout_ms);
|
||||
if (ret == AT_MBOX_TIMEOUT) {
|
||||
AT_ERROR("at conn %d fetch data time out %d\n", conn->connid, conn->recv_timeout_ms);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*new_buf = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************public interface*********************/
|
||||
int at_conn_input(struct at_conn_input *param)
|
||||
{
|
||||
int s = -1;
|
||||
void *data = NULL;
|
||||
int len = 0;
|
||||
char *remote_ip = NULL;
|
||||
uint16_t remote_port = 0;
|
||||
struct at_conn *conn = NULL;
|
||||
at_netbuf_t *buf = NULL;
|
||||
|
||||
if (NULL == param) {
|
||||
AT_ERROR("at conn input param NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = param->fd;
|
||||
data = param->data;
|
||||
len = param->datalen;
|
||||
remote_ip = param->remote_ip;
|
||||
remote_port = param->remote_port;
|
||||
|
||||
if (NULL == data || 0 == len) {
|
||||
AT_ERROR("low level invalid input data\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (remote_ip != NULL &&
|
||||
strlen(remote_ip) > IPV4_STR_MAX_LEN) {
|
||||
AT_ERROR("invalid ip string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn = get_conn(s);
|
||||
if (NULL == conn) {
|
||||
AT_ERROR("conn %d doesn't exist\n", s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->connid < 0) {
|
||||
AT_ERROR("conn %d invalid connid\n", s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!at_mbox_valid(&conn->recvmbox)) {
|
||||
AT_ERROR("invalid conn to input packet\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = alloc_atnetbuf();
|
||||
if (NULL == buf) {
|
||||
AT_ERROR("alloc at net buf size %d fail\n", sizeof(at_netbuf_t));
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
|
||||
buf->payload = alloc_payload(len);
|
||||
if (NULL == buf->payload) {
|
||||
free_atnetbuf(buf);
|
||||
AT_ERROR("alloc payload size %d fail\n", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(buf->payload, data, len);
|
||||
buf->len = len;
|
||||
buf->remote_port = remote_port;
|
||||
if (remote_ip)
|
||||
memcpy(buf->remote_ip, remote_ip, IPV4_STR_MAX_LEN);
|
||||
|
||||
if (at_mbox_trypost(&conn->recvmbox, buf) != 0) {
|
||||
free_payload(buf->payload);
|
||||
buf->payload = NULL;
|
||||
free_atnetbuf(buf);
|
||||
AT_ERROR("try post recv packet fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_conn_init(void)
|
||||
{
|
||||
static int at_conn_init_done = 0;
|
||||
int i;
|
||||
|
||||
if (at_conn_init_done) {
|
||||
AT_ERROR("at conn have already init done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < AT_CONN_NUM; i++) {
|
||||
atconnects[i].connid = UNUSED_ATCONN;
|
||||
}
|
||||
|
||||
g_atconnmutex = HAL_MutexCreate();
|
||||
if (g_atconnmutex == NULL) {
|
||||
AT_ERROR("failed to creat g_atconnmutex \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (HAL_AT_CONN_Init() != 0) {
|
||||
AT_ERROR("at conn low level init fail\n");
|
||||
HAL_MutexDestroy(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
at_conn_init_done = 1;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int at_conn_getaddrinfo(const char *nodename, char resultip[16])
|
||||
{
|
||||
int namelen;
|
||||
|
||||
if (NULL == nodename || NULL == resultip) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
namelen = strlen(nodename);
|
||||
if (namelen > DNS_MAX_NAME_LENGTH)
|
||||
return -1;
|
||||
|
||||
if (HAL_AT_CONN_DomainToIp((char *)nodename, resultip) != 0) {
|
||||
AT_ERROR("domain to ip failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_conn_setup(netconn_type_t type)
|
||||
{
|
||||
struct at_conn *conn = NULL;
|
||||
int connid = -1;
|
||||
|
||||
if (type >= NETCONN_TYPE_NUM || type <= NETCONN_INVALID) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(g_atconnmutex);
|
||||
if ((connid = at_newconn()) == -1) {
|
||||
AT_ERROR("fai to new at conn\n");
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((conn = get_conn(connid)) == NULL) {
|
||||
AT_ERROR("fai to get at conn\n");
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn->type = type;
|
||||
conn->state = NETCONN_NONE;
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
|
||||
return connid;
|
||||
}
|
||||
|
||||
int at_conn_start(int connid, char* remoteipaddr, uint16_t remoteport)
|
||||
{
|
||||
char *ipv4anyadrr = AT_IP4_ANY_ADDR;
|
||||
at_conn_t statconn = {0};
|
||||
struct at_conn *conn = NULL;
|
||||
|
||||
HAL_MutexLock(g_atconnmutex);
|
||||
conn = get_conn(connid);
|
||||
if (NULL == conn) {
|
||||
AT_ERROR("at_startconn: invalid conn\n");
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->state != NETCONN_NONE) {
|
||||
AT_ERROR("at_startconn: conn %d state is %d \n", connid, conn->state);
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
statconn.fd = connid;
|
||||
statconn.r_port = remoteport;
|
||||
statconn.l_port = -1;
|
||||
statconn.addr = (char *)remoteipaddr;
|
||||
if (NULL == statconn.addr) {
|
||||
statconn.addr = ipv4anyadrr;
|
||||
}
|
||||
|
||||
switch (conn->type) {
|
||||
case NETCONN_TCP:
|
||||
statconn.type = TCP_CLIENT;
|
||||
if (HAL_AT_CONN_Start(&statconn) != 0) {
|
||||
AT_ERROR("fail to setup tcp connect, remote is %s port is %d.\n", statconn.addr, remoteport);
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
memcpy(conn->remote_ip, statconn.addr, IPV4_STR_MAX_LEN);
|
||||
conn->remote_port = remoteport;
|
||||
break;
|
||||
default:
|
||||
AT_ERROR("Unsupported at connection type.\n");
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update at conn state */
|
||||
conn->state = NETCONN_CONNECT;
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_conn_close(int c)
|
||||
{
|
||||
struct at_conn *conn = NULL;
|
||||
int err;
|
||||
|
||||
AT_DEBUG("at_close(%d)\r\n", c);
|
||||
|
||||
conn = get_conn(c);
|
||||
if (NULL == conn) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->state == NETCONN_CONNECT) {
|
||||
if (HAL_AT_CONN_Close(c, -1) != 0) {
|
||||
AT_DEBUG("HAL_AT_close failed.");
|
||||
}
|
||||
}
|
||||
|
||||
HAL_MutexLock(g_atconnmutex);
|
||||
err = at_freeconn(conn);
|
||||
HAL_MutexUnlock(g_atconnmutex);
|
||||
if (err != 0) {
|
||||
AT_ERROR("at_freeconn failed in %s.", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_conn_recvbufempty(int c)
|
||||
{
|
||||
struct at_conn *conn = NULL;
|
||||
|
||||
conn = get_conn(c);
|
||||
if (NULL == conn) {
|
||||
AT_ERROR("at_recvbufempty cannot get socket %d\n", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* remain data */
|
||||
if (conn->lastdata)
|
||||
return 0;
|
||||
|
||||
if (!at_mbox_valid(&conn->recvmbox)) {
|
||||
AT_ERROR("conn %d invalid recvmbox\n", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return at_mbox_empty(&conn->recvmbox);
|
||||
}
|
||||
|
||||
int at_conn_send(int c, const void *data, uint32_t size)
|
||||
{
|
||||
struct at_conn *conn = NULL;
|
||||
|
||||
if (NULL == data || size == 0 || size > AT_MAX_PAYLOAD_SIZE) {
|
||||
AT_ERROR("at_conn_send fail to send, size %d\n", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn = get_conn(c);
|
||||
if (NULL == conn) {
|
||||
AT_ERROR("at_conn_send fail to get conn %d\n", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->type == NETCONN_TCP) {
|
||||
if (conn->state == NETCONN_NONE) {
|
||||
AT_ERROR("at_conn_send connect %d state %d\n", c, conn->state);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (HAL_AT_CONN_Send(c, (uint8_t *)data, size, NULL, -1, conn->send_timeout_ms)) {
|
||||
AT_ERROR("c %d fail to send do nothing for now\n", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int at_conn_recv(int c, void *mem, uint32_t len)
|
||||
{
|
||||
struct at_conn *conn = NULL;
|
||||
at_netbuf_t *buf = NULL;
|
||||
int off = 0;
|
||||
uint16_t buflen = 0;
|
||||
uint16_t copylen = 0;
|
||||
int err = 0;
|
||||
uint8_t done = 0;
|
||||
|
||||
if (NULL == mem || 0 == len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn = get_conn(c);
|
||||
if (NULL == conn) {
|
||||
AT_ERROR("at_conn_recv fail to get conn %d\n", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
if (conn->lastdata) {
|
||||
buf = conn->lastdata;
|
||||
} else {
|
||||
err = at_conn_fetch(conn, &buf);
|
||||
if (err != 0 || buf == NULL || buf->payload == NULL) {
|
||||
if (off > 0) {
|
||||
return off;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
conn->lastdata = buf;
|
||||
}
|
||||
|
||||
buflen = buf->len;
|
||||
AT_DEBUG("at_conn_recv: buflen=%u, len=%u, off=%d, lastoffset=%u\n",
|
||||
buflen, len, off, conn->lastoffset);
|
||||
|
||||
buflen -= conn->lastoffset;
|
||||
if (len > buflen) {
|
||||
copylen = buflen;
|
||||
} else {
|
||||
copylen = len;
|
||||
}
|
||||
|
||||
memcpy(&((uint8_t *)mem)[off], &((uint8_t *)buf->payload)[conn->lastoffset], copylen);
|
||||
off += copylen;
|
||||
|
||||
if (NETCONN_TCP == conn->type) {
|
||||
if (len < copylen) {
|
||||
AT_ERROR("invalid copylen %d, len = %d\n", copylen, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len -= copylen;
|
||||
if (len <= 0) {
|
||||
done = 1;
|
||||
}
|
||||
} else {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if ((NETCONN_TCP == conn->type) && (buflen > copylen)) {
|
||||
conn->lastdata = buf;
|
||||
conn->lastoffset += copylen;
|
||||
} else {
|
||||
conn->lastdata = NULL;
|
||||
conn->lastoffset = 0;
|
||||
free_payload(buf->payload);
|
||||
buf->payload = NULL;
|
||||
free_atnetbuf(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
return off;
|
||||
}
|
94
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mgmt.h
vendored
Normal file
94
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_conn_mgmt.h
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _AT_CONN_MGMT_H_
|
||||
#define _AT_CONN_MGMT_H_
|
||||
|
||||
typedef enum netconn_type {
|
||||
NETCONN_INVALID = 0,
|
||||
/** TCP IPv4 */
|
||||
NETCONN_TCP,
|
||||
NETCONN_TYPE_NUM
|
||||
} netconn_type_t;
|
||||
|
||||
/**
|
||||
* at connection module initialization
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_init(void);
|
||||
|
||||
/**
|
||||
* receive data from an at connection
|
||||
*
|
||||
* @param[in]: connection id;
|
||||
* @param[out]: pointer to output buffer
|
||||
* @param[in]: expect length
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_recv(int connid, void *mem, uint32_t len);
|
||||
|
||||
/**
|
||||
* query ip from domain address
|
||||
*
|
||||
* @param[in]: domain address
|
||||
* @param[out]: query result
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_getaddrinfo(const char *nodename, char resultip[16]);
|
||||
|
||||
|
||||
/**
|
||||
* setup an new at connection
|
||||
*
|
||||
* @param[in]: connection type only tcp support
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_setup(netconn_type_t type);
|
||||
|
||||
/**
|
||||
* start an at connection
|
||||
*
|
||||
* @param[in]: connection id
|
||||
* @param[in]: remote ip address
|
||||
* @param[in]: remote port
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_start(int connid, char* remoteipaddr, uint16_t remoteport);
|
||||
|
||||
/**
|
||||
* close an at connection
|
||||
*
|
||||
* @param[in] connection id
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_close(int connid);
|
||||
|
||||
/**
|
||||
* check whether recvbuf empty
|
||||
*
|
||||
* @param[in] connection id
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_recvbufempty(int connid);
|
||||
|
||||
/**
|
||||
* send data through an at connection
|
||||
*
|
||||
* @param[in] connection id
|
||||
* @param[in] send buf pointer
|
||||
*
|
||||
* @return 0 : on success, -1: error
|
||||
*/
|
||||
int at_conn_send(int connid, const void *data, uint32_t size);
|
||||
|
||||
#endif
|
1269
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_mqtt.c
vendored
Normal file
1269
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_mqtt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
62
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_mqtt.h
vendored
Normal file
62
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_mqtt.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _AT_MQTT_H_
|
||||
#define _AT_MQTT_H_
|
||||
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
#ifndef IOTX_MC_SUBHANDLE_LIST_MAX_LEN
|
||||
#define IOTX_MC_SUBHANDLE_LIST_MAX_LEN (5)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MQTT_TOPIC_MAXLEN
|
||||
#define CONFIG_MQTT_TOPIC_MAXLEN (128)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* State of MQTT client */
|
||||
typedef enum {
|
||||
IOTX_MC_STATE_INVALID = 0, /* MQTT in invalid state */
|
||||
IOTX_MC_STATE_INITIALIZED = 1, /* MQTT in initializing state */
|
||||
IOTX_MC_STATE_CONNECTED = 2, /* MQTT in connected state */
|
||||
IOTX_MC_STATE_DISCONNECTED = 3, /* MQTT in disconnected state */
|
||||
IOTX_MC_STATE_DISCONNECTED_RECONNECTING = 4, /* MQTT in reconnecting state */
|
||||
} iotx_mc_state_t;
|
||||
|
||||
typedef enum {
|
||||
TOPIC_NAME_TYPE = 0,
|
||||
TOPIC_FILTER_TYPE
|
||||
} iotx_mc_topic_type_t;
|
||||
|
||||
/* Handle structure of subscribed topic */
|
||||
typedef struct iotx_mc_topic_handle_s {
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
const char *topic_filter;
|
||||
#else
|
||||
const char topic_filter[CONFIG_MQTT_TOPIC_MAXLEN];
|
||||
int used;
|
||||
#endif
|
||||
iotx_mc_topic_type_t topic_type;
|
||||
iotx_mqtt_event_handle_t handle;
|
||||
struct iotx_mc_topic_handle_s *next;
|
||||
} iotx_mc_topic_handle_t;
|
||||
|
||||
typedef struct Client {
|
||||
uint32_t packet_id; /* packet id */
|
||||
void *lock_generic; /* generic lock */
|
||||
void *lock_yield;
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
iotx_mc_topic_handle_t *first_sub_handle; /* list of subscribe handle */
|
||||
#else
|
||||
iotx_mc_topic_handle_t list_sub_handle[IOTX_MC_SUBHANDLE_LIST_MAX_LEN];
|
||||
#endif
|
||||
void *lock_list_sub; /* lock for list of sub/unsub */
|
||||
iotx_mc_state_t client_state; /* state of MQTT client */
|
||||
iotx_mqtt_event_handle_t handle_event; /* event handle */
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
int used;
|
||||
#endif
|
||||
} iotx_mc_client_t, *iotx_mc_client_pt;
|
||||
|
||||
#endif
|
948
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_parser.c
vendored
Normal file
948
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_parser.c
vendored
Normal file
@@ -0,0 +1,948 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "at_wrapper.h"
|
||||
#include "at_parser.h"
|
||||
|
||||
#define OOB_MAX 5
|
||||
|
||||
typedef struct oob_s
|
||||
{
|
||||
char * prefix;
|
||||
char * postfix;
|
||||
char * oobinputdata;
|
||||
uint32_t reallen;
|
||||
uint32_t maxlen;
|
||||
at_recv_cb cb;
|
||||
void * arg;
|
||||
} oob_t;
|
||||
|
||||
/*
|
||||
* --> | slist | --> | slist | --> NULL
|
||||
* --------- ---------
|
||||
* | smhr | | smpr |
|
||||
* --------- ---------
|
||||
* | rsp | | rsp |
|
||||
* --------- ---------
|
||||
*/
|
||||
#if !AT_SINGLE_TASK
|
||||
#include "infra_list.h"
|
||||
typedef struct at_task_s
|
||||
{
|
||||
slist_t next;
|
||||
void * smpr;
|
||||
char * command;
|
||||
char * rsp;
|
||||
char * rsp_prefix;
|
||||
char * rsp_success_postfix;
|
||||
char * rsp_fail_postfix;
|
||||
uint32_t rsp_prefix_len;
|
||||
uint32_t rsp_success_postfix_len;
|
||||
uint32_t rsp_fail_postfix_len;
|
||||
uint32_t rsp_offset;
|
||||
uint32_t rsp_len;
|
||||
} at_task_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Parser structure for parsing AT commands
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uart_dev_t *_pstuart;
|
||||
int _timeout;
|
||||
char * _default_recv_prefix;
|
||||
char * _default_recv_success_postfix;
|
||||
char * _default_recv_fail_postfix;
|
||||
char * _send_delimiter;
|
||||
int _recv_prefix_len;
|
||||
int _recv_success_postfix_len;
|
||||
int _recv_fail_postfix_len;
|
||||
int _send_delim_size;
|
||||
oob_t _oobs[OOB_MAX];
|
||||
int _oobs_num;
|
||||
void * at_uart_recv_mutex;
|
||||
void * at_uart_send_mutex;
|
||||
void * task_mutex;
|
||||
#if !AT_SINGLE_TASK
|
||||
slist_t task_l;
|
||||
#endif
|
||||
} at_parser_t;
|
||||
|
||||
#define TASK_DEFAULT_WAIT_TIME 5000
|
||||
|
||||
#ifndef AT_WORKER_STACK_SIZE
|
||||
#define AT_WORKER_STACK_SIZE 1024
|
||||
#endif
|
||||
|
||||
#ifndef AT_UART_TIMEOUT_MS
|
||||
#define AT_UART_TIMEOUT_MS 1000
|
||||
#endif
|
||||
|
||||
#ifndef AT_CMD_DATA_INTERVAL_MS
|
||||
#define AT_CMD_DATA_INTERVAL_MS 0
|
||||
#endif
|
||||
|
||||
#ifdef AT_DEBUG_MODE
|
||||
#define atpsr_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define atpsr_warning(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define atpsr_info(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define atpsr_debug(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#else
|
||||
#define atpsr_err(...)
|
||||
#define atpsr_warning(...)
|
||||
#define atpsr_info(...)
|
||||
#define atpsr_debug(...)
|
||||
#endif
|
||||
|
||||
static uint8_t inited = 0;
|
||||
static uart_dev_t at_uart;
|
||||
|
||||
static at_parser_t at;
|
||||
|
||||
#if !AT_SINGLE_TASK
|
||||
static void* at_worker(void *arg);
|
||||
#endif
|
||||
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
#if !AT_SINGLE_TASK
|
||||
static at_task_t g_at_task;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void at_uart_configure(uart_dev_t *u)
|
||||
{
|
||||
u->port = AT_UART_PORT;
|
||||
u->config.baud_rate = AT_UART_BAUDRATE;
|
||||
u->config.data_width = AT_UART_DATA_WIDTH;
|
||||
u->config.parity = AT_UART_PARITY;
|
||||
u->config.stop_bits = AT_UART_STOP_BITS;
|
||||
u->config.flow_control = AT_UART_FLOW_CONTROL;
|
||||
u->config.mode = AT_UART_MODE;
|
||||
}
|
||||
|
||||
static int at_init_uart()
|
||||
{
|
||||
at_uart_configure(&at_uart);
|
||||
|
||||
if (HAL_AT_Uart_Init(&at_uart) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
at._pstuart = &at_uart;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at_set_timeout(int timeout)
|
||||
{
|
||||
at._timeout = timeout;
|
||||
}
|
||||
|
||||
static void at_set_recv_delimiter(const char *recv_prefix,
|
||||
const char *recv_success_postfix,
|
||||
const char *recv_fail_postfix)
|
||||
{
|
||||
at._default_recv_prefix = (char *)recv_prefix;
|
||||
at._default_recv_success_postfix = (char *)recv_success_postfix;
|
||||
at._default_recv_fail_postfix = (char *)recv_fail_postfix;
|
||||
at._recv_prefix_len = strlen(recv_prefix);
|
||||
at._recv_success_postfix_len = strlen(recv_success_postfix);
|
||||
at._recv_fail_postfix_len = strlen(recv_fail_postfix);
|
||||
}
|
||||
|
||||
static void at_set_send_delimiter(const char *delimiter)
|
||||
{
|
||||
at._send_delimiter = (char *)delimiter;
|
||||
at._send_delim_size = strlen(delimiter);
|
||||
}
|
||||
|
||||
static int at_init_task_mutex()
|
||||
{
|
||||
at.task_mutex = HAL_MutexCreate();
|
||||
if (NULL == at.task_mutex) {
|
||||
atpsr_err("Creating task mutex failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at_deinit_task_mutex()
|
||||
{
|
||||
if (at.task_mutex) {
|
||||
HAL_MutexDestroy(at.task_mutex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int at_init_uart_recv_mutex()
|
||||
{
|
||||
at.at_uart_recv_mutex = HAL_MutexCreate();
|
||||
if (NULL == at.at_uart_recv_mutex) {
|
||||
atpsr_err("Creating at_uart_recv_mutex failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at_deinit_uart_recv_mutex()
|
||||
{
|
||||
if (at.at_uart_recv_mutex) {
|
||||
HAL_MutexDestroy(at.at_uart_recv_mutex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int at_worker_uart_send_mutex_init()
|
||||
{
|
||||
at.at_uart_send_mutex = HAL_MutexCreate();
|
||||
if (NULL == at.at_uart_send_mutex) {
|
||||
atpsr_err("Creating at worker sem failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !AT_SINGLE_TASK
|
||||
static void at_worker_uart_send_mutex_deinit()
|
||||
{
|
||||
if (at.at_uart_send_mutex) {
|
||||
HAL_MutexDestroy(at.at_uart_send_mutex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int at_parser_init(void)
|
||||
{
|
||||
char *recv_prefix = AT_RECV_PREFIX;
|
||||
char *recv_success_postfix = AT_RECV_SUCCESS_POSTFIX;
|
||||
char *recv_fail_postfix = AT_RECV_FAIL_POSTFIX;
|
||||
char *send_delimiter = AT_SEND_DELIMITER;
|
||||
int timeout = AT_UART_TIMEOUT_MS;
|
||||
#if !AT_SINGLE_TASK
|
||||
void *task;
|
||||
int stack_used;
|
||||
hal_os_thread_param_t task_parms = {0};
|
||||
#endif
|
||||
|
||||
if (inited == 1) {
|
||||
atpsr_info("have already inited ,it will init again\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&at, 0, sizeof(at_parser_t));
|
||||
|
||||
if (at_init_uart() != 0) {
|
||||
atpsr_err("at uart init fail \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(at._oobs, 0, sizeof(oob_t) * OOB_MAX);
|
||||
|
||||
at_set_timeout(timeout);
|
||||
at_set_recv_delimiter(recv_prefix, recv_success_postfix, recv_fail_postfix);
|
||||
at_set_send_delimiter(send_delimiter);
|
||||
|
||||
if (at_init_uart_recv_mutex() != 0) {
|
||||
atpsr_err("at_uart_recv_mutex init fail \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (at_init_task_mutex() != 0) {
|
||||
at_deinit_uart_recv_mutex();
|
||||
atpsr_err("at mutex init fail \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (at_worker_uart_send_mutex_init() != 0) {
|
||||
at_deinit_uart_recv_mutex();
|
||||
at_deinit_task_mutex();
|
||||
atpsr_err("fail to creat at worker sem\r\n");
|
||||
}
|
||||
|
||||
#if AT_SINGLE_TASK
|
||||
inited = true;
|
||||
#else
|
||||
slist_init(&at.task_l);
|
||||
|
||||
task_parms.priority = os_thread_priority_normal;
|
||||
task_parms.stack_size = AT_WORKER_STACK_SIZE;
|
||||
task_parms.name = "at_worker";
|
||||
if (HAL_ThreadCreate(&task, at_worker, NULL, &task_parms, &stack_used) != 0) {
|
||||
at_deinit_uart_recv_mutex();
|
||||
at_deinit_task_mutex();
|
||||
at_worker_uart_send_mutex_deinit();
|
||||
atpsr_err("fail to creat at task\r\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at_sendto_lower(uart_dev_t *uart, void *data, uint32_t size,
|
||||
uint32_t timeout, bool ackreq)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
(void) ackreq;
|
||||
ret = HAL_AT_Uart_Send(uart, data, size, timeout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int at_recvfrom_lower(uart_dev_t *uart, void *data, uint32_t expect_size,
|
||||
uint32_t *recv_size, uint32_t timeout)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = HAL_AT_Uart_Recv(uart, data, expect_size, recv_size, timeout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if AT_SINGLE_TASK
|
||||
int at_send_wait_reply(const char *cmd, int cmdlen, bool delimiter,
|
||||
const char *data, int datalen,
|
||||
char *replybuf, int bufsize,
|
||||
const atcmd_config_t *atcmdconfig)
|
||||
{
|
||||
int intval_ms = AT_CMD_DATA_INTERVAL_MS;
|
||||
|
||||
if (at_send_no_reply(cmd, cmdlen, delimiter) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data && datalen) {
|
||||
if (intval_ms > 0)
|
||||
HAL_SleepMs(intval_ms);
|
||||
|
||||
if (at_send_no_reply(data, datalen, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (at_yield(replybuf, bufsize, atcmdconfig, at._timeout) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int at_worker_task_add(at_task_t *tsk)
|
||||
{
|
||||
if (NULL == tsk) {
|
||||
atpsr_err("invalid input %s \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(at.task_mutex);
|
||||
slist_add_tail(&tsk->next, &at.task_l);
|
||||
HAL_MutexUnlock(at.task_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at_worker_task_del(at_task_t *tsk)
|
||||
{
|
||||
if (NULL == tsk) {
|
||||
atpsr_err("invalid input %s \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(at.task_mutex);
|
||||
slist_del(&tsk->next, &at.task_l);
|
||||
HAL_MutexUnlock(at.task_mutex);
|
||||
if (tsk->smpr) {
|
||||
HAL_SemaphoreDestroy(tsk->smpr);
|
||||
}
|
||||
if (tsk) {
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
HAL_Free(tsk);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_send_wait_reply(const char *cmd, int cmdlen, bool delimiter,
|
||||
const char *data, int datalen,
|
||||
char *replybuf, int bufsize,
|
||||
const atcmd_config_t *atcmdconfig)
|
||||
{
|
||||
int ret = 0;
|
||||
int intval_ms = AT_CMD_DATA_INTERVAL_MS;
|
||||
at_task_t *tsk;
|
||||
|
||||
if (inited == 0) {
|
||||
atpsr_err("at have not init yet\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == cmd || cmdlen <= 0) {
|
||||
atpsr_err("%s invalid input \r\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == replybuf || 0 == bufsize) {
|
||||
atpsr_err("%s invalid input \r\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(at.at_uart_send_mutex);
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
tsk = (at_task_t *)HAL_Malloc(sizeof(at_task_t));
|
||||
#else
|
||||
tsk = &g_at_task;
|
||||
#endif
|
||||
if (NULL == tsk) {
|
||||
atpsr_err("tsk buffer allocating failed");
|
||||
HAL_MutexUnlock(at.at_uart_send_mutex);
|
||||
return -1;
|
||||
}
|
||||
memset(tsk, 0, sizeof(at_task_t));
|
||||
|
||||
tsk->smpr = HAL_SemaphoreCreate();
|
||||
if (NULL == tsk->smpr) {
|
||||
atpsr_err("failed to allocate semaphore");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (atcmdconfig) {
|
||||
if (NULL != atcmdconfig->reply_prefix) {
|
||||
tsk->rsp_prefix = atcmdconfig->reply_prefix;
|
||||
tsk->rsp_prefix_len = strlen(atcmdconfig->reply_prefix);
|
||||
}
|
||||
|
||||
if (NULL != atcmdconfig->reply_success_postfix) {
|
||||
tsk->rsp_success_postfix = atcmdconfig->reply_success_postfix;
|
||||
tsk->rsp_success_postfix_len = strlen(atcmdconfig->reply_success_postfix);
|
||||
}
|
||||
|
||||
if (NULL != atcmdconfig->reply_fail_postfix) {
|
||||
tsk->rsp_fail_postfix = atcmdconfig->reply_fail_postfix;
|
||||
tsk->rsp_fail_postfix_len = strlen(atcmdconfig->reply_fail_postfix);
|
||||
}
|
||||
}
|
||||
|
||||
tsk->command = (char *)cmd;
|
||||
tsk->rsp = replybuf;
|
||||
tsk->rsp_len = bufsize;
|
||||
|
||||
at_worker_task_add(tsk);
|
||||
|
||||
if ((ret = at_sendto_lower(at._pstuart, (void *)cmd, cmdlen,
|
||||
at._timeout, true)) != 0) {
|
||||
atpsr_err("uart send command failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (delimiter) {
|
||||
if ((ret = at_sendto_lower(at._pstuart, (void *)at._send_delimiter,
|
||||
strlen(at._send_delimiter), at._timeout, false)) != 0) {
|
||||
atpsr_err("uart send delimiter failed");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (data && datalen > 0) {
|
||||
if (intval_ms > 0)
|
||||
HAL_SleepMs(intval_ms);
|
||||
|
||||
if ((ret = at_sendto_lower(at._pstuart, (void *)data, datalen, at._timeout, true)) != 0) {
|
||||
atpsr_err("uart send delimiter failed");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = HAL_SemaphoreWait(tsk->smpr, TASK_DEFAULT_WAIT_TIME)) != 0) {
|
||||
atpsr_err("sem_wait failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
at_worker_task_del(tsk);
|
||||
HAL_MutexUnlock(at.at_uart_send_mutex);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int at_send_no_reply(const char *data, int datalen, bool delimiter)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (inited == 0) {
|
||||
atpsr_err("at have not init yet\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == data || datalen <= 0) {
|
||||
atpsr_err("invalid input \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(at.at_uart_send_mutex);
|
||||
if ((ret = at_sendto_lower(at._pstuart, (void *)data,
|
||||
datalen, at._timeout, true)) != 0) {
|
||||
atpsr_err("uart send raw content (%s) failed", data);
|
||||
HAL_MutexUnlock(at.at_uart_send_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (delimiter) {
|
||||
if ((ret = at_sendto_lower(at._pstuart, (void *)at._send_delimiter,
|
||||
strlen(at._send_delimiter), at._timeout, false)) != 0) {
|
||||
atpsr_err("uart send delimiter failed");
|
||||
HAL_MutexUnlock(at.at_uart_send_mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
HAL_MutexUnlock(at.at_uart_send_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int at_getc(char *c, int timeout_ms)
|
||||
{
|
||||
int ret = 0;
|
||||
char data;
|
||||
uint32_t recv_size = 0;
|
||||
|
||||
if (NULL == c) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (inited == 0) {
|
||||
atpsr_err("at have not init yet\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(at.at_uart_recv_mutex);
|
||||
ret = at_recvfrom_lower(at._pstuart, (void *)&data, 1, &recv_size, timeout_ms);
|
||||
HAL_MutexUnlock(at.at_uart_recv_mutex);
|
||||
|
||||
if (ret != 0) {
|
||||
#ifdef WORKAROUND_DEVELOPERBOARD_DMA_UART
|
||||
if (ret == 1) {
|
||||
HAL_UART_Deinit(at._pstuart);
|
||||
at_init_uart();
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recv_size == 1) {
|
||||
*c = data;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int at_read(char *outbuf, int readsize)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t recv_size, total_read = 0;
|
||||
|
||||
if (inited == 0) {
|
||||
atpsr_err("at have not init yet\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(at.at_uart_recv_mutex);
|
||||
while (total_read < readsize) {
|
||||
ret = at_recvfrom_lower(at._pstuart, (void *)(outbuf + total_read),
|
||||
readsize - total_read, &recv_size, at._timeout);
|
||||
if (ret != 0) {
|
||||
atpsr_err("at_read failed on uart_recv.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (recv_size <= 0) {
|
||||
continue;
|
||||
}
|
||||
total_read += recv_size;
|
||||
if (total_read >= readsize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
HAL_MutexUnlock(at.at_uart_recv_mutex);
|
||||
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return total_read;
|
||||
}
|
||||
|
||||
#define RECV_BUFFER_SIZE 512
|
||||
static char at_rx_buf[RECV_BUFFER_SIZE];
|
||||
int at_register_callback(const char *prefix, const char *postfix, char *recvbuf,
|
||||
int bufsize, at_recv_cb cb, void *arg)
|
||||
{
|
||||
oob_t *oob = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (bufsize < 0 || bufsize >= RECV_BUFFER_SIZE || NULL == prefix) {
|
||||
atpsr_err("%s invalid input \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != postfix && (NULL == recvbuf || 0 == bufsize)) {
|
||||
atpsr_err("%s invalid postfix input \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (at._oobs_num >= OOB_MAX) {
|
||||
atpsr_err("No place left in OOB.\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*check oob exist*/
|
||||
for (i = 0; i < at._oobs_num; i++) {
|
||||
if (NULL != at._oobs[i].prefix &&
|
||||
strcmp(prefix, at._oobs[i].prefix) == 0) {
|
||||
atpsr_warning("oob prefix %s is already exist.\r\n", prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
oob = &(at._oobs[at._oobs_num++]);
|
||||
|
||||
oob->oobinputdata = recvbuf;
|
||||
if (oob->oobinputdata != NULL) {
|
||||
memset(oob->oobinputdata, 0, bufsize);
|
||||
}
|
||||
oob->maxlen = bufsize;
|
||||
oob->prefix = (char *)prefix;
|
||||
oob->postfix = (char *)postfix;
|
||||
oob->cb = cb;
|
||||
oob->arg = arg;
|
||||
oob->reallen = 0;
|
||||
|
||||
atpsr_debug("New oob registered (%s)", oob->prefix);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at_scan_for_callback(char c, char *buf, int *index)
|
||||
{
|
||||
int k;
|
||||
oob_t *oob = NULL;
|
||||
int offset = *index;
|
||||
|
||||
if (!buf || offset < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (k = 0; k < at._oobs_num; k++) {
|
||||
oob = &(at._oobs[k]);
|
||||
if (oob->reallen > 0 ||
|
||||
(offset >= strlen(oob->prefix) &&
|
||||
memcmp(oob->prefix, buf + offset - strlen(oob->prefix),
|
||||
strlen(oob->prefix)) == 0)) {
|
||||
atpsr_debug("AT! %s\r\n", oob->prefix);
|
||||
if (oob->postfix == NULL) {
|
||||
oob->cb(oob->arg, NULL, 0);
|
||||
memset(buf, 0, offset);
|
||||
offset = 0;
|
||||
} else {
|
||||
if (oob->reallen == 0) {
|
||||
int len = strlen(oob->prefix) - 1;
|
||||
len = len > 0 ? len : 0;
|
||||
memset(oob->oobinputdata, 0, oob->maxlen);
|
||||
memcpy(oob->oobinputdata, oob->prefix, len);
|
||||
oob->reallen += len;
|
||||
}
|
||||
|
||||
if (oob->reallen < oob->maxlen) {
|
||||
oob->oobinputdata[oob->reallen] = c;
|
||||
oob->reallen++;
|
||||
if ((oob->reallen >=
|
||||
strlen(oob->prefix) + strlen(oob->postfix)) &&
|
||||
(strncmp(oob->oobinputdata + oob->reallen -
|
||||
strlen(oob->postfix),
|
||||
oob->postfix,
|
||||
strlen(oob->postfix)) == 0)) {
|
||||
/*recv postfix*/
|
||||
oob->cb(oob->arg, oob->oobinputdata, oob->reallen);
|
||||
memset(oob->oobinputdata, 0, oob->reallen);
|
||||
oob->reallen = 0;
|
||||
memset(buf, 0, offset);
|
||||
offset = 0;
|
||||
}
|
||||
} else {
|
||||
atpsr_err("invalid oob %s input , for oversize %s \r\n",
|
||||
oob->prefix, oob->oobinputdata);
|
||||
memset(oob->oobinputdata, 0, oob->reallen);
|
||||
oob->reallen = 0;
|
||||
memset(buf, 0, offset);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
/*oob data maybe more than buf size */
|
||||
if (offset > (RECV_BUFFER_SIZE - 2)) {
|
||||
memset(buf, 0, offset);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*index = offset;
|
||||
return;
|
||||
}
|
||||
|
||||
#if AT_SINGLE_TASK
|
||||
int at_yield(char *replybuf, int bufsize, const atcmd_config_t *atcmdconfig,
|
||||
int timeout_ms)
|
||||
{
|
||||
int offset = 0;
|
||||
int ret = 0;
|
||||
int rsp_prefix_len = 0;
|
||||
int rsp_success_postfix_len = 0;
|
||||
int rsp_fail_postfix_len = 0;
|
||||
int at_reply_begin = 0;
|
||||
int at_reply_offset = 0;
|
||||
char c = 0;
|
||||
char *buf = NULL;
|
||||
char *rsp_prefix = NULL;
|
||||
char *rsp_success_postfix = NULL;
|
||||
char *rsp_fail_postfix = NULL;
|
||||
|
||||
if (!inited) {
|
||||
atpsr_err("AT parser has not inited!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (replybuf != NULL && bufsize <= 0) {
|
||||
atpsr_err("buffer size %d unmatched!\r\n", bufsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = at_rx_buf;
|
||||
if (NULL == buf) {
|
||||
atpsr_err("AT worker fail to malloc ,task exist \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf, 0, RECV_BUFFER_SIZE);
|
||||
|
||||
while (true) {
|
||||
/* read from uart and store buf */
|
||||
ret = at_getc(&c, timeout_ms);
|
||||
if (ret != 0) {
|
||||
atpsr_err("at yield timeout break loop");
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset + 1 >= RECV_BUFFER_SIZE) {
|
||||
atpsr_err("buffer full");
|
||||
break;
|
||||
}
|
||||
buf[offset++] = c;
|
||||
buf[offset] = 0;
|
||||
|
||||
at_scan_for_callback(c, buf, &offset);
|
||||
|
||||
if (replybuf == NULL || bufsize <= 0) {
|
||||
/* if no task, continue recv */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL != atcmdconfig && NULL != atcmdconfig->reply_prefix) {
|
||||
rsp_prefix = atcmdconfig->reply_prefix;
|
||||
rsp_prefix_len = strlen(rsp_prefix);
|
||||
} else {
|
||||
rsp_prefix = at._default_recv_prefix;
|
||||
rsp_prefix_len = at._recv_prefix_len;
|
||||
}
|
||||
|
||||
if (NULL != atcmdconfig && NULL != atcmdconfig->reply_success_postfix) {
|
||||
rsp_success_postfix = atcmdconfig->reply_success_postfix;
|
||||
rsp_success_postfix_len = strlen(rsp_success_postfix);
|
||||
} else {
|
||||
rsp_success_postfix = at._default_recv_success_postfix;
|
||||
rsp_success_postfix_len = at._recv_success_postfix_len;
|
||||
}
|
||||
|
||||
if (NULL != atcmdconfig && NULL != atcmdconfig->reply_fail_postfix) {
|
||||
rsp_fail_postfix = atcmdconfig->reply_fail_postfix;
|
||||
rsp_fail_postfix_len = strlen(rsp_fail_postfix);
|
||||
} else {
|
||||
rsp_fail_postfix = at._default_recv_fail_postfix;
|
||||
rsp_fail_postfix_len = at._recv_fail_postfix_len;
|
||||
}
|
||||
|
||||
if (offset >= rsp_prefix_len && at_reply_begin == 0 &&
|
||||
(strncmp(buf + offset - rsp_prefix_len, rsp_prefix,
|
||||
rsp_prefix_len) == 0)) {
|
||||
at_reply_begin = 1;
|
||||
}
|
||||
|
||||
if (at_reply_begin == 1) {
|
||||
if (at_reply_offset < bufsize) {
|
||||
replybuf[at_reply_offset] = c;
|
||||
at_reply_offset++;
|
||||
|
||||
if ((at_reply_offset >= rsp_success_postfix_len &&
|
||||
strncmp(
|
||||
replybuf + at_reply_offset - rsp_success_postfix_len,
|
||||
rsp_success_postfix, rsp_success_postfix_len) == 0) ||
|
||||
(at_reply_offset >= rsp_fail_postfix_len &&
|
||||
strncmp(replybuf + at_reply_offset - rsp_fail_postfix_len,
|
||||
rsp_fail_postfix, rsp_fail_postfix_len) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
memset(replybuf, 0, bufsize);
|
||||
strcpy(replybuf, rsp_fail_postfix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
static void* at_worker(void *arg)
|
||||
{
|
||||
int offset = 0;
|
||||
int ret = 0;
|
||||
int at_task_empty = 0;
|
||||
int at_task_reponse_begin = 0;
|
||||
int memcpy_size = 0;
|
||||
int rsp_prefix_len = 0;
|
||||
int rsp_success_postfix_len = 0;
|
||||
int rsp_fail_postfix_len = 0;
|
||||
char c = 0;
|
||||
at_task_t *tsk;
|
||||
char *buf = NULL;
|
||||
char *rsp_prefix = NULL;
|
||||
char *rsp_success_postfix = NULL;
|
||||
char *rsp_fail_postfix = NULL;
|
||||
|
||||
atpsr_debug("at_work started.");
|
||||
|
||||
buf = at_rx_buf;
|
||||
if (NULL == buf) {
|
||||
atpsr_err("AT worker fail to malloc ,task exist \r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(buf, 0, RECV_BUFFER_SIZE);
|
||||
inited = 1;
|
||||
|
||||
while (true) {
|
||||
ret = at_getc(&c, at._timeout);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (offset + 1 >= RECV_BUFFER_SIZE) {
|
||||
atpsr_err("Fatal error, no one is handling AT uart");
|
||||
goto check_buffer;
|
||||
}
|
||||
buf[offset++] = c;
|
||||
buf[offset] = 0;
|
||||
|
||||
at_scan_for_callback(c, buf, &offset);
|
||||
|
||||
HAL_MutexLock(at.task_mutex);
|
||||
at_task_empty = slist_empty(&at.task_l);
|
||||
|
||||
if (!at_task_empty) {
|
||||
tsk = slist_first_entry(&at.task_l, at_task_t, next);
|
||||
}
|
||||
HAL_MutexUnlock(at.task_mutex);
|
||||
|
||||
/* if no task, continue recv */
|
||||
if (at_task_empty) {
|
||||
atpsr_debug("No task in queue");
|
||||
goto check_buffer;
|
||||
}
|
||||
|
||||
if (NULL != tsk->rsp_prefix && 0 != tsk->rsp_prefix_len) {
|
||||
rsp_prefix = tsk->rsp_prefix;
|
||||
rsp_prefix_len = tsk->rsp_prefix_len;
|
||||
} else {
|
||||
rsp_prefix = at._default_recv_prefix;
|
||||
rsp_prefix_len = at._recv_prefix_len;
|
||||
}
|
||||
|
||||
if (NULL != tsk->rsp_success_postfix &&
|
||||
0 != tsk->rsp_success_postfix_len) {
|
||||
rsp_success_postfix = tsk->rsp_success_postfix;
|
||||
rsp_success_postfix_len = tsk->rsp_success_postfix_len;
|
||||
} else {
|
||||
rsp_success_postfix = at._default_recv_success_postfix;
|
||||
rsp_success_postfix_len = at._recv_success_postfix_len;
|
||||
}
|
||||
|
||||
if (NULL != tsk->rsp_fail_postfix && 0 != tsk->rsp_fail_postfix_len) {
|
||||
rsp_fail_postfix = tsk->rsp_fail_postfix;
|
||||
rsp_fail_postfix_len = tsk->rsp_fail_postfix_len;
|
||||
} else {
|
||||
rsp_fail_postfix = at._default_recv_fail_postfix;
|
||||
rsp_fail_postfix_len = at._recv_fail_postfix_len;
|
||||
}
|
||||
|
||||
if (offset >= rsp_prefix_len && at_task_reponse_begin == 0 &&
|
||||
(strncmp(buf + offset - rsp_prefix_len, rsp_prefix,
|
||||
rsp_prefix_len) == 0)) {
|
||||
at_task_reponse_begin = 1;
|
||||
}
|
||||
|
||||
if (at_task_reponse_begin == 1) {
|
||||
if (tsk->rsp_offset < tsk->rsp_len) {
|
||||
tsk->rsp[tsk->rsp_offset] = c;
|
||||
tsk->rsp_offset++;
|
||||
|
||||
if ((tsk->rsp_offset >= rsp_success_postfix_len &&
|
||||
strncmp(
|
||||
tsk->rsp + tsk->rsp_offset - rsp_success_postfix_len,
|
||||
rsp_success_postfix, rsp_success_postfix_len) == 0) ||
|
||||
(tsk->rsp_offset >= rsp_fail_postfix_len &&
|
||||
strncmp(tsk->rsp + tsk->rsp_offset - rsp_fail_postfix_len,
|
||||
rsp_fail_postfix, rsp_fail_postfix_len) == 0)) {
|
||||
HAL_SemaphorePost(tsk->smpr);
|
||||
at_task_reponse_begin = 0;
|
||||
memset(buf, 0, offset);
|
||||
offset = 0;
|
||||
}
|
||||
} else {
|
||||
memset(tsk->rsp, 0, tsk->rsp_len);
|
||||
strcpy(tsk->rsp, rsp_fail_postfix);
|
||||
HAL_SemaphorePost(tsk->smpr);
|
||||
at_task_reponse_begin = 0;
|
||||
memset(buf, 0, offset);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
check_buffer:
|
||||
/* in case buffer is full */
|
||||
if (offset > (RECV_BUFFER_SIZE - 2)) {
|
||||
memcpy_size = rsp_prefix_len > rsp_success_postfix_len
|
||||
? rsp_prefix_len
|
||||
: rsp_success_postfix_len;
|
||||
memcpy_size = memcpy_size > rsp_fail_postfix_len
|
||||
? memcpy_size
|
||||
: rsp_fail_postfix_len;
|
||||
memcpy(buf, buf + offset - memcpy_size, memcpy_size);
|
||||
memset(buf + memcpy_size, 0, offset - memcpy_size);
|
||||
offset = memcpy_size;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
125
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_parser.h
vendored
Normal file
125
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_parser.h
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _AT_PARSER_H_
|
||||
#define _AT_PARSER_H_
|
||||
|
||||
#include "infra_config.h"
|
||||
|
||||
/* uart config */
|
||||
#define AT_UART_PORT 1
|
||||
#define AT_UART_LINUX_DEV "/dev/ttyUSB0"
|
||||
#define AT_UART_BAUDRATE 115200
|
||||
#define AT_UART_DATA_WIDTH DATA_WIDTH_8BIT
|
||||
#define AT_UART_PARITY NO_PARITY
|
||||
#define AT_UART_STOP_BITS STOP_BITS_1
|
||||
#define AT_UART_FLOW_CONTROL FLOW_CONTROL_DISABLED
|
||||
#define AT_UART_MODE MODE_TX_RX
|
||||
#define AT_UART_TIMEOUT_MS 1000
|
||||
|
||||
/* Delimiter */
|
||||
#define AT_RECV_PREFIX "\r\n"
|
||||
#define AT_RECV_SUCCESS_POSTFIX "OK\r\n"
|
||||
#define AT_RECV_FAIL_POSTFIX "ERROR\r\n"
|
||||
#define AT_SEND_DELIMITER "\r"
|
||||
|
||||
#if defined(AT_TCP_HAL_SIM800)
|
||||
#define AT_CMD_DATA_INTERVAL_MS 50
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
#define AT_SINGLE_TASK 0
|
||||
#else
|
||||
#define AT_SINGLE_TASK 1
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#define bool unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *reply_prefix;
|
||||
char *reply_success_postfix;
|
||||
char *reply_fail_postfix;
|
||||
} atcmd_config_t;
|
||||
|
||||
typedef void (*at_recv_cb)(void *arg, char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* initialization
|
||||
* Configuration (e.g. AT_UART_PORT, UART_BAUDRATE) can be found
|
||||
* in above macro
|
||||
*/
|
||||
int at_parser_init(void);
|
||||
|
||||
/**
|
||||
* at send (format: command + delimiter + data) and wait reply
|
||||
*
|
||||
* @param cmd at command sending buf. MUST not be NULL.
|
||||
* @param cmdlen at command length.
|
||||
* @param delimiter whether sending delimiter, usually value is true
|
||||
* @param data data sending buf. NULL if no data.
|
||||
* @param datalen data length. Zero if no data.
|
||||
* @param replybuf reply buffer. MUST not be NULL.
|
||||
* @param bufsize reply buffer size
|
||||
* @param atcmdconfig AT cmd reply format config. Use default if NULL
|
||||
*/
|
||||
int at_send_wait_reply(const char *cmd, int cmdlen, bool delimiter,
|
||||
const char *data, int datalen,
|
||||
char *replybuf, int bufsize,
|
||||
const atcmd_config_t *atcmdconfig);
|
||||
|
||||
/**
|
||||
* at send (format: data + delimiter) and does not wait reply
|
||||
*
|
||||
* @param data sending buffer.
|
||||
* @param datalen sending length.
|
||||
* @param delimiter whether sending delimiter, usually value is false
|
||||
*/
|
||||
int at_send_no_reply(const char *data, int datalen, bool delimiter);
|
||||
|
||||
|
||||
/**
|
||||
* at read for certain bytes of data
|
||||
*
|
||||
* @param outbuf output buffer.
|
||||
* @param readsize read size.
|
||||
*/
|
||||
int at_read(char *outbuf, int readsize);
|
||||
|
||||
|
||||
/**
|
||||
* at register callback for recv
|
||||
*
|
||||
* @param prefix interested string. Must not be NULL.
|
||||
* @param postfix intersted postfix. NULL if postfix not provided.
|
||||
* @param recvbuf recv data buffer provided by caller, NULL if postfix not provided
|
||||
* @param bufsize buffer size for recv data, zero if postfix not provided
|
||||
* @param cb callback handle function. Must not be NULL.
|
||||
* @param arg callback handle function args. NULL if not used.
|
||||
*/
|
||||
int at_register_callback(const char *prefix, const char *postfix, char *recvbuf,
|
||||
int bufsize, at_recv_cb cb, void *arg);
|
||||
|
||||
|
||||
/**
|
||||
* at yield receive function. Only used in single task scenario
|
||||
*
|
||||
* @param replybuf reply buffer.
|
||||
* @param bufsize reply buffer size.
|
||||
* @param atcmdconfig AT cmd reply format config. Use default if NULL
|
||||
* @param timeout_ms receive timeout in millisecond
|
||||
*/
|
||||
int at_yield(char *replybuf, int bufsize, const atcmd_config_t *atcmdconfig,
|
||||
int timeout_ms);
|
||||
#endif
|
||||
|
||||
|
183
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_tcp.c
vendored
Normal file
183
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_tcp.c
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "infra_config.h"
|
||||
|
||||
#include "at_conn_mgmt.h"
|
||||
|
||||
#include "at_wrapper.h"
|
||||
|
||||
#ifdef AT_PARSER_ENABLED
|
||||
#include "at_parser.h"
|
||||
#endif
|
||||
|
||||
static uint64_t _get_time_ms(void)
|
||||
{
|
||||
return HAL_UptimeMs();
|
||||
}
|
||||
|
||||
static uint64_t _time_left(uint64_t t_end, uint64_t t_now)
|
||||
{
|
||||
uint64_t t_left;
|
||||
|
||||
if (t_end > t_now) {
|
||||
t_left = t_end - t_now;
|
||||
} else {
|
||||
t_left = 0;
|
||||
}
|
||||
|
||||
return t_left;
|
||||
}
|
||||
|
||||
uintptr_t AT_TCP_Establish(const char *host, uint16_t port)
|
||||
{
|
||||
int fd = 0;
|
||||
int rc = 0;
|
||||
char resultip[16];
|
||||
|
||||
HAL_Printf("establish tcp connection with server(host='%s', port=[%u])\n", host, port);
|
||||
|
||||
if ((rc = at_conn_getaddrinfo(host, resultip)) != 0) {
|
||||
HAL_Printf("getaddrinfo error(%d), host = '%s', port = [%d]\n", rc, host, port);
|
||||
return (uintptr_t)(-1);
|
||||
}
|
||||
|
||||
fd = at_conn_setup(NETCONN_TCP);
|
||||
if (fd < 0) {
|
||||
HAL_Printf("create at conn error\n");
|
||||
return (uintptr_t)(-1);
|
||||
}
|
||||
|
||||
if (at_conn_start(fd, resultip, port) == 0) {
|
||||
rc = fd;
|
||||
} else {
|
||||
at_conn_close(fd);
|
||||
HAL_Printf("connect error\n");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (-1 == rc) {
|
||||
HAL_Printf("fail to establish tcp\n");
|
||||
} else {
|
||||
HAL_Printf("success to establish tcp, fd=%d\n", rc);
|
||||
}
|
||||
|
||||
return (uintptr_t)rc;
|
||||
}
|
||||
|
||||
int AT_TCP_Destroy(uintptr_t fd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = at_conn_close((int) fd);
|
||||
if (0 != rc) {
|
||||
HAL_Printf("closesocket error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t AT_TCP_Write(uintptr_t fd, const char *buf, uint32_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int ret;
|
||||
uint32_t len_sent;
|
||||
uint64_t t_end;
|
||||
int net_err = 0;
|
||||
|
||||
t_end = _get_time_ms() + timeout_ms;
|
||||
len_sent = 0;
|
||||
ret = 1; /* send one time if timeout_ms is value 0 */
|
||||
|
||||
do {
|
||||
ret = at_conn_send(fd, buf + len_sent, len - len_sent);
|
||||
if (ret > 0) {
|
||||
len_sent += ret;
|
||||
} else if (0 == ret) {
|
||||
HAL_Printf("No data be sent\n");
|
||||
} else {
|
||||
HAL_Printf("send fail, ret = send() = %d\n", ret);
|
||||
net_err = 1;
|
||||
break;
|
||||
}
|
||||
} while (!net_err && (len_sent < len) && (_time_left(t_end, _get_time_ms()) > 0));
|
||||
|
||||
if (net_err) {
|
||||
return -1;
|
||||
} else {
|
||||
return len_sent;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t AT_TCP_Read(uintptr_t fd, char *buf, uint32_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int ret, err_code;
|
||||
uint32_t len_recv;
|
||||
uint64_t t_end, t_left;
|
||||
int empty;
|
||||
|
||||
t_end = _get_time_ms() + timeout_ms;
|
||||
len_recv = 0;
|
||||
err_code = 0;
|
||||
|
||||
do {
|
||||
t_left = _time_left(t_end, _get_time_ms());
|
||||
if (0 == t_left) {
|
||||
break;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
#ifdef AT_PARSER_ENABLED
|
||||
#if AT_SINGLE_TASK
|
||||
at_yield(NULL, 0, NULL, 100);
|
||||
#endif
|
||||
#endif
|
||||
empty = at_conn_recvbufempty(fd);
|
||||
if (0 == empty) {
|
||||
ret = 1;
|
||||
break;
|
||||
} else if (empty < 0) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
t_left = _time_left(t_end, _get_time_ms());
|
||||
if (0 == t_left) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
HAL_SleepMs(10);
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
ret = at_conn_recv(fd, buf + len_recv, len - len_recv);
|
||||
if (ret > 0) {
|
||||
len_recv += ret;
|
||||
} else if (0 == ret) {
|
||||
HAL_Printf("connection is closed\n");
|
||||
err_code = -1;
|
||||
break;
|
||||
} else {
|
||||
HAL_Printf("recv fail\n");
|
||||
err_code = -2;
|
||||
break;
|
||||
}
|
||||
} else if (0 == ret) {
|
||||
break;
|
||||
} else {
|
||||
HAL_Printf("select-recv fail\n");
|
||||
err_code = -2;
|
||||
break;
|
||||
}
|
||||
} while ((len_recv < len));
|
||||
|
||||
/* priority to return data bytes if any data be received from TCP connection. */
|
||||
/* It will get error code on next calling */
|
||||
return (0 != len_recv) ? len_recv : err_code;
|
||||
}
|
||||
|
291
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_wrapper.h
vendored
Normal file
291
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/at_wrapper.h
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _AT_WRAPPER_H_
|
||||
#define _AT_WRAPPER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "wrappers_defs.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (void *)0
|
||||
#endif
|
||||
|
||||
void *HAL_Malloc(uint32_t size);
|
||||
void HAL_Free(void *ptr);
|
||||
void HAL_Printf(const char *fmt, ...);
|
||||
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
|
||||
uint64_t HAL_UptimeMs(void);
|
||||
void *HAL_MutexCreate(void);
|
||||
void HAL_MutexDestroy(void *mutex);
|
||||
void HAL_MutexLock(void *mutex);
|
||||
void HAL_MutexUnlock(void *mutex);
|
||||
void HAL_SleepMs(uint32_t ms);
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
void *HAL_SemaphoreCreate(void);
|
||||
void HAL_SemaphoreDestroy(void *sem);
|
||||
void HAL_SemaphorePost(void *sem);
|
||||
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms);
|
||||
|
||||
int HAL_ThreadCreate(
|
||||
void **thread_handle,
|
||||
void *(*work_routine)(void *),
|
||||
void *arg,
|
||||
hal_os_thread_param_t *hal_os_thread_param,
|
||||
int *stack_used);
|
||||
#endif
|
||||
|
||||
#define HAL_WAIT_FOREVER 0xFFFFFFFFU
|
||||
|
||||
|
||||
#if defined(AT_PARSER_ENABLED)
|
||||
/*
|
||||
* UART data width
|
||||
*/
|
||||
typedef enum {
|
||||
DATA_WIDTH_5BIT,
|
||||
DATA_WIDTH_6BIT,
|
||||
DATA_WIDTH_7BIT,
|
||||
DATA_WIDTH_8BIT,
|
||||
DATA_WIDTH_9BIT
|
||||
} hal_uart_data_width_t;
|
||||
|
||||
/*
|
||||
* UART stop bits
|
||||
*/
|
||||
typedef enum {
|
||||
STOP_BITS_1,
|
||||
STOP_BITS_2
|
||||
} hal_uart_stop_bits_t;
|
||||
|
||||
/*
|
||||
* UART flow control
|
||||
*/
|
||||
typedef enum {
|
||||
FLOW_CONTROL_DISABLED,
|
||||
FLOW_CONTROL_CTS,
|
||||
FLOW_CONTROL_RTS,
|
||||
FLOW_CONTROL_CTS_RTS
|
||||
} hal_uart_flow_control_t;
|
||||
|
||||
/*
|
||||
* UART parity
|
||||
*/
|
||||
typedef enum {
|
||||
NO_PARITY,
|
||||
ODD_PARITY,
|
||||
EVEN_PARITY
|
||||
} hal_uart_parity_t;
|
||||
|
||||
/*
|
||||
* UART mode
|
||||
*/
|
||||
typedef enum {
|
||||
MODE_TX,
|
||||
MODE_RX,
|
||||
MODE_TX_RX
|
||||
} hal_uart_mode_t;
|
||||
|
||||
/*
|
||||
* UART configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t baud_rate;
|
||||
hal_uart_data_width_t data_width;
|
||||
hal_uart_parity_t parity;
|
||||
hal_uart_stop_bits_t stop_bits;
|
||||
hal_uart_flow_control_t flow_control;
|
||||
hal_uart_mode_t mode;
|
||||
} uart_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t port; /* uart port */
|
||||
uart_config_t config; /* uart config */
|
||||
void *priv; /* priv data */
|
||||
} uart_dev_t;
|
||||
|
||||
/**
|
||||
* Initialises a UART interface
|
||||
*
|
||||
*
|
||||
* @param[in] uart the interface which should be initialised
|
||||
*
|
||||
* @return 0 : on success, EIO : if an error occurred with any step
|
||||
*/
|
||||
int32_t HAL_AT_Uart_Init(uart_dev_t *uart);
|
||||
|
||||
/**
|
||||
* Deinitialises a UART interface
|
||||
*
|
||||
* @param[in] uart the interface which should be deinitialised
|
||||
*
|
||||
* @return 0 : on success, EIO : if an error occurred with any step
|
||||
*/
|
||||
int32_t HAL_AT_Uart_Deinit(uart_dev_t *uart);
|
||||
|
||||
/**
|
||||
* Transmit data on a UART interface
|
||||
*
|
||||
* @param[in] uart the UART interface
|
||||
* @param[in] data pointer to the start of data
|
||||
* @param[in] size number of bytes to transmit
|
||||
* @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
|
||||
* if you want to wait forever
|
||||
*
|
||||
* @return 0 : on success, EIO : if an error occurred with any step
|
||||
*/
|
||||
int32_t HAL_AT_Uart_Send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Receive data on a UART interface
|
||||
*
|
||||
* @param[in] uart the UART interface
|
||||
* @param[out] data pointer to the buffer which will store incoming data
|
||||
* @param[in] expect_size number of bytes to receive
|
||||
* @param[out] recv_size number of bytes received
|
||||
* @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
|
||||
* if you want to wait forever
|
||||
*
|
||||
* @return 0 : on success, EIO : if an error occurred with any step
|
||||
*/
|
||||
int32_t HAL_AT_Uart_Recv(uart_dev_t *uart, void *data, uint32_t expect_size,
|
||||
uint32_t *recv_size, uint32_t timeout);
|
||||
#endif
|
||||
|
||||
#if defined(AT_TCP_ENABLED)
|
||||
typedef enum {
|
||||
/* WiFi */
|
||||
TCP_SERVER,
|
||||
TCP_CLIENT,
|
||||
SSL_CLIENT,
|
||||
UDP_BROADCAST,
|
||||
UDP_UNICAST,
|
||||
/*WiFi end */
|
||||
/* Add others hereafter */
|
||||
} CONN_TYPE;
|
||||
|
||||
/* Fill necessary fileds according to the socket type. */
|
||||
typedef struct {
|
||||
int fd; /* fd that are used in socket level */
|
||||
CONN_TYPE type;
|
||||
char *addr; /* remote ip or domain */
|
||||
int32_t r_port; /* remote port (set to -1 if not used) */
|
||||
int32_t l_port; /* local port (set to -1 if not used) */
|
||||
uint32_t tcp_keep_alive; /* tcp keep alive value (set to 0 if not used) */
|
||||
} at_conn_t;
|
||||
|
||||
struct at_conn_input {
|
||||
int fd;
|
||||
void *data;
|
||||
uint32_t datalen;
|
||||
char *remote_ip;
|
||||
uint16_t remote_port;
|
||||
};
|
||||
|
||||
/**
|
||||
* Module low level init so that it's ready to setup socket connection.
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int HAL_AT_CONN_Init(void);
|
||||
|
||||
|
||||
/**
|
||||
* Start a socket connection via module.
|
||||
*
|
||||
* @param[in] conn - connect parameters which are used to setup
|
||||
* the socket connection.
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int HAL_AT_CONN_Start(at_conn_t *conn);
|
||||
|
||||
|
||||
/**
|
||||
* Send data via module.
|
||||
* This function does not return until all data sent.
|
||||
*
|
||||
* @param[in] fd - the file descripter to operate on.
|
||||
* @param[in] data - pointer to data to send.
|
||||
* @param[in] len - length of the data.
|
||||
* @param[in] remote_ip - remote port number (optional).
|
||||
* @param[in] remote_port - remote port number (optional).
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int HAL_AT_CONN_Send(int fd, uint8_t *data, uint32_t len, char remote_ip[16],
|
||||
int32_t remote_port, int32_t timeout);
|
||||
|
||||
|
||||
/**
|
||||
* Get IP information of the corresponding domain.
|
||||
* Currently only one IP string is returned (even when the domain
|
||||
* coresponses to mutliple IPs). Note: only IPv4 is supported.
|
||||
*
|
||||
* @param[in] domain - the domain string.
|
||||
* @param[out] ip - the place to hold the dot-formatted ip string.
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int HAL_AT_CONN_DomainToIp(char *domain, char ip[16]);
|
||||
|
||||
|
||||
/**
|
||||
* Close the socket connection.
|
||||
*
|
||||
* @param[in] fd - the file descripter to operate on.
|
||||
* @param[in] remote_port - remote port number (optional).
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int HAL_AT_CONN_Close(int fd, int32_t remote_port);
|
||||
|
||||
|
||||
/**
|
||||
* Destroy SAL or exit low level state if necessary.
|
||||
*
|
||||
* @return 0 - success, -1 - failure
|
||||
*/
|
||||
int HAL_AT_CONN_Deinit(void);
|
||||
|
||||
#elif defined(AT_MQTT_ENABLED)
|
||||
#include "mqtt_api.h"
|
||||
|
||||
struct at_mqtt_input {
|
||||
char *topic;
|
||||
uint32_t topic_len;
|
||||
char *message;
|
||||
uint32_t msg_len;
|
||||
};
|
||||
|
||||
int HAL_AT_MQTT_Init(iotx_mqtt_param_t *pInitParams);
|
||||
int HAL_AT_MQTT_Deinit(void);
|
||||
int HAL_AT_MQTT_Connect(char *proKey, char *devName, char *devSecret);
|
||||
int HAL_AT_MQTT_Disconnect(void);
|
||||
int HAL_AT_MQTT_Subscribe(const char *topic, int qos, unsigned int *mqtt_packet_id, int *mqtt_status, int timeout_ms);
|
||||
int HAL_AT_MQTT_Unsubscribe(const char *topic, unsigned int *mqtt_packet_id, int *mqtt_status);
|
||||
int HAL_AT_MQTT_Publish(const char *topic, int qos, const char *message, unsigned int msg_len);
|
||||
int HAL_AT_MQTT_State(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
19
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/iot.mk
vendored
Normal file
19
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/atm/iot.mk
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
LIBA_TARGET := libiot_at.a
|
||||
|
||||
HDR_REFS := src/infra
|
||||
|
||||
ifneq (,$(filter -DATM_ENABLED, $(CFLAGS)))
|
||||
LIB_SRCS_PATTERN += at_api.c
|
||||
|
||||
ifneq (,$(filter -DAT_TCP_ENABLED, $(CFLAGS)))
|
||||
LIB_SRCS_PATTERN += at_conn_mbox.c at_conn_mgmt.c at_tcp.c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter -DAT_MQTT_ENABLED, $(CFLAGS)))
|
||||
LIB_SRCS_PATTERN += at_mqtt.c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter -DAT_PARSER_ENABLED, $(CFLAGS)))
|
||||
LIB_SRCS_PATTERN += at_parser.c
|
||||
endif
|
||||
endif
|
Reference in New Issue
Block a user