esp8266 AT命令解析

直接貼代碼 ,  感冒好了有空再來註釋 , 原則就是基於sscanf來做命令解析。

#include "init_d.h"
#include "miscdevice.h"
#include "log.h"
#include "cmsis_os.h"
#include "stdlib.h"
#include "esp8266.h"
#include "stp_socket.h"

#define TAG "WIFI"

xTaskHandle app_handle;
unsigned portBASE_TYPE wifi_free_map;

/*
* 146 remaining with printf memory
* 182 remaining without using printf memory
*/

uint8_t wifi_buff[256];
int id = -1;
int status = 0;
esp_wifi_config_t cfg = {
    .sta =
        {
            .ssid = "********",
            .password = "********",
        }};

int wifi_recv(int8_t id, char *data, uint16_t len)
{
    LOGD(TAG, "%d->%d:%s\n", id, len, data);
    return 0;
}

void app_setup(void const *arg)
{
    configASSERT(((unsigned long)arg) == 0);

    socket_init();
    esp_set_wifi_config(&cfg);
    socket_regist_recv_event(wifi_recv);
    while (1)
    {

        switch (status)
        {
        case 0:
        {
            socket_reset();
            status = 1;
            break;
        }
        case 1:
        {
            if ((id = socket_connect("192.168.10.144", 8080, SOCKET_TCP)) >= 0)
            {
                status = 2;
            }
            else
            {
                status = 0;
            }

            break;
        }
        case 2:
        {
            if (socket_write(id, "1111111111", 10) < 0)
            {

                socket_disconnect(id);
                status = 1;
            }
            break;
        }
        default:
            break;
        }

        wifi_free_map = uxTaskGetStackHighWaterMark(app_handle);
        osDelay(1000);
    }
}

int app_init(void)
{
    LOG_ADD(TAG, _LOG_DEBUG);

    osThreadDef(app_task, app_setup, osPriorityNormal, 0, 256);
    app_handle = osThreadCreate(osThread(app_task), NULL);
    configASSERT(app_handle);

    return 0;
}

task_init(app_init);

 

 

#ifndef __ESP8266_H__
#define __ESP8266_H__
#include <stdint.h>
#include "stp_socket.h"
#include "stm32l4xx.h"

#define ESP_USE_RTOS (1)

#define ESP_CONN_MUX (0) //set multi connect

#define ESP_TIMEROUT_READY (30000)
#define ESP_POWERON_TIMEROUT_TIMES (30000)

#define ESP_AT_OK "OK"
#define ESP_AT_ERROR "ERROR"

#define ESP_WIFI_SSID_DEFAULT "Xiaomi_2601"
#define ESP_WIFI_PASSWD_DEFAULT "hhyjq2601"

#define ESP_IPV4_ADDR_LEN (16)

#define ESP_WIFI_DEFAULT()                           \
    {                                                \
        .mode = ESP_MODE_STA,                        \
        .dhcp = ESP_DHCP_ON,                         \
        .autoconn = ESP_AUTOCONN_ON,                 \
        .sta =                                       \
            {                                        \
                .set = true,                         \
                .ssid = ESP_WIFI_SSID_DEFAULT,       \
                .password = ESP_WIFI_PASSWD_DEFAULT, \
            }};

#define ESP_WIFI_NOINIT()                 \
    {                                     \
        .mode = ESP_MODE_DEFAULT,         \
        .dhcp = ESP_DHCP_DEFAULT,         \
        .autoconn = ESP_AUTOCONN_DEFAULT, \
        .sta =                            \
            {                             \
                .set = false,             \
            }};

typedef enum
{
    ESP_RTN_ERROR,
    ESP_RTN_OK,
} esp_rtn_t;

typedef enum
{
    ESP_MODE_INIT,
    ESP_MODE_STA,
    ESP_MODE_AP,
    ESP_MODE_APSTA,
    ESP_MODE_DEFAULT,
} esp_mode_t;

typedef enum
{
    ESP_DHCP_OFF,
    ESP_DHCP_ON,
    ESP_DHCP_DEFAULT,
} esp_dhcp_t;

typedef enum
{
    ESP_MUX_OFF,
    ESP_MUX_ON,
    ESP_MUX_DEFAULT,
} esp_mux_t;

typedef enum
{
    ESP_AUTOCONN_OFF,
    ESP_AUTOCONN_ON,
    ESP_AUTOCONN_DEFAULT,
} esp_autoconn_t;

#if 0
    ESP_CMD_AT,         //3
    ESP_CMD_ATE1,       //4
    ESP_CMD_MODE,       //5
    ESP_CMD_DHCP,       //6
    ESP_CMD_AUTOCONN,   //7
#endif
typedef enum
{
    ESP_CMD_NULL,         //0
    ESP_CMD_READY,        //1
    ESP_CMD_WIFI_CONN,    //2
    ESP_CMD_WIFI_GOTIP,   //3
    ESP_CMD_OK,           //4
    ESP_CMD_ERROR,        //5
    ESP_CMD_FAIL,         //6
    ESP_CMD_CONN_STATUS,  //7
    ESP_CMD_SEND_READY,   //8
    ESP_CMD_SEND_OK,      //9
    ESP_CMD_SEND_FAIL,    //10
    ESP_CMD_LINK_NOVALID, //11
    ESP_CMD_ALARY_CONN,   //12
    ESP_CMD_INIT,
    ESP_CMD_MAX,
} esp_cmd_t;

typedef enum
{
    ESP_INIT_CONFIG,
    ESP_INIT_DONE,
} esp_init_t;

typedef enum
{
    ESP_DISCONNECT_STATUS,
    ESP_CONNECT_STATUS
} esp_conn_status_t;

typedef enum
{
    ESP_CONFIG_RESET,         //0
    ESP_CONFIG_READY,         //1
    ESP_C0NFIG_CONNECTSTATUS, //2
    ESP_CONFIG_GOTIP,         //3
    ESP_CONFIG_ATE0,          //4
    ESP_CONFIG_MODE,          //5
    ESP_CONFIG_HDCP,          //6
    ESP_CONFIG_AUTO,          //7
    ESP_CONFIG_MUX,           //8
    ESP_CONFIG_APCFG,         //9
    ESP_CONFIG_DONE,          //10
    ESP_CONFIG_MAX,           //

} esp_init_config_t;

#if (ESP_USE_RTOS == 0)
#define esp_set_bits(x, y) \
    do                     \
    {                      \
        (x) |= (1 << (y)); \
    } while (0)

/*
*
*/
#define esp_clr_bits(x, y)    \
    do                        \
    {                         \
        (x) &= (~(1 << (y))); \
    } while (0)

