feat(smartconfig): refactor smartconfig callback to use esp event

Consistent with esp-idf(branch: release/v4.2, commit id: c5bb6c4)
This commit is contained in:
chenwen
2020-10-20 16:57:54 +08:00
parent dda5062c80
commit d3a974f6f2
13 changed files with 339 additions and 296 deletions

View File

@ -32,6 +32,8 @@ else()
"source/crc.c"
"source/phy_init.c"
"source/reset_reason.c"
"source/smartconfig.c"
"source/smartconfig_ack.c"
"source/startup.c"
"source/system_api.c"
"source/task_wdt.c"

View File

@ -18,6 +18,7 @@
#include "esp_wifi_types.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_smartconfig.h"
#ifdef __cplusplus
extern "C" {
@ -81,7 +82,7 @@ typedef enum {
* - ESP_ERR_NO_MEM: out of memory
* - others: refer to error code esp_err.h
*/
esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config);
esp_err_t esp_wifi_init_internal(const wifi_init_config_t* config);
/**
* @brief Deinitialize Wi-Fi Driver
@ -124,7 +125,7 @@ int8_t esp_wifi_get_ap_rssi(void);
* @param len length of received probe request.
* @param rssi rssi of received probe request.
*/
typedef void (*wifi_sta_rx_probe_req_t)(const uint8_t *frame, int len, int rssi);
typedef void (*wifi_sta_rx_probe_req_t)(const uint8_t* frame, int len, int rssi);
/**
* @brief Register the RX callback function when receive probe request.
@ -159,14 +160,14 @@ void esp_wifi_internal_free_rx_buffer(void* buffer);
* - ERR_IF : WiFi driver error
* - ERR_ARG : Invalid argument
*/
int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len);
int esp_wifi_internal_tx(wifi_interface_t wifi_if, void* buffer, uint16_t len);
/**
* @brief The WiFi RX callback function
*
* Each time the WiFi need to forward the packets to high layer, the callback function will be called
*/
typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb);
typedef esp_err_t (*wifi_rxcb_t)(void* buffer, uint16_t len, void* eb);
/**
* @brief Set the WiFi RX callback
@ -215,21 +216,49 @@ esp_err_t esp_wifi_internal_set_log_mod(uint32_t submodule);
* @return
* - ESP_OK: succeed
*/
esp_err_t esp_wifi_internal_get_log(wifi_log_level_t *log_level, uint32_t *log_mod);
esp_err_t esp_wifi_internal_get_log(wifi_log_level_t* log_level, uint32_t* log_mod);
/**
* @brief get wifi power management config.
*
* @param ps_config power management config
*/
void esp_wifi_set_pm_config(esp_pm_config_t *pm_config);
void esp_wifi_set_pm_config(esp_pm_config_t* pm_config);
/**
* @brief set wifi power management config.
*
* @param ps_config power management config
*/
void esp_wifi_get_pm_config(esp_pm_config_t *pm_config);
void esp_wifi_get_pm_config(esp_pm_config_t* pm_config);
/**
* @brief Start SmartConfig, config ESP device to connect AP. You need to broadcast information by phone APP.
* Device sniffer special packets from the air that containing SSID and password of target AP.
*
* @attention 1. This API can be called in station or softAP-station mode.
* @attention 2. Can not call esp_smartconfig_start twice before it finish, please call
* esp_smartconfig_stop first.
*
* @param config pointer to smartconfig start configure structure
*
* @return
* - ESP_OK: succeed
* - others: fail
*/
esp_err_t esp_smartconfig_internal_start(const smartconfig_start_config_t* config);
/**
* @brief Stop SmartConfig, free the buffer taken by esp_smartconfig_start.
*
* @attention Whether connect to AP succeed or not, this API should be called to free
* memory taken by smartconfig_start.
*
* @return
* - ESP_OK: succeed
* - others: fail
*/
esp_err_t esp_smartconfig_internal_stop(void);
#ifdef __cplusplus
}

View File

@ -18,37 +18,48 @@
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_event_base.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
SC_STATUS_WAIT = 0, /**< Waiting to start connect */
SC_STATUS_FIND_CHANNEL, /**< Finding target channel */
SC_STATUS_GETTING_SSID_PSWD, /**< Getting SSID and password of target AP */
SC_STATUS_LINK, /**< Connecting to target AP */
SC_STATUS_LINK_OVER, /**< Connected to AP successfully */
} smartconfig_status_t;
typedef enum {
SC_TYPE_ESPTOUCH = 0, /**< protocol: ESPTouch */
SC_TYPE_AIRKISS, /**< protocol: AirKiss */
SC_TYPE_ESPTOUCH_AIRKISS, /**< protocol: ESPTouch and AirKiss */
} smartconfig_type_t;
/**
* @brief The callback of SmartConfig, executed when smart-config status changed.
*
* @param status Status of SmartConfig:
* - SC_STATUS_GETTING_SSID_PSWD : pdata is a pointer of smartconfig_type_t, means config type.
* - SC_STATUS_LINK : pdata is a pointer of struct station_config.
* - SC_STATUS_LINK_OVER : pdata is a pointer of phone's IP address(4 bytes) if pdata unequal NULL.
* - otherwise : parameter void *pdata is NULL.
* @param pdata According to the different status have different values.
*
*/
typedef void (*sc_callback_t)(smartconfig_status_t status, void *pdata);
/** Smartconfig event declarations */
typedef enum {
SC_EVENT_SCAN_DONE, /*!< ESP32 station smartconfig has finished to scan for APs */
SC_EVENT_FOUND_CHANNEL, /*!< ESP32 station smartconfig has found the channel of the target AP */
SC_EVENT_GOT_SSID_PSWD, /*!< ESP32 station smartconfig got the SSID and password */
SC_EVENT_SEND_ACK_DONE, /*!< ESP32 station smartconfig has sent ACK to cellphone */
} smartconfig_event_t;
/** @brief smartconfig event base declaration */
ESP_EVENT_DECLARE_BASE(SC_EVENT);
/** Argument structure for SC_EVENT_GOT_SSID_PSWD event */
typedef struct {
uint8_t ssid[32]; /**< SSID of the AP. Null terminated string. */
uint8_t password[64]; /**< Password of the AP. Null terminated string. */
bool bssid_set; /**< whether set MAC address of target AP or not. */
uint8_t bssid[6]; /**< MAC address of target AP. */
smartconfig_type_t type; /**< Type of smartconfig(ESPTouch or AirKiss). */
uint8_t token; /**< Token from cellphone which is used to send ACK to cellphone. */
uint8_t cellphone_ip[4]; /**< IP address of cellphone. */
} smartconfig_event_got_ssid_pswd_t;
/** Configure structure for esp_smartconfig_start */
typedef struct {
bool enable_log; /**< Enable smartconfig logs. */
} smartconfig_start_config_t;
#define SMARTCONFIG_START_CONFIG_DEFAULT() { \
.enable_log = false \
};
/**
* @brief Get the version of SmartConfig.
@ -56,24 +67,23 @@ typedef void (*sc_callback_t)(smartconfig_status_t status, void *pdata);
* @return
* - SmartConfig version const char.
*/
const char *esp_smartconfig_get_version(void);
const char* esp_smartconfig_get_version(void);
/**
* @brief Start SmartConfig, config ESP device to connect AP. You need to broadcast information by phone APP.
* Device sniffer special packets from the air that containing SSID and password of target AP.
*
* @attention 1. This API can be called in station or softAP-station mode.
* @attention 1. This API can be called in station mode.
* @attention 2. Can not call esp_smartconfig_start twice before it finish, please call
* esp_smartconfig_stop first.
*
* @param cb SmartConfig callback function.
* @param ... log 1: UART output logs; 0: UART only outputs the result.
* @param config pointer to smartconfig start configure structure
*
* @return
* - ESP_OK: succeed
* - others: fail
*/
esp_err_t esp_smartconfig_start(sc_callback_t cb, ...);
esp_err_t esp_smartconfig_start(const smartconfig_start_config_t* config);
/**
* @brief Stop SmartConfig, free the buffer taken by esp_smartconfig_start.

View File

@ -0,0 +1,44 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SMARTCONFIG_ACK_H
#define SMARTCONFIG_ACK_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Send smartconfig ACK to cellphone.
*
* @attention The API can only be used when receiving SC_EVENT_GOT_SSID_PSWD event.
*
* @param type: smartconfig type(ESPTouch or AirKiss);
* token: token from the cellphone;
* cellphone_ip: IP address of the cellphone;
*
* @retuen ESP_OK: succeed
* others: fail
*/
esp_err_t sc_send_ack_start(smartconfig_type_t type, uint8_t token, uint8_t* cellphone_ip);
/**
* @brief Stop sending smartconfig ACK to cellphone.
*/
void sc_send_ack_stop(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -4,5 +4,5 @@ gwen:
pp: 4a1ab49
espnow: a4246a0
smartconfig: 2.8.2
smartconfig: 2.9.0
phy: 1163.0

View File

@ -0,0 +1,83 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <string.h>
#include "esp_log.h"
#include "esp_event_base.h"
#include "esp_private/wifi.h"
#include "esp_smartconfig.h"
#include "smartconfig_ack.h"
/* Smartconfig events definitions */
ESP_EVENT_DEFINE_BASE(SC_EVENT);
static const char* TAG = "smartconfig";
static void handler_got_ssid_passwd(void* arg, esp_event_base_t base, int32_t event_id, void* data)
{
smartconfig_event_got_ssid_pswd_t* evt = (smartconfig_event_got_ssid_pswd_t*)data;
uint8_t ssid[33] = { 0 };
uint8_t password[65] = { 0 };
uint8_t cellphone_ip[4];
esp_err_t err = ESP_OK;
memcpy(ssid, evt->ssid, sizeof(evt->ssid));
memcpy(password, evt->password, sizeof(evt->password));
memcpy(cellphone_ip, evt->cellphone_ip, sizeof(evt->cellphone_ip));
ESP_LOGD(TAG, "SSID:%s", ssid);
ESP_LOGD(TAG, "PASSWORD:%s", password);
ESP_LOGD(TAG, "Phone ip: %d.%d.%d.%d\n", cellphone_ip[0], cellphone_ip[1], cellphone_ip[2], cellphone_ip[3]);
err = sc_send_ack_start(evt->type, evt->token, evt->cellphone_ip);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Send smartconfig ACK error: %d", err);
}
}
esp_err_t esp_smartconfig_start(const smartconfig_start_config_t* config)
{
esp_err_t err = ESP_OK;
err = esp_event_handler_register(SC_EVENT, SC_EVENT_GOT_SSID_PSWD, handler_got_ssid_passwd, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Register smartconfig default event handler fail!");
return err;
}
err = esp_smartconfig_internal_start(config);
if (err != ESP_OK) {
esp_event_handler_unregister(SC_EVENT, SC_EVENT_GOT_SSID_PSWD, handler_got_ssid_passwd);
}
return err;
}
esp_err_t esp_smartconfig_stop(void)
{
esp_err_t err = ESP_OK;
err = esp_smartconfig_internal_stop();
if (err == ESP_OK) {
sc_send_ack_stop();
esp_event_handler_unregister(SC_EVENT, SC_EVENT_GOT_SSID_PSWD, handler_got_ssid_passwd);
}
return err;
}

View File

@ -32,12 +32,35 @@
#include "esp_smartconfig.h"
#include "smartconfig_ack.h"
static const char *TAG = "smartconfig";
#define SC_ACK_TASK_PRIORITY 2 /*!< Priority of sending smartconfig ACK task */
#define SC_ACK_TASK_STACK_SIZE 2048 /*!< Stack size of sending smartconfig ACK task */
#define SC_ACK_TOUCH_SERVER_PORT 18266 /*!< ESP touch UDP port of server on cellphone */
#define SC_ACK_AIRKISS_SERVER_PORT 10000 /*!< Airkiss UDP port of server on cellphone */
#define SC_ACK_AIRKISS_DEVICE_PORT 10001 /*!< Airkiss UDP port of server on device */
#define SC_ACK_AIRKISS_TIMEOUT 1500 /*!< Airkiss read data timout millisecond */
#define SC_ACK_TOUCH_LEN 11 /*!< Length of ESP touch ACK context */
#define SC_ACK_AIRKISS_LEN 7 /*!< Length of Airkiss ACK context */
#define SC_ACK_MAX_COUNT 60 /*!< Maximum count of sending smartconfig ACK */
/**
* @brief Smartconfig parameters passed to sc_ack_send call.
*/
typedef struct sc_ack {
smartconfig_type_t type; /*!< Smartconfig type(ESPTouch or AirKiss) */
struct {
uint8_t token; /*!< Smartconfig token from the cellphone */
uint8_t mac[6]; /*!< MAC address of station */
uint8_t ip[4]; /*!< IP address of cellphone */
} ctx;
} sc_ack_t;
static const char* TAG = "smartconfig";
/* Flag to indicate sending smartconfig ACK or not. */
static bool s_sc_ack_send = false;
static void *s_sc_ack_info = NULL;
static size_t s_sc_ack_info_size = 0;
static int sc_ack_send_get_errno(int fd)
{
@ -49,32 +72,26 @@ static int sc_ack_send_get_errno(int fd)
return sock_errno;
}
static void sc_ack_send_task(void *pvParameters)
static void sc_ack_send_task(void* pvParameters)
{
sc_ack_t *ack = (sc_ack_t *)pvParameters;
sc_ack_t* ack = (sc_ack_t*)pvParameters;
tcpip_adapter_ip_info_t local_ip;
sc_callback_data_t sc_callback_data;
uint8_t remote_ip[4];
memset(&sc_callback_data, 0x0, sizeof(sc_callback_data_t));
if (ack->type == SC_ACK_TYPE_ESPTOUCH) {
memcpy(sc_callback_data.ip, ack->ctx.ip, sizeof(sc_callback_data.ip));
}
memcpy(remote_ip, ack->ctx.ip, sizeof(remote_ip));
sc_callback_data.type = ack->type;
int remote_port = (ack->type == SC_ACK_TYPE_ESPTOUCH) ? SC_ACK_TOUCH_SERVER_PORT : SC_ACK_AIRKISS_SERVER_PORT;
memset(remote_ip, 0xFF, sizeof(remote_ip));
int remote_port = (ack->type == SC_TYPE_ESPTOUCH) ? SC_ACK_TOUCH_SERVER_PORT : SC_ACK_AIRKISS_SERVER_PORT;
struct sockaddr_in server_addr;
socklen_t sin_size = sizeof(server_addr);
int send_sock = -1;
int optval = 1;
int sendlen;
int ack_len = (ack->type == SC_ACK_TYPE_ESPTOUCH) ? SC_ACK_TOUCH_LEN : SC_ACK_AIRKISS_LEN;
int ack_len = (ack->type == SC_TYPE_ESPTOUCH) ? SC_ACK_TOUCH_LEN : SC_ACK_AIRKISS_LEN;
uint8_t packet_count = 1;
int err;
int ret;
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr((const char*)remote_ip);
memcpy(&server_addr.sin_addr.s_addr, remote_ip, sizeof(remote_ip));
server_addr.sin_port = htons(remote_port);
esp_wifi_get_mac(WIFI_IF_STA, ack->ctx.mac);
@ -84,14 +101,16 @@ static void sc_ack_send_task(void *pvParameters)
while (s_sc_ack_send) {
/* Get local IP address of station */
ret = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &local_ip);
if ((ESP_OK == ret) && (local_ip.ip.addr != INADDR_ANY)) {
/* If ESP touch, smartconfig ACK contains local IP address. */
if (ack->type == SC_ACK_TYPE_ESPTOUCH) {
if (ack->type == SC_TYPE_ESPTOUCH) {
memcpy(ack->ctx.ip, &local_ip.ip.addr, 4);
}
/* Create UDP socket. */
send_sock = socket(AF_INET, SOCK_DGRAM, 0);
if ((send_sock < LWIP_SOCKET_OFFSET) || (send_sock > (FD_SETSIZE - 1))) {
ESP_LOGE(TAG, "Creat udp socket failed");
goto _end;
@ -99,7 +118,7 @@ static void sc_ack_send_task(void *pvParameters)
setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &optval, sizeof(int));
if (ack->type == SC_ACK_TYPE_AIRKISS) {
if (ack->type == SC_TYPE_AIRKISS) {
char data = 0;
struct sockaddr_in local_addr, from;
socklen_t sockadd_len = sizeof(struct sockaddr);
@ -114,18 +133,15 @@ static void sc_ack_send_task(void *pvParameters)
local_addr.sin_addr.s_addr = INADDR_ANY;
local_addr.sin_port = htons(SC_ACK_AIRKISS_DEVICE_PORT);
bind(send_sock, (struct sockaddr *)&local_addr, sockadd_len);
bind(send_sock, (struct sockaddr*)&local_addr, sockadd_len);
setsockopt(send_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
recvfrom(send_sock, &data, 1, 0, (struct sockaddr *)&from, &sockadd_len);
recvfrom(send_sock, &data, 1, 0, (struct sockaddr*)&from, &sockadd_len);
if (from.sin_addr.s_addr != INADDR_ANY) {
memcpy(remote_ip, &from.sin_addr, 4);
memcpy(sc_callback_data.ip, &from.sin_addr, sizeof(sc_callback_data.ip));
server_addr.sin_addr.s_addr = from.sin_addr.s_addr;
} else {
if (ack->cb) {
ack->cb(SC_STATUS_LINK_OVER, &sc_callback_data);
}
goto _end;
}
}
@ -133,95 +149,73 @@ static void sc_ack_send_task(void *pvParameters)
while (s_sc_ack_send) {
/* Send smartconfig ACK every 100ms. */
vTaskDelay(100 / portTICK_RATE_MS);
if (s_sc_ack_info) {
sendlen = sendto(send_sock, s_sc_ack_info, s_sc_ack_info_size, 0, (struct sockaddr*) &server_addr, sin_size);
} else {
sendlen = sendto(send_sock, &ack->ctx, ack_len, 0, (struct sockaddr*) &server_addr, sin_size);
}
sendlen = sendto(send_sock, &ack->ctx, ack_len, 0, (struct sockaddr*) &server_addr, sin_size);
if (sendlen > 0) {
/* Totally send 30 smartconfig ACKs. Then smartconfig is successful. */
if (packet_count++ >= SC_ACK_MAX_COUNT) {
if (ack->link_flag) {
*ack->link_flag = 1;
}
if (ack->cb) {
ack->cb(SC_STATUS_LINK_OVER, &sc_callback_data);
}
esp_event_post(SC_EVENT, SC_EVENT_SEND_ACK_DONE, NULL, 0, portMAX_DELAY);
goto _end;
}
}
else {
} else {
err = sc_ack_send_get_errno(send_sock);
if (err == ENOMEM || err == EAGAIN) {
ESP_LOGD(TAG, "send failed, errno %d", err);
continue;
}
ESP_LOGE(TAG, "send failed, errno %d", err);
goto _end;
}
}
}
else {
vTaskDelay((portTickType)(100 / portTICK_RATE_MS));
} else {
vTaskDelay((portTickType)(200 / portTICK_RATE_MS));
}
}
_end:
if ((send_sock >= LWIP_SOCKET_OFFSET) && (send_sock <= (FD_SETSIZE - 1))) {
close(send_sock);
}
if (s_sc_ack_info) {
free(s_sc_ack_info);
s_sc_ack_info = NULL;
s_sc_ack_info_size = 0;
}
free(ack);
vTaskDelete(NULL);
}
void sc_ack_send(sc_ack_t *param)
esp_err_t sc_send_ack_start(smartconfig_type_t type, uint8_t token, uint8_t* cellphone_ip)
{
sc_ack_t *ack = NULL;
sc_ack_t* ack = NULL;
if (param == NULL) {
ESP_LOGE(TAG, "Smart config ack parameter error");
return;
if (cellphone_ip == NULL) {
ESP_LOGE(TAG, "Cellphone IP address is NULL");
return ESP_ERR_INVALID_ARG;
}
ack = malloc(sizeof(sc_ack_t));
if (ack == NULL) {
ESP_LOGE(TAG, "Smart config ack parameter malloc fail");
return;
ESP_LOGE(TAG, "ACK parameter malloc fail");
return ESP_ERR_NO_MEM;
}
memcpy(ack, param, sizeof(sc_ack_t));
ack->type = type;
ack->ctx.token = token;
memcpy(ack->ctx.ip, cellphone_ip, 4);
s_sc_ack_send = true;
if (xTaskCreate(sc_ack_send_task, "sc_ack_send_task", SC_ACK_TASK_STACK_SIZE, ack, SC_ACK_TASK_PRIORITY, NULL) != pdPASS) {
ESP_LOGE(TAG, "Create sending smartconfig ACK task fail");
free(ack);
return ESP_ERR_NO_MEM;
}
return ESP_OK;
}
void sc_ack_send_stop(void)
void sc_send_ack_stop(void)
{
s_sc_ack_send = false;
}
bool sc_ack_send_info(void *buffer, size_t size)
{
if (!buffer || !size)
return false;
s_sc_ack_info = s_sc_ack_info ? realloc(s_sc_ack_info, size + 1) : malloc(size + 1);
if (!s_sc_ack_info)
return false;
s_sc_ack_info_size = size;
memset(s_sc_ack_info, 0, size + 1);
memcpy(s_sc_ack_info, buffer, size);
return true;
}

View File

@ -1,6 +0,0 @@
set(COMPONENT_SRCDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_PRIV_REQUIRES lwip tcpip_adapter)
register_component()

View File

@ -1,2 +0,0 @@
#
# Component Makefile

View File

@ -1,94 +0,0 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SMARTCONFIG_ACK_H
#define SMARTCONFIG_ACK_H
#ifdef __cplusplus
extern "C" {
#endif
#define SC_ACK_TASK_PRIORITY 2 /*!< Priority of sending smartconfig ACK task */
#define SC_ACK_TASK_STACK_SIZE 2048 /*!< Stack size of sending smartconfig ACK task */
#define SC_ACK_TOUCH_SERVER_PORT 18266 /*!< ESP touch UDP port of server on cellphone */
#define SC_ACK_AIRKISS_SERVER_PORT 10000 /*!< Airkiss UDP port of server on cellphone */
#define SC_ACK_AIRKISS_DEVICE_PORT 10001 /*!< Airkiss UDP port of server on device */
#define SC_ACK_AIRKISS_TIMEOUT 1500 /*!< Airkiss read data timeout millisecond */
#define SC_ACK_TOUCH_LEN 11 /*!< Length of ESP touch ACK context */
#define SC_ACK_AIRKISS_LEN 7 /*!< Length of Airkiss ACK context */
#define SC_ACK_MAX_COUNT 30 /*!< Maximum count of sending smartconfig ACK */
/**
* @brief Smartconfig ACK type.
*/
typedef enum {
SC_ACK_TYPE_ESPTOUCH = 0, /*!< ESP touch ACK type */
SC_ACK_TYPE_AIRKISS, /*!< Airkiss ACK type */
} sc_ack_type_t;
/**
* @brief Smartconfig parameters passed to sc_ack_send call.
*/
typedef struct sc_ack {
sc_ack_type_t type; /*!< Smartconfig ACK type */
uint8_t *link_flag; /*!< Smartconfig link flag */
sc_callback_t cb; /*!< Smartconfig callback function */
struct {
uint8_t token; /*!< Smartconfig token to be sent */
uint8_t mac[6]; /*!< MAC address of station */
uint8_t ip[4]; /*!< IP address of cellphone */
} ctx;
} sc_ack_t;
/**
* @brief Smartconfig parameters passed sc_callback call.
*/
typedef struct sc_callback_ack {
uint8_t ip[4]; /*!< IP address of cellphone */
sc_ack_type_t type; /*!< Smartconfig ACK type */
} sc_callback_data_t;
/**
* @brief Send smartconfig ACK to cellphone.
*
* @attention The API is only used in libsmartconfig.a.
*
* @param param: smartconfig parameters;
*/
void sc_ack_send(sc_ack_t *param);
/**
* @brief Stop sending smartconfig ACK to cellphone.
*
* @attention The API is only used in libsmartconfig.a.
*/
void sc_ack_send_stop(void);
/**
* @brief Fill smartconfig ACK information to cellphone.
*
* @attention The API is only used in libsmartconfig.a.
*
* @param buffer: Transmits the data in the buffer;
* @param size: The size argument specifies the number of bytes to be transmitted.
*/
bool sc_ack_send_info(void *buffer, size_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -28,6 +28,11 @@ INPUT = \
../../components/esp8266/include/esp_wifi_types.h \
../../components/esp8266/include/esp_smartconfig.h \
##
## Event loop - API Reference
../../components/esp_event/include/esp_event.h \
../../components/esp_event/include/esp_event_base.h \
../../components/esp_event/include/esp_event_legacy.h \
##
## TCP-IP - API Reference
##
../../components/tcpip_adapter/include/tcpip_adapter.h \
@ -78,7 +83,8 @@ PREDEFINED = \
configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \
configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \
configUSE_APPLICATION_TASK_TAG=1 \
configTASKLIST_INCLUDE_COREID=1
configTASKLIST_INCLUDE_COREID=1 \
"ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x"
## Do not complain about not having dot
##

View File

@ -22,118 +22,95 @@
#include "smartconfig_ack.h"
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "sc";
static const char* TAG = "smartconfig_example";
static void smartconfig_example_task(void * parm);
static void smartconfig_example_task(void* parm);
static void on_wifi_start(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
}
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
ESP_LOGI(TAG, "Scan done");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
ESP_LOGI(TAG, "Found channel");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
ESP_LOGI(TAG, "Got SSID and password");
static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
system_event_sta_disconnected_t *event = (system_event_sta_disconnected_t *)event_data;
smartconfig_event_got_ssid_pswd_t* evt = (smartconfig_event_got_ssid_pswd_t*)event_data;
wifi_config_t wifi_config;
uint8_t ssid[33] = { 0 };
uint8_t password[65] = { 0 };
ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
if (event->reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
bzero(&wifi_config, sizeof(wifi_config_t));
memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
wifi_config.sta.bssid_set = evt->bssid_set;
if (wifi_config.sta.bssid_set == true) {
memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
}
memcpy(ssid, evt->ssid, sizeof(evt->ssid));
memcpy(password, evt->password, sizeof(evt->password));
ESP_LOGI(TAG, "SSID:%s", ssid);
ESP_LOGI(TAG, "PASSWORD:%s", password);
ESP_ERROR_CHECK(esp_wifi_disconnect());
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_connect());
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
}
ESP_ERROR_CHECK(esp_wifi_connect());
}
static void on_got_ip(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, &on_wifi_start, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_start() );
ESP_ERROR_CHECK( esp_wifi_connect() );
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
static void sc_callback(smartconfig_status_t status, void *pdata)
{
switch (status) {
case SC_STATUS_WAIT:
ESP_LOGI(TAG, "SC_STATUS_WAIT");
break;
case SC_STATUS_FIND_CHANNEL:
ESP_LOGI(TAG, "SC_STATUS_FINDING_CHANNEL");
break;
case SC_STATUS_GETTING_SSID_PSWD:
ESP_LOGI(TAG, "SC_STATUS_GETTING_SSID_PSWD");
break;
case SC_STATUS_LINK:
ESP_LOGI(TAG, "SC_STATUS_LINK");
wifi_config_t *wifi_config = pdata;
ESP_LOGI(TAG, "SSID:%s", wifi_config->sta.ssid);
ESP_LOGI(TAG, "PASSWORD:%s", wifi_config->sta.password);
ESP_ERROR_CHECK( esp_wifi_disconnect() );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, wifi_config) );
ESP_ERROR_CHECK( esp_wifi_connect() );
break;
case SC_STATUS_LINK_OVER:
ESP_LOGI(TAG, "SC_STATUS_LINK_OVER");
if (pdata != NULL) {
sc_callback_data_t *sc_callback_data = (sc_callback_data_t *)pdata;
switch (sc_callback_data->type) {
case SC_ACK_TYPE_ESPTOUCH:
ESP_LOGI(TAG, "Phone ip: %d.%d.%d.%d", sc_callback_data->ip[0], sc_callback_data->ip[1], sc_callback_data->ip[2], sc_callback_data->ip[3]);
ESP_LOGI(TAG, "TYPE: ESPTOUCH");
break;
case SC_ACK_TYPE_AIRKISS:
ESP_LOGI(TAG, "TYPE: AIRKISS");
break;
default:
ESP_LOGE(TAG, "TYPE: ERROR");
break;
}
}
xEventGroupSetBits(wifi_event_group, ESPTOUCH_DONE_BIT);
break;
default:
break;
}
}
static void smartconfig_example_task(void * parm)
static void smartconfig_example_task(void* parm)
{
EventBits_t uxBits;
ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS) );
ESP_ERROR_CHECK( esp_smartconfig_start(sc_callback) );
ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH));
smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_smartconfig_start(&cfg));
while (1) {
uxBits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
if(uxBits & CONNECTED_BIT) {
uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
if (uxBits & CONNECTED_BIT) {
ESP_LOGI(TAG, "WiFi Connected to ap");
}
if(uxBits & ESPTOUCH_DONE_BIT) {
if (uxBits & ESPTOUCH_DONE_BIT) {
ESP_LOGI(TAG, "smartconfig over");
esp_smartconfig_stop();
vTaskDelete(NULL);
@ -143,7 +120,7 @@ static void smartconfig_example_task(void * parm)
void app_main()
{
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
}