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:
dcxajichu
2019-10-31 16:36:28 +08:00
parent 30ea36a7ab
commit 8c24d921b0
692 changed files with 199829 additions and 0 deletions

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

View 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

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

View 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_*/

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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

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

View 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

View 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