/*
*
*/
#define esp_wait_arg(c, x, t, y_e, n_e, cmd)      \
    do                                            \
    {                                             \
        if (esp_wait_timer == 0)                  \
        {                                         \
            esp_wait_timer = HAL_GetTick();       \
            if (c != NULL)                        \
            {                                     \
                esp_write(c, strlen(c));          \
            }                                     \
        }                                         \
        if (HAL_GetTick() - esp_wait_timer > t)   \
        {                                         \
            esp_config_status = n_e;              \
            esp_wait_timer = 0;                   \
        }                                         \
        if (esp_is_bits(esp_config.events, cmd))  \
        {                                         \
            esp_clr_bits(esp_config.events, cmd); \
            esp_config_status = x ? y_e : n_e;    \
            esp_wait_timer = 0;                   \
        }                                         \
    } while (0)

/*
*
*/
#define esp_is_bits(x, y) (((x) & (1 << (y))))

#else

/*
*
*/
#define ESP_EVENT_BIT(x) (1UL << x)

/*
*
*/
#define esp_wait_event(cmd, delay)                                                                               \
    do                                                                                                           \
    {                                                                                                            \
        EventBits_t bits;                                                                                        \
        bits = xEventGroupWaitBits(esp_events, ESP_EVENT_BIT(cmd), pdTRUE, pdFALSE, delay / portTICK_PERIOD_MS); \
        if (bits & ESP_EVENT_BIT(cmd) == 0)                                                                      \
        {                                                                                                        \
            return -ETIMEOUT;                                                                                    \
        }                                                                                                        \
    } while (0)

#define esp_read_events(events, time) xEventGroupWaitBits(esp_events, events, pdTRUE, pdFALSE, time / portTICK_PERIOD_MS)
/*
*
*/

#define esp_wait_arg(c, x, t, y_e, n_e, cmd)                                            \
    do                                                                                  \
    {                                                                                   \
        EventBits_t bits;                                                               \
        if (esp_wait_timer == 0)                                                        \
        {                                                                               \
            esp_wait_timer = HAL_GetTick();                                             \
            if (c != NULL)                                                              \
            {                                                                           \
                xEventGroupClearBits(esp_events, ESP_EVENT_BIT(cmd));                   \
                esp_write(c, strlen(c));                                                \
            }                                                                           \
        }                                                                               \
        if (HAL_GetTick() - esp_wait_timer > t)                                         \
        {                                                                               \
            esp_config_status = n_e;                                                    \
            esp_wait_timer = 0;                                                         \
        }                                                                               \
        bits = xEventGroupWaitBits(esp_events, ESP_EVENT_BIT(cmd), pdTRUE, pdFALSE, 1); \
        if ((bits & ESP_EVENT_BIT(cmd)) != 0)                                           \
        {                                                                               \
            esp_config_status = x ? y_e : n_e;                                          \
            esp_wait_timer = 0;                                                         \
        }                                                                               \
    } while (0)

//esp_write(c, l);
#define esp_set_argv(y_e, n_e, t, format, ...)                                                                                \
    do                                                                                                                        \
    {                                                                                                                         \
        EventBits_t bits;                                                                                                     \
        if (esp_wait_timer == 0)                                                                                              \
        {                                                                                                                     \
            esp_wait_timer = HAL_GetTick();                                                                                   \
            xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR));                       \
            esp_pack_argv(format, ##__VA_ARGS__);                                                                             \
        }                                                                                                                     \
        if (HAL_GetTick() - esp_wait_timer > t)                                                                               \
        {                                                                                                                     \
            esp_config_status = n_e;                                                                                          \
            esp_wait_timer = 0;                                                                                               \
        }                                                                                                                     \
        bits = xEventGroupWaitBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR), pdTRUE, pdFALSE, 1); \
        if ((bits & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)                                                                          \
        {                                                                                                                     \
            esp_config_status = y_e;                                                                                          \
            esp_wait_timer = 0;                                                                                               \
        }                                                                                                                     \
        else if ((bits & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)                                                                  \
        {                                                                                                                     \
            esp_config_status = n_e;                                                                                          \
            esp_wait_timer = 0;                                                                                               \
        }                                                                                                                     \
    } while (0)

#endif // end of events define

typedef struct
{
    char set;
    char ssid[32];
    char password[64];
    char bssid[64];
    int channel;
    int rssi;
    char ip[ESP_IPV4_ADDR_LEN];
    char gateway[ESP_IPV4_ADDR_LEN];
    char netmask[ESP_IPV4_ADDR_LEN];
} esp_wifi_sta_config_t;

typedef struct
{
    esp_mode_t mode;
    esp_dhcp_t dhcp;
    esp_autoconn_t autoconn;
    esp_wifi_sta_config_t sta;
} esp_wifi_config_t;

typedef struct
{
    volatile long events;
    volatile int8_t is_init;
    volatile int8_t ready;
    volatile int8_t wifi_connect;
    volatile int8_t got_ip;
    volatile int8_t atex;
    esp_wifi_config_t config;
    volatile int8_t conn_status[5];
    volatile int8_t isok;
    socket_status_t status;
} esp_config_t;

typedef char *(*atcmd_cb)(char *cmd, char *buffer);

typedef int8_t (*esp_event_cb)(esp_cmd_t cmd, int32_t status, int32_t val, char *buff);

typedef char (*esp_timerout_cb)(void);

typedef struct
{
    char *name;
    esp_cmd_t cmd;
    atcmd_cb cb;
} esp_atcmd_t;

typedef enum
{
    ESP_POWERON_EVENT,
} esp_wait_event_t;

typedef struct
{
    esp_wait_event_t event;
    int times;
    esp_timerout_cb cb;
} eps_timer_t;

void esp_reset(void);
int esp_write(char *data, uint8_t len);

int8_t esp_set_mode(esp_mode_t mode, uint8_t def);
//must be use<esp_set_mode> before
int8_t esp_set_dhcp(esp_dhcp_t dhcp, uint8_t def);
int8_t esp_set_autoconn(esp_autoconn_t autoconn);
int8_t esp_set_wifi_sta(char *ssid, char *passwd, uint8_t def);
int8_t esp_get_staip(esp_wifi_sta_config_t *sta_cfg);

int8_t eps_wifi_send(int8_t id, uint8_t *data, uint16_t len);
int8_t esp_set_wifi_config(esp_wifi_config_t *config);
void esp_wifi_init(esp_wifi_config_t *config);
int8_t esp_wifi_start(void);
void esp_wifi_reset(void);
#endif

 

#include <stdarg.h>
#include "esp8266.h"
#include "log.h"
#include "init_d.h"
#include "miscdevice.h"
#include "cmsis_os.h"
#include "err.h"

#define TAG "ESP"
#define MODULE_NAME "esp8266"

#define IOCTL_FLAG_USER_RESET_FIFO 0x02000001

static xTaskHandle esp_task_handle;
static DEV_HAND fd;
static DEV_HAND rst_fd;
static esp_event_cb esp_event_callback;
static esp_config_t esp_config;
static esp_init_config_t esp_config_status = ESP_CONFIG_RESET;
static volatile uint32_t esp_wait_timer = 0;
static EventGroupHandle_t esp_events;

static char *esp_set_cwjap_err[5] =
    {
        "return code error\n",
        "connect time out\n",
        "password err\n",
        "can't find ap\n",
        "connect fail\n"};

static char *esp_net_type[3] =
    {
        "TCP",
        "UDP",
        "SSL"};

char *atcmd_parser(char *buffer, char *format, char *argv)
{
    char *str = buffer;
    char argc = 0;

    while (*str != '\0')
    {
        if ((*str == '\r') || (*str == '\n') || (*str > 0x7F) || (*str == ' ') || (*str == ','))
        {
            *str++;
            continue;
        }
        if ((argc = sscanf(str, format, argv)) > 0)
        {
            break;
        }
    }

    if (argc)
    {
        return (str + strlen(argv));
    }

    return NULL;
}
/*
*Example:
char *esp_dhcp_cb(char *cmd, char *buffer)
{
    char str[7];
    char *rtstr = NULL;
    int mode = 0;
    int8_t result = -1;
    
    esp_config.dhcp = -EFAIL;
    memset(str, 0, sizeof(str));
    if ((rtstr = atcmd_parser(buffer, "%7s", str)) == NULL)
    {
        return buffer;
    }
    if ( (result = esp_judge_error(cmd, str)) < 0) //return OK
    {
        return buffer;
    }
    
    if( result )
    {
        sscanf(cmd, "%*[^=]=%d,%d", &mode, (int *)&esp_config.dhcp);
        LOGD(TAG, "mode=%d , dhcp=%d\n", mode, esp_config.dhcp);
        if (mode != esp_config.mode)
        {
            LOGW(TAG, "Set hdcp mode , is not the current mode->cur:%d ,get:%d\n", esp_config.mode, mode);
            esp_config.dhcp = -EFAIL;
        }
    }
    return rtstr;
}
*/
int8_t esp_judge_error(char *cmd, char *str)
{
    if (strncmp(str, ESP_AT_OK, strlen(ESP_AT_OK)) == 0)
    {
        return 1;
    }
    else if (strncmp(str, ESP_AT_ERROR, strlen(ESP_AT_ERROR)) == 0)
    {
        return 0;
    }
    else
    {
        LOGE(TAG, "%s parser error->%s\n", cmd, str);
    }
    return -1;
}

char *esp_coltd_cb(char *cmd, char *buffer)
{
    //char data[24];
    //char *rtstr = NULL;

    //memset(data, 0, sizeof(data));
    //if ((rtstr = atcmd_parser(buffer, "%[^\n]", data)) != NULL)
    //{
    //LOGD(TAG, " Company information:Ai-Thinker %s\n", data);
    // return rtstr;
    //}

    return buffer;
}

char *esp_ready_cb(char *cmd, char *buffer)
{
    esp_config.ready = 1;
    esp_event_callback(ESP_CMD_READY, 1, 0, NULL);
    return buffer;
}

char *esp_wifi_disconn_cb(char *cmd, char *buffer)
{
    esp_event_callback(ESP_CMD_WIFI_CONN, 0, 0, NULL);
    return buffer;
}

char *esp_wifi_conn_cb(char *cmd, char *buffer)
{
    esp_event_callback(ESP_CMD_WIFI_CONN, 1, 0, NULL);
    return buffer;
}

/* Sometimes the received data is incomplete, GOTIP is the important data, making a second judgment.
* example: I ESP[34911] : get:FI GOT IP
*/
char *esp_gotip_cb(char *cmd, char *buffer)
{
    esp_event_callback(ESP_CMD_WIFI_GOTIP, 1, 0, NULL);

    return buffer;
}

char *esp_at_ok(char *cmd, char *buffer)
{
    esp_config.isok = ESP_RTN_OK;
    return buffer;
    //return esp_inspect_ok_error(cmd, buffer, (int8_t *)&esp_config.isok);
}

char *esp_at_error(char *cmd, char *buffer)
{
    esp_config.isok = ESP_RTN_ERROR;
    return buffer;
    //return esp_inspect_ok_error(cmd, buffer, (int8_t *)&esp_config.isok);
}

char *esp_at_cwjap(char *cmd, char *buffer)
{
    char data[24];
    char *rtstr = NULL;

    memset(data, 0, sizeof(data));
    if ((rtstr = atcmd_parser(buffer, "%s", data)) != NULL)
    {
        if (strncmp(data, "FAIL", strlen("FAIL")) == 0)
        {
            int code = 0;
            sscanf(cmd, "%*[^:]:%d", &code);
            if (code < 5)
            {
                LOGD(TAG, "set wifi config:%s", esp_set_cwjap_err[code]);
            }
            return rtstr;
        }
    }

    LOGW(TAG, "CWJAP has no FAIL->%s.\n", buffer);
    return buffer;
}

char *esp_cipsta_cb(char *cmd, char *buffer)
{
    char type[64];
    char addr[64];

    memset(type, 0, sizeof(type));
    memset(addr, 0, sizeof(addr));
    if (sscanf(cmd, "%*[^:]:%[^:]:\"%[^\"]", type, addr) > 0)
    {
        LOGD(TAG, "%s->%s\n", type, addr);

        if (strncmp(type, "ip", strlen("ip")) == 0)
        {
            if (strlen(addr) < ESP_IPV4_ADDR_LEN)
            {
                memcpy(esp_config.config.sta.ip, addr, strlen(addr));
            }
        }
        else if (strncmp(type, "gateway", strlen("gateway")) == 0)
        {
            if (strlen(addr) < ESP_IPV4_ADDR_LEN)
            {
                memcpy(esp_config.config.sta.gateway, addr, strlen(addr));
            }
        }
        else if (strncmp(type, "netmask", strlen("netmask")) == 0)
        {
            if (strlen(addr) < ESP_IPV4_ADDR_LEN)
            {
                memcpy(esp_config.config.sta.netmask, addr, strlen(addr));
            }
        }
    }

    return buffer;
}

#if (ESP_CONN_MUX == 1)
char *esp_conn_status_cb(char *cmd, char *buffer)
{
    int id = -1;

    if (sscanf(cmd, "%d", &id) > 0)
    {
        char data[24];
        char *rtstr = NULL;

        memset(data, 0, sizeof(data));
        if ((rtstr = atcmd_parser(buffer, "%s", data)) != NULL)
        {
            if (strncmp(data, "CONNECT", strlen("CONNECT")) == 0)
            {
                esp_config.conn_status[id] = ESP_CONNECT_STATUS;
                LOGW(TAG, "%d connect\n", id);
                esp_event_callback(ESP_CMD_CONN_STATUS, id, esp_config.conn_status[id]);
                return rtstr;
            }
            if (strncmp(data, "CLOSE", strlen("CLOSE")) == 0)
            {
                esp_config.conn_status[id] = ESP_DISCONNECT_STATUS;
                LOGW(TAG, "%d disconnect\n", id);
                esp_event_callback(ESP_CMD_CONN_STATUS, id, esp_config.conn_status[id]);
                return rtstr;
            }
        }
    }

    return buffer;
}
#endif

#if (ESP_CONN_MUX != 1)
char *esp_connect_cb(char *cmd, char *buffer)
{
    esp_config.conn_status[0] = 1;
    esp_event_callback(ESP_CMD_CONN_STATUS, 0, esp_config.conn_status[0], NULL);
    return buffer;
}

char *esp_close_cb(char *cmd, char *buffer)
{
    esp_config.conn_status[0] = 0;
    esp_event_callback(ESP_CMD_CONN_STATUS, 0, esp_config.conn_status[0], NULL);
    return buffer;
}
#endif

char *esp_ipd_cb(char *cmd, char *buffer)
{
    char *data;
    int id = 0;
    int len = 0;
    char lentemp[10];
    memset(lentemp, 0, sizeof(lentemp));
    sscanf(buffer, "%[^:]", lentemp);
#if (ESP_CONN_MUX == 1)
    sscanf(lentemp, "%d,%d", &id, &len);
#else
    sscanf(lentemp, ",%d", &len);
#endif
    data = buffer + strlen(lentemp) + 1;
    stp_socket_status_events(SOCKET_RECV, id, len, data);
    LOGD(TAG, "id = %d, len = %d\r\ndata=%s\r\n", id, len, data);

    return data + len;
}

#if 0

//inspect OK or ERROR
char *esp_inspect_ok_error(char *cmd, char *buffer, int8_t *result)
{
    char temp[7];
    char *resback = buffer;

    memset(temp, 0, sizeof(temp));
    if ((resback = atcmd_parser(buffer, "%7s", temp)) == NULL)
    {
        LOGW(TAG, "%s no data\n", cmd);

        *result = -ENODATA;
        return buffer;
    }

    if ((strlen(temp) == strlen(ESP_AT_OK)) &&
        (strncmp(temp, ESP_AT_OK, strlen(ESP_AT_OK)) == 0))
    {
        *result = ETOK;
        return resback;
    }
    else if ((strlen(temp) == strlen(ESP_AT_ERROR)) &&
             (strncmp(temp, ESP_AT_ERROR, strlen(ESP_AT_ERROR)) == 0))
    {
        *result = -EERROR;
        LOGW(TAG, "%s return ERROR\n", cmd);
        return resback;
    }
    else
    {
        LOGE(TAG, "%s data no ok/error->%s\n", cmd, temp);
    }
    *result = -ENODATA;
    return buffer;
}

char *esp_at_cb(char *cmd, char *buffer)
{
    return esp_inspect_ok_error(cmd, buffer, (int8_t *)&esp_config.at);
}

char *esp_ate1_cb(char *cmd, char *buffer)
{
    return esp_inspect_ok_error(cmd, buffer, (int8_t *)&esp_config.ate1);
}

char *esp_mode_cb(char *cmd, char *buffer)
{
    char *res = buffer;
    int8_t result = 0;

    esp_config.mode = -EFAIL;

    res = esp_inspect_ok_error(cmd, buffer, &result);
    if (result > 0)
    {
        sscanf(cmd, "%*[^=]=%d", (int *)&esp_config.mode);
        LOGD(TAG, "mode=%d\n", esp_config.mode);
    }

    return res;
}

char *esp_dhcp_cb(char *cmd, char *buffer)
{
    char *res = buffer;
    int8_t result = 0;
    int mode = 0;

    esp_config.dhcp = -EFAIL;

    res = esp_inspect_ok_error(cmd, buffer, &result);
    if (result > 0)
    {
        sscanf(cmd, "%*[^=]=%d,%d", &mode, (int *)&esp_config.dhcp);
        LOGD(TAG, "mode=%d , dhcp=%d\n", mode, esp_config.dhcp);
        if (mode != esp_config.mode)
        {
            LOGW(TAG, "Set hdcp mode , is not the current mode->cur:%d ,get:%d\n", esp_config.mode, mode);
            esp_config.dhcp = -EFAIL;
        }
    }

    return res;
}

char *esp_autoconn_cb(char *cmd, char *buffer)
{
    char *res = buffer;
    int8_t result = 0;

    esp_config.autoconn = -EFAIL;

    res = esp_inspect_ok_error(cmd, buffer, &result);
    if (result > 0)
    {
        sscanf(cmd, "%*[^=]=%d", (int *)&esp_config.autoconn);
        LOGD(TAG, "autoconn=%d\n", esp_config.autoconn);
    }

    return res;
}
#endif
char send_recv_bytes[20];
static esp_atcmd_t atcmd[] =
    {
        {"Ai-Thinker", ESP_CMD_NULL, esp_coltd_cb},
        {"ready", ESP_CMD_READY, esp_ready_cb},
        {"ATE0", ESP_CMD_NULL, NULL},
        {"WIFI DISCONNECT", ESP_CMD_NULL, esp_wifi_disconn_cb},
        {"WIFI CONNECTED", ESP_CMD_NULL, esp_wifi_conn_cb},
        {"WIFI GOT IP", ESP_CMD_NULL, esp_gotip_cb},
        {"OK", ESP_CMD_OK, esp_at_ok},
        {"ERROR", ESP_CMD_ERROR, esp_at_error},
        {"+CWJAP:", ESP_CMD_FAIL, esp_at_cwjap},
        {"+CIPSTA", ESP_CMD_NULL, esp_cipsta_cb},
#if (ESP_CONN_MUX == 1)
        {"0", ESP_CMD_NULL, esp_conn_status_cb},
        {"1", ESP_CMD_NULL, esp_conn_status_cb},
        {"2", ESP_CMD_NULL, esp_conn_status_cb},
        {"3", ESP_CMD_NULL, esp_conn_status_cb},
        {"4", ESP_CMD_NULL, esp_conn_status_cb},
#else
        {"CONNECT", ESP_CMD_NULL, esp_connect_cb},
        {"CLOSED", ESP_CMD_NULL, esp_close_cb},
#endif
        {"+IPD", ESP_CMD_NULL, esp_ipd_cb},
        {">", ESP_CMD_SEND_READY, NULL},
        {"SEND OK", ESP_CMD_SEND_OK, NULL},
        {"SEND FAIL", ESP_CMD_SEND_FAIL, NULL},
        {"link is not valid", ESP_CMD_LINK_NOVALID, NULL},
        {"ALREADY CONNECTED", ESP_CMD_NULL, NULL},
        {send_recv_bytes, ESP_CMD_NULL, NULL},
};

static uint8_t atcmd_len = (sizeof(atcmd) / sizeof(atcmd[0]));

void esp_send_events(int event)
{
#if (ESP_USE_RTOS == 0)
    esp_set_bits(esp_config.events, event);
#else
    xEventGroupSetBits(esp_events, ESP_EVENT_BIT(event));
#endif
}

char *esp_find_cmd(char *cmd, char *buffer)
{
    char i;
    char *str = buffer;

    for (i = 0; i < atcmd_len; i++)
    {
        if (strncmp(cmd, atcmd[i].name, strlen(atcmd[i].name)) == 0)
        {
            if (atcmd[i].cb != NULL)
            {
                str = atcmd[i].cb(cmd, buffer);
            }
            if (atcmd[i].cmd != 0)
            {
                esp_send_events(atcmd[i].cmd);
            }
            return (str);
        }
    }

    LOGE(TAG, "There is no handler for this command->%s\n", cmd);
    return buffer;
}

int esp_atcmd_parser(char *buffer, int len)
{
    char *str = buffer;
    char cmd[64];
    int buf_size = len;

    while ((*str != '\0') && (len > 0))
    {
        if ((*str == '\r') || (*str == '\n') || (*str > 0x7F) || (*str < 0x2A) || (*str == ' '))
        {
            *str++;
            len--;
            continue;
        }
        memset(cmd, 0, sizeof(cmd));
        //printf("find cmd ->%s\n", str);
        if ((str = atcmd_parser(str, "%[^,'\n']", cmd)) != NULL)
        {
            LOGD(TAG, "get->%s\n", cmd);
            str = esp_find_cmd(cmd, str);
            len = buf_size - ((int)str - (int)buffer);
            LOGD(TAG, "len=%d , return str ->%s\n", len, str);
        }
        else
        {
            break;
        }
    }
    return 0;
}

void esp_reset(void)
{
    uint8_t val = 0;

    dev_write(rst_fd, &val, 1);

    osDelay(10);

    val = 1;
    dev_write(rst_fd, &val, 1);

    osDelay(10);
}

int8_t esp_event(esp_cmd_t cmd, int32_t status, int32_t val, char *buff)
{

    switch (cmd)
    {
    case ESP_CMD_READY:
    {
        LOGD(TAG, "get ready\n");
        stp_socket_status_events(SOCKET_READY, 0, 0, NULL);
        break;
    }
    case ESP_CMD_WIFI_CONN:
    {
        LOGD(TAG, "wifi connect=%d\n", status);
        esp_config.wifi_connect = status;
        if (status)
        {
            esp_send_events(ESP_CMD_WIFI_CONN);
        }
        break;
    }
    case ESP_CMD_WIFI_GOTIP:
    {
        esp_config.got_ip = status;
        esp_send_events(ESP_CMD_WIFI_GOTIP);
        if (esp_config.wifi_connect == 0)
        {
            //mybee lost wifi connect message
            esp_config.wifi_connect = 1;
            esp_send_events(ESP_CMD_WIFI_CONN);
        }
        stp_socket_status_events(SOCKET_GOTIP, status, 0, NULL);
        break;
    }
    case ESP_CMD_CONN_STATUS:
    {
        LOGI(TAG, "esp connect hasbeen change,%d->%d\n", status, val);
        stp_socket_status_events(SOCKET_CONNECT, status, val, NULL);
        break;
    }

    default:
        break;
    }

    return 0;
}

void esp_pack_argv(char *format, ...)

{
    char buff[64];
    va_list arg;
    int16_t ret = 0;
    memset(buff, 0, sizeof(buff));
    va_start(arg, format);
    ret = vsnprintf(buff, sizeof(buff), format, arg);
    va_end(arg);
    if (ret <= 0)
    {
        LOGE(TAG, "set %s err.\n", buff);
    }
    else
    {
        esp_write(buff, ret);
    }
}

esp_init_config_t esp_config_status_old = ESP_CONFIG_MAX;

static int8_t esp_config_init(void)
{
    if (esp_config_status_old != esp_config_status)
    {
        LOGW(TAG, "STATUS:%d\n", esp_config_status);
        esp_config_status_old = esp_config_status;
    }
    switch (esp_config_status)
    {
    case ESP_CONFIG_RESET:
    {
        long flags = 0;
        esp_config.status = SOCKET_STATUS_RESET;
        esp_reset();

        flags = dev_fcntl(fd, F_D_GETFL, 0);
        flags |= F_O_NONBLOCK;
        dev_fcntl(fd, F_D_SETFL, flags);

        esp_wait_timer = 0;

        esp_config_status = ESP_CONFIG_READY;
        esp_config.status = SOCKET_STATUS_INIT;

        stp_socket_status_events(SOCKET_INITIAL, 0, 0, NULL);

        break;
    }
    case ESP_CONFIG_READY:
    {
        esp_wait_arg(NULL, esp_config.ready, 10000, ESP_C0NFIG_CONNECTSTATUS, ESP_CONFIG_RESET, ESP_CMD_READY);
        break;
    }
    case ESP_C0NFIG_CONNECTSTATUS:
    {
        esp_wait_arg(NULL, esp_config.wifi_connect, 30000, ESP_CONFIG_GOTIP, ESP_CONFIG_ATE0, ESP_CMD_WIFI_CONN);
        break;
    }
    case ESP_CONFIG_GOTIP:
    {
        //got_ip
        esp_wait_arg(NULL, esp_config.got_ip, 30000, ESP_CONFIG_ATE0, ESP_CONFIG_ATE0, ESP_CMD_WIFI_GOTIP);
        break;
    }

    case ESP_CONFIG_ATE0:
    {
        //esp_wait_arg(ATE0_CMD, esp_config.atex, 3000, ESP_CONFIG_DONE, ESP_CONFIG_RESET, ESP_CMD_OK);
        esp_set_argv(ESP_CONFIG_MODE, ESP_CONFIG_RESET, 3000, "%s", "ATE0\r\n");
        if ((esp_config.got_ip) && (esp_config_status == ESP_CONFIG_MODE))
        {
            esp_config_status = ESP_CONFIG_MUX;
        }
        break;
    }
    case ESP_CONFIG_MODE:
    {
        if (esp_config.config.mode < ESP_MODE_DEFAULT)
        {
            esp_set_argv(ESP_CONFIG_HDCP, ESP_CONFIG_RESET, 3000, "AT+CWMODE_DEF=%d\r\n", esp_config.config.mode);
        }
        else
        {
            esp_config_status = ESP_CONFIG_HDCP;
        }
        break;
    }
    case ESP_CONFIG_HDCP:
    {
        if (esp_config.config.dhcp < ESP_DHCP_DEFAULT)
        {
            esp_set_argv(ESP_CONFIG_AUTO, ESP_CONFIG_RESET, 3000, "AT+CWDHCP_DEF=%d,%d\r\n", esp_config.config.mode, esp_config.config.dhcp);
        }
        else
        {
            esp_config_status = ESP_CONFIG_AUTO;
        }
        break;
    }
    case ESP_CONFIG_AUTO:
    {
        if (esp_config.config.autoconn < ESP_AUTOCONN_DEFAULT)
        {
            esp_set_argv(ESP_CONFIG_APCFG, ESP_CONFIG_RESET, 3000, "AT+CWAUTOCONN=%d\r\n", esp_config.config.autoconn);
        }
        else
        {
            esp_config_status = ESP_CONFIG_APCFG;
        }
        break;
    }

    case ESP_CONFIG_APCFG:
    {
        if (esp_config.config.sta.set)
        {
            //esp_set_argv(ESP_CONFIG_DONE, ESP_CONFIG_RESET, 3000, "AT+CWJAP_DEF=\"%s\",\"%s\"\r\n", esp_config.config.sta.ssid, esp_config.config.sta.password);
            EventBits_t bits;

            if (esp_wait_timer == 0)
            {
                esp_wait_timer = HAL_GetTick();
                xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_FAIL));
                esp_pack_argv("AT+CWJAP_DEF=\"%s\",\"%s\"\r\n", esp_config.config.sta.ssid, esp_config.config.sta.password);
            }
            if (HAL_GetTick() - esp_wait_timer > 30000)
            {
                esp_config_status = ESP_CONFIG_RESET;
                esp_wait_timer = 0;
            }

            bits = xEventGroupWaitBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_FAIL), pdTRUE, pdFALSE, 1);
            if ((bits & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
            {
                esp_config_status = ESP_CONFIG_MUX;
                esp_wait_timer = 0;
            }
            else if ((bits & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
            {
                esp_config_status = ESP_CONFIG_RESET;
                esp_wait_timer = 0;
            }
        }
        else
        {
            esp_config_status = ESP_CONFIG_MUX;
        }
        break;
    }

    case ESP_CONFIG_MUX:
    {
#if (ESP_CONN_MUX == 1)
        esp_set_argv(ESP_CONFIG_DONE, ESP_CONFIG_RESET, 3000, "AT+CIPMUX=1\r\n");
#else
        esp_config_status = ESP_CONFIG_DONE;
#endif
        break;
    }

    case ESP_CONFIG_DONE:
    {
        long flags = 0;

        flags = dev_fcntl(fd, F_D_GETFL, 0);
        flags &= ~F_O_NONBLOCK;
        dev_fcntl(fd, F_D_SETFL, flags);

        esp_config.status = SOCKET_STATUS_READY;
        esp_config.is_init = 1;
        esp_send_events(ESP_CMD_INIT);
        stp_socket_status_events(SOCKET_INIT_DONE, 0, 0, NULL);
        break;
    }
    default:
        break;
    }

    return 0;
}
//test data1:// = "\r\nready\r\n\r\nAT\r\nOK\r\n\r\nATE1\r\nOK\r\n\r\n\
AT+CWMODE_DEF=1\r\nERROR\r\n\r\nAT+CWDHCP_DEF=1,1\r\n\r\nERROR\r\n\r\nAT+CWAUTOCONN=1\r\nERROR\r\n";

static void esp_recv_parser(void)
{
    uint8_t *rxbuf = NULL;
    int len = 0;
    int rx_addr = 0;

    if ((len = dev_read(fd, (uint8_t *)&rx_addr, 2048)) > 0)
    {
        rxbuf = (uint8_t *)rx_addr;
        if (strstr((char *)rxbuf, "\r\n") != NULL)
        {
            LOGI(TAG, "get:%s\n", rxbuf);
            esp_atcmd_parser((char *)rxbuf, len);
        }
        dev_ioctl(fd, NULL, 0, IOCTL_FLAG_USER_RESET_FIFO);
    }
}

unsigned portBASE_TYPE esp_free_heap;
static void esp_task(void const *argv)
{

    configASSERT(((unsigned long)argv) == 0);

    fd = dev_open("serial2", 0);
    if (fd == NULL)
    {
        LOGE(TAG, "open serial1 fail ,delet task.\n");
        osThreadTerminate(esp_task_handle);
    }

    rst_fd = dev_open("GPIOB_2", 0);
    if (rst_fd == NULL)
    {
        LOGE(TAG, "open reset pin fail ,delet task.\n");
        osThreadTerminate(esp_task_handle);
    }

    if ((esp_events = xEventGroupCreate()) == NULL)
    {
        LOGE(TAG, "creat esp event fail.\n");
        osThreadTerminate(esp_task_handle);
    }

    esp_event_callback = esp_event;

    while (1)
    {
        if (esp_config.is_init == 0)
        {
            esp_config_init();
        }
        esp_recv_parser();
        //1084
        esp_free_heap = uxTaskGetStackHighWaterMark(esp_task_handle);
    }
}

int esp_init(void)
{
    osThreadDef(esp, esp_task, osPriorityRealtime, 0, configMINIMAL_STACK_SIZE * 20);
    esp_task_handle = osThreadCreate(osThread(esp), NULL);
    configASSERT(esp_task_handle);

    LOG_ADD(TAG, _LOG_DEBUG);

    return 0;
}

//modules_init(esp_init);

int esp_write(char *data, uint8_t len)
{
    LOGI(TAG, "SEND:%s\n", data);
    return (dev_write(fd, (uint8_t *)data, len));
}

int esp_dbg(char *data, uint8_t len)
{
    return (dev_write(fd, (uint8_t *)data, len));
}

void esp_wifi_reset(void)
{
    esp_config.is_init = 0;
    esp_config.isok = 0;
    esp_config.got_ip = 0;
    esp_config.wifi_connect = 0;
    esp_config.ready = 0;
    esp_config.status = SOCKET_STATUS_RESET;
    esp_config_status = ESP_CONFIG_RESET;
    esp_config.conn_status[0] = 0;
    esp_config.conn_status[1] = 0;
    esp_config.conn_status[2] = 0;
    esp_config.conn_status[3] = 0;
    esp_config.conn_status[4] = 0;
    stp_socket_status_events(SOCKET_CONNECT, 0, 0, NULL);
    stp_socket_status_events(SOCKET_CONNECT, 1, 0, NULL);
    stp_socket_status_events(SOCKET_CONNECT, 2, 0, NULL);
    stp_socket_status_events(SOCKET_CONNECT, 3, 0, NULL);
    stp_socket_status_events(SOCKET_CONNECT, 4, 0, NULL);
    esp_reset();
}
/*
*Example:
#define esp_atcmd_send_and_wait(buf, len, cmd, cnt, t)                \
    do                                                                \
    {                                                                 \
        esp_clr_bits(esp_config.events, cmd);                         \
        esp_write(buf, len);                                          \
        while ((esp_is_bits(esp_config.events, cmd) == 0) && (--cnt)) \
        {                                                             \
            osDelay(t);                                               \
        }                                                             \
        if (cnt <= 0)                                                 \
        {                                                             \
            return -ETIMEDOUT;                                         \
        }                                                             \
    } while (0)


int8_t esp_set_mode(esp_mode_t mode, uint8_t is_save)
{
    char cmd[64];
    int16_t len = 0;
    int16_t timecnt = 1000; //10sec timerout

    if ((len = esp_pack_cmd(cmd, sizeof(cmd), "AT+CWMODE_%s=%d\r\n", is_save ? "DEF" : "CUR", mode)) <= 0)
    {
        LOGE(TAG, "set mode pack err.\n");
        return -EPACK;
    }

    esp_atcmd_send_and_wait(cmd, len, ESP_CMD_CWMODE, timecnt, 10);

    LOGD(TAG, "esp mode->%d\n", esp_config.mode);
    return ((mode == esp_config.mode) ? EOK : -EFAIL);
}
*/
int16_t esp_pack_cmd(char *cmd, uint16_t max, char *format, ...)
{
    va_list arg;
    int16_t ret = 0;

    memset(cmd, 0, max);
    va_start(arg, format);
    ret = vsnprintf(cmd, max, format, arg);
    va_end(arg);

    return ret;
}

void esp_log_set_err(const char *f, int8_t err)
{
    switch (err)
    {
    case EFAIL:
    {
        LOGW(TAG, "%s->fail\n", f);
        break;
    }
    case ETIMEDOUT:
    {
        LOGW(TAG, "%s->timeout\n", f);
        break;
    }
    case EERROR:
    {
        LOGW(TAG, "%s->error\n", f);
        break;
    }
    default:
    {
        LOGW(TAG, "%s->%d\n", f, err);
        break;
    }
    }
}

#if (ESP_USE_RTOS)

int8_t esp_set_param(char *format, ...)
{
    char buff[64];
    va_list arg;
    int16_t ret = 0;

    memset(buff, 0, sizeof(buff));
    va_start(arg, format);
    ret = vsnprintf(buff, sizeof(buff), format, arg);
    va_end(arg);

    if (ret <= 0)
    {
        LOGE(TAG, "set mode pack err.\n");
        return -EPACK;
    }

    return esp_write(buff, ret);
}

int8_t esp_set_mode(esp_mode_t mode, uint8_t def)
{
    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR));
    if ((ret = esp_set_param("AT+CWMODE_%s=%d\r\n", def ? "DEF" : "CUR", mode)) < 0)
    {
        return ret;
    }

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR), 10000);
    LOGI(TAG, "bits=%d\n", bit);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        esp_config.config.mode = mode;
        return EOK;
    }
    else if ((bit & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
    {
        return -EFAIL;
    }

    return -ETIMEDOUT;
}

int8_t esp_set_dhcp(esp_dhcp_t dhcp, uint8_t def)
{
    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR));
    if ((ret = esp_set_param("AT+CWDHCP_%s=%d,%d\r\n", def ? "DEF" : "CUR", esp_config.config.mode, dhcp)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR), 10000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        esp_config.config.dhcp = dhcp;
        return EOK;
    }
    else if ((bit & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
    {
        return -EERROR;
    }

    return -ETIMEDOUT;
}

int8_t esp_set_autoconn(esp_autoconn_t autoconn)
{
    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR));
    if ((ret = esp_set_param("AT+CWAUTOCONN=%d\r\n", autoconn)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR), 10000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        esp_config.config.autoconn = autoconn;
        return EOK;
    }
    else if ((bit & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
    {
        return -EFAIL;
    }

    return -ETIMEDOUT;
}

int8_t esp_set_wifi_sta(char *ssid, char *passwd, uint8_t def)
{
    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_FAIL));
    if ((ret = esp_set_param("AT+CWJAP_%s=\"%s\",\"%s\"\r\n", (def ? "DEF" : "CUR"), ssid, passwd)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_FAIL), 30000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        return EOK;
    }
    else if ((bit & ESP_EVENT_BIT(ESP_CMD_FAIL)) != 0)
    {
        return -EFAIL;
    }

    return -ETIMEDOUT;
}

int8_t esp_get_staip(esp_wifi_sta_config_t *sta_cfg)
{
    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK));
    if ((ret = esp_set_param("AT+CIPSTA_CUR?\r\n")) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK), 30000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        memcpy(sta_cfg, &esp_config.config.sta, sizeof(esp_wifi_sta_config_t));
        return EOK;
    }

    return -ETIMEDOUT;
}

int8_t esp_wifi_connect(uint8_t id, socket_net_type_t type, char *ip, uint16_t port)
{

    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR));
#if (ESP_CONN_MUX == 1)
    if ((ret = esp_set_param("AT+CIPSTART=%d,\"%s\",\"%s\",%d\r\n", id, esp_net_type[type], ip, port)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }
#else
    if ((ret = esp_set_param("AT+CIPSTART=\"%s\",\"%s\",%d\r\n", esp_net_type[type], ip, port)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }
#endif

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR), 30000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        return EOK;
    }
    else if ((bit & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
    {
        return -EFAIL;
    }

    return -ETIMEDOUT;
}

int8_t eps_wifi_send(int8_t id, uint8_t *data, uint16_t len)
{
    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR) | ESP_EVENT_BIT(ESP_CMD_SEND_READY) | ESP_EVENT_BIT(ESP_CMD_LINK_NOVALID));
#if (ESP_CONN_MUX == 1)
    if ((ret = esp_set_param("AT+CIPSEND=%d,%d\r\n", id, len)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }
#else
    if ((ret = esp_set_param("AT+CIPSEND=%d\r\n", len)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }
#endif
    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR) | ESP_EVENT_BIT(ESP_CMD_SEND_READY) | ESP_EVENT_BIT(ESP_CMD_LINK_NOVALID), 30000);

    if ((bit & ESP_EVENT_BIT(ESP_CMD_LINK_NOVALID)) != 0)
    {
        LOGW(TAG, "connect not valid.\n");
        return -ECONN;
    }
    if ((bit & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
    {
        return -EFAIL;
    }

    if ((bit & ESP_EVENT_BIT(ESP_CMD_SEND_READY)) == 0)
    {
        bit |= esp_read_events(ESP_EVENT_BIT(ESP_CMD_SEND_READY), 30000);
    }

    if (((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0) && ((bit & ESP_EVENT_BIT(ESP_CMD_SEND_READY)) != 0))
    {
        EventBits_t tmpbit;
        xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_SEND_OK) | ESP_EVENT_BIT(ESP_CMD_SEND_FAIL));
        memset(send_recv_bytes, 0, sizeof(send_recv_bytes));
        sprintf(send_recv_bytes, "Recv %d bytes", len);
        esp_write((char *)data, len);
        tmpbit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_SEND_OK) | ESP_EVENT_BIT(ESP_CMD_SEND_FAIL), 30000);
        if ((tmpbit & ESP_EVENT_BIT(ESP_CMD_SEND_OK)) != 0)
        {
            return EOK;
        }
        else if ((tmpbit & ESP_EVENT_BIT(ESP_CMD_SEND_FAIL)) != 0)
        {
            return -EFAIL;
        }

        return -ETIMEDOUT;
    }

    return -ETIMEDOUT;
}

int8_t eps_wifi_disconnect(int8_t id)
{

    EventBits_t bit;
    int8_t ret = 0;

    xEventGroupClearBits(esp_events, ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR));
#if (ESP_CONN_MUX == 1)
    if ((ret = esp_set_param("AT+CIPCLOSE=%d\r\n", id)) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }
#else
    if ((ret = esp_set_param("AT+CIPCLOSE\r\n")) < 0)
    {
        esp_log_set_err(__func__, ret);
        return ret;
    }
#endif

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_OK) | ESP_EVENT_BIT(ESP_CMD_ERROR), 10000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_OK)) != 0)
    {
        return EOK;
    }
    else if ((bit & ESP_EVENT_BIT(ESP_CMD_ERROR)) != 0)
    {
        return -EFAIL;
    }

    return -ETIMEDOUT;
}

int8_t esp_set_wifi_config(esp_wifi_config_t *config)
{
    config->sta.set = true;
    memcpy(&esp_config.config.sta, &config->sta, sizeof(esp_wifi_sta_config_t));

    return EOK;
}

void esp_wifi_init(esp_wifi_config_t *config)
{
    memcpy(&esp_config.config, config, sizeof(esp_wifi_config_t));
    esp_init();
}

int8_t esp_wifi_start(void)
{
    EventBits_t bit;

    bit = esp_read_events(ESP_EVENT_BIT(ESP_CMD_INIT), 600000);
    if ((bit & ESP_EVENT_BIT(ESP_CMD_INIT)) != 0)
    {
        return (esp_config.got_ip);
    }
    return -EFAIL;
}

//如果是rtos ,返回使用osDelay , send不用做一次發送 ,
//如果不是ROTS , 需要判斷一次性發送, delay不能用死等 ,

#else
int8_t esp_set_mode(esp_mode_t mode, uint8_t def)
{
    if (esp_wait_timer == 0)
    {
        char *cmd = malloc(100);
        int16_t len = 0;

        esp_clr_bits(esp_config.events, ESP_CMD_MODE);

        if ((len = esp_pack_cmd(cmd, 100, "AT+CWMODE_%s=%d\r\n", def ? "DEF" : "CUR", mode)))
        {
            esp_write(cmd, len);
        }
        else
        {
            LOGE(TAG, "set mode pack err.\n");
        }
    }
    if (HAL_GetTick() - esp_wait_timer > 10000)
    {
        return -ETIMEDOUT;
    }

    if (esp_is_bits(esp_config.events, ESP_CMD_MODE))
    {
        esp_clr_bits(esp_config.events, ESP_CMD_MODE);
        return ((mode == esp_config.mode) ? (OPER_OK) : (-EFAIL));
    }

    return OPER_NO;
}
#endif


static int8_t wifi_error(const char *f, int8_t id, int8_t err)
{
    switch (err)
    {
    case -ECONN:
    {
        stp_socket_status_events(SOCKET_CONNECT, id, 0, NULL);
        break;
    }
    case -ETIMEDOUT:
    {
        esp_wifi_reset();
        break;
    }
    default:
        break;
    }

    return err;
}

static int wifi_connect(uint8_t id, socket_net_type_t type, char *ip, uint16_t port)
{
    return wifi_error(__func__, id, esp_wifi_connect(id, type, ip, port));
}

static int wifi_send(int8_t id, uint8_t *data, uint16_t len)
{
    return wifi_error(__func__, id, eps_wifi_send(id, data, len));
}

static int wifi_disconnect(int8_t id)
{
    return wifi_error(__func__, id, eps_wifi_disconnect(id));
}

//
//
//
//
//
//
//
//
//
//
static void esp_dev_to_flags(struct miscdevice *dev)
{
    if (dev->flags & F_O_NONBLOCK)
    {
        //ser_read_mode = 10;
    }
    else
    {
        //ser_read_mode = WAIT_FOR_EVER;
    }
}

static int esp_dev_open(FIL_HAND *fd, long flags)
{
    esp_wifi_config_t cfg = ESP_WIFI_DEFAULT();
    struct miscdevice *dev = (struct miscdevice *)fd;
    //save flags
    dev->flags = flags;
    esp_dev_to_flags(dev);

    //init esp
    esp_wifi_init(&cfg);

    return 0;
}

static int esp_dev_write(FIL_HAND *fd, const void *buf, uint32_t cmd)
{

    switch (cmd)
    {
    case SOCKET_W_CONNECT:
    {
        stp_socket_config_t *pcn = (stp_socket_config_t *)buf;

        return wifi_connect(pcn->id, pcn->type, pcn->ip, pcn->port);
        break;
    }
    case SOCKET_S_DATA:
    {
        stp_socket_data_t *psd = (stp_socket_data_t *)buf;

        return wifi_send(psd->id, psd->data, psd->len);
    }
    default:
        break;
    }

    return EOK;
}

static int esp_dev_read(FIL_HAND *fd, void *data, uint32_t count)
{

    return 0;
}

static int esp_dev_resume(FIL_HAND *fd)
{

    return 0;
}

static int esp_dev_suspend(FIL_HAND *fd)
{

    return 0;
}

static long esp_dev_fcntl(FIL_HAND *fd, int cmd, long argv)
{
    struct miscdevice *dev = (struct miscdevice *)fd;

    if (dev == NULL)
    {
        return -EIO;
    }

    switch (cmd)
    {
    case F_D_GETFL:
    {
        return dev->flags;
        break;
    }
    case F_D_SETFL:
    {
        dev->flags = argv;
        esp_dev_to_flags(dev);
        break;
    }
    case F_S_GETFL:
    {
        return esp_config.status;
        break;
    }
    default:
        break;
    }
    return 0;
}

static int esp_dev_ioctl(FIL_HAND *fd, void *buf, uint32_t count, uint32_t flag)
{
    if (flag & IOCTL_FLAG_RESUME)
    {
        esp_dev_resume(fd);
    }
    if (flag & IOCTL_FLAG_SUSPEND)
    {
        esp_dev_suspend(fd);
    }
    if (flag & IOCTL_FLAG_DISCONNECT)
    {
        wifi_disconnect(count);
    }
    if (flag & IOCTL_FLAG_RESERT)
    {
        esp_wifi_reset();
    }

    return 0;
}

static struct file_operations esp_fops =
    {
        .onwer = 0,
        .open = esp_dev_open,
        .write = esp_dev_write,
        .read = esp_dev_read,
        .ioctl = esp_dev_ioctl,
        .fcntl = esp_dev_fcntl,
        .resume = esp_dev_resume,
        .suspend = esp_dev_suspend,
};

static struct miscdevice esp_dev =
    {
        .minor = MISC_DYNAMIC_MINOR,
        .name = MODULE_NAME,
        .fops = &esp_fops,
        .nodename = "module",
};

static int esp_device_init(void)
{
    return (misc_register(&esp_dev));
}

modules_init(esp_device_init);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章