Merge branch 'master' into esp32s2

This commit is contained in:
Me No Dev
2020-05-11 23:35:43 +03:00
committed by GitHub
15 changed files with 890 additions and 40 deletions

View File

@ -9,7 +9,7 @@ echo "Installing PlatformIO ..."
pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1
echo "Installing Platform ESP32 ..."
python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1
python -m platformio platform install https://github.com/platformio/platform-espressif32.git > /dev/null 2>&1
echo "Replacing the framework version ..."
if [[ "$OSTYPE" == "darwin"* ]]; then

View File

@ -71,6 +71,7 @@ set(LIBRARY_SRCS
libraries/WiFi/src/WiFi.cpp
libraries/WiFi/src/WiFiGeneric.cpp
libraries/WiFi/src/WiFiMulti.cpp
libraries/WiFi/src/WiFiProv.cpp
libraries/WiFi/src/WiFiScan.cpp
libraries/WiFi/src/WiFiServer.cpp
libraries/WiFi/src/WiFiSTA.cpp

View File

@ -2625,6 +2625,67 @@ m5stick-c.menu.DebugLevel.debug.build.code_debug=4
m5stick-c.menu.DebugLevel.verbose=Verbose
m5stick-c.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
m5stack-atom.name=M5Stack-ATOM
m5stack-atom.upload.tool=esptool_py
m5stack-atom.upload.maximum_size=1310720
m5stack-atom.upload.maximum_data_size=327680
m5stack-atom.upload.wait_for_upload_port=true
m5stack-atom.serial.disableDTR=true
m5stack-atom.serial.disableRTS=true
m5stack-atom.build.mcu=esp32
m5stack-atom.build.core=esp32
m5stack-atom.build.variant=m5stack_atom
m5stack-atom.build.board=M5Stack_ATOM
m5stack-atom.build.f_cpu=240000000L
m5stack-atom.build.flash_size=4MB
m5stack-atom.build.flash_freq=80m
m5stack-atom.build.flash_mode=dio
m5stack-atom.build.boot=dio
m5stack-atom.build.partitions=default
m5stack-atom.build.defines=
m5stack-atom.menu.PartitionScheme.default=Default
m5stack-atom.menu.PartitionScheme.default.build.partitions=default
m5stack-atom.menu.PartitionScheme.no_ota=No OTA (Large APP)
m5stack-atom.menu.PartitionScheme.no_ota.build.partitions=no_ota
m5stack-atom.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
m5stack-atom.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
m5stack-atom.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
m5stack-atom.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
m5stack-atom.menu.UploadSpeed.1500000=1500000
m5stack-atom.menu.UploadSpeed.1500000.upload.speed=1500000
m5stack-atom.menu.UploadSpeed.750000=750000
m5stack-atom.menu.UploadSpeed.750000.upload.speed=750000
m5stack-atom.menu.UploadSpeed.500000=500000
m5stack-atom.menu.UploadSpeed.500000.upload.speed=500000
m5stack-atom.menu.UploadSpeed.250000=250000
m5stack-atom.menu.UploadSpeed.250000.upload.speed=250000
m5stack-atom.menu.UploadSpeed.115200=115200
m5stack-atom.menu.UploadSpeed.115200.upload.speed=115200
m5stack-atom.menu.DebugLevel.none=None
m5stack-atom.menu.DebugLevel.none.build.code_debug=0
m5stack-atom.menu.DebugLevel.error=Error
m5stack-atom.menu.DebugLevel.error.build.code_debug=1
m5stack-atom.menu.DebugLevel.warn=Warn
m5stack-atom.menu.DebugLevel.warn.build.code_debug=2
m5stack-atom.menu.DebugLevel.info=Info
m5stack-atom.menu.DebugLevel.info.build.code_debug=3
m5stack-atom.menu.DebugLevel.debug=Debug
m5stack-atom.menu.DebugLevel.debug.build.code_debug=4
m5stack-atom.menu.DebugLevel.verbose=Verbose
m5stack-atom.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
@ -4908,3 +4969,154 @@ metro_esp-32.menu.DebugLevel.verbose=Verbose
metro_esp-32.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
sensesiot_weizen.name=Senses's WEIZEN
sensesiot_weizen.upload.tool=esptool_py
sensesiot_weizen.upload.maximum_size=1310720
sensesiot_weizen.upload.maximum_data_size=327680
sensesiot_weizen.upload.wait_for_upload_port=true
sensesiot_weizen.serial.disableDTR=true
sensesiot_weizen.serial.disableRTS=true
sensesiot_weizen.build.mcu=esp32
sensesiot_weizen.build.core=esp32
sensesiot_weizen.build.variant=esp32
sensesiot_weizen.build.board=sensesiot_weizen
sensesiot_weizen.build.f_cpu=240000000L
sensesiot_weizen.build.flash_mode=dio
sensesiot_weizen.build.flash_size=4MB
sensesiot_weizen.build.boot=dio
sensesiot_weizen.build.partitions=default
sensesiot_weizen.build.defines=
sensesiot_weizen.menu.FlashFreq.80=80MHz
sensesiot_weizen.menu.FlashFreq.80.build.flash_freq=80m
sensesiot_weizen.menu.FlashFreq.40=40MHz
sensesiot_weizen.menu.FlashFreq.40.build.flash_freq=40m
sensesiot_weizen.menu.UploadSpeed.921600=921600
sensesiot_weizen.menu.UploadSpeed.921600.upload.speed=921600
sensesiot_weizen.menu.UploadSpeed.115200=115200
sensesiot_weizen.menu.UploadSpeed.115200.upload.speed=115200
sensesiot_weizen.menu.UploadSpeed.256000.windows=256000
sensesiot_weizen.menu.UploadSpeed.256000.upload.speed=256000
sensesiot_weizen.menu.UploadSpeed.230400.windows.upload.speed=256000
sensesiot_weizen.menu.UploadSpeed.230400=230400
sensesiot_weizen.menu.UploadSpeed.230400.upload.speed=230400
sensesiot_weizen.menu.UploadSpeed.460800.linux=460800
sensesiot_weizen.menu.UploadSpeed.460800.macosx=460800
sensesiot_weizen.menu.UploadSpeed.460800.upload.speed=460800
sensesiot_weizen.menu.UploadSpeed.512000.windows=512000
sensesiot_weizen.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
mPython.name=mPython
mPython.upload.tool=esptool_py
mPython.upload.maximum_size=1310720
mPython.upload.maximum_data_size=327680
mPython.upload.wait_for_upload_port=true
mPython.serial.disableDTR=true
mPython.serial.disableRTS=true
mPython.build.mcu=esp32
mPython.build.core=esp32
mPython.build.variant=mpython
mPython.build.board=ESP32_DEV
mPython.build.f_cpu=240000000L
mPython.build.flash_size=8MB
mPython.build.flash_freq=40m
mPython.build.flash_mode=dio
mPython.build.boot=dio
mPython.build.partitions=huge_app
mPython.build.defines=
mPython.menu.PSRAM.disabled=Disabled
mPython.menu.PSRAM.disabled.build.defines=
mPython.menu.PSRAM.enabled=Enabled
mPython.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
mPython.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
mPython.menu.PartitionScheme.huge_app.build.partitions=huge_app
mPython.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
mPython.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
mPython.menu.PartitionScheme.default.build.partitions=default
mPython.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
mPython.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
mPython.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
mPython.menu.PartitionScheme.minimal.build.partitions=minimal
mPython.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
mPython.menu.PartitionScheme.no_ota.build.partitions=no_ota
mPython.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
mPython.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
mPython.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
mPython.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
mPython.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
mPython.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
mPython.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
mPython.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
mPython.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
mPython.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
mPython.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
mPython.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
mPython.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
mPython.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT)
mPython.menu.PartitionScheme.fatflash.build.partitions=ffat
mPython.menu.CPUFreq.240=240MHz (WiFi/BT)
mPython.menu.CPUFreq.240.build.f_cpu=240000000L
mPython.menu.FlashMode.qio=QIO
mPython.menu.FlashMode.qio.build.flash_mode=dio
mPython.menu.FlashMode.qio.build.boot=qio
mPython.menu.FlashMode.dio=DIO
mPython.menu.FlashMode.dio.build.flash_mode=dio
mPython.menu.FlashMode.dio.build.boot=dio
mPython.menu.FlashMode.qout=QOUT
mPython.menu.FlashMode.qout.build.flash_mode=dout
mPython.menu.FlashMode.qout.build.boot=qout
mPython.menu.FlashMode.dout=DOUT
mPython.menu.FlashMode.dout.build.flash_mode=dout
mPython.menu.FlashMode.dout.build.boot=dout
mPython.menu.FlashFreq.80=80MHz
mPython.menu.FlashFreq.80.build.flash_freq=80m
mPython.menu.FlashFreq.40=40MHz
mPython.menu.FlashFreq.40.build.flash_freq=40m
mPython.menu.FlashSize.8M=8MB (64Mb)
mPython.menu.FlashSize.8M.build.flash_size=8MB
mPython.menu.UploadSpeed.921600=921600
mPython.menu.UploadSpeed.921600.upload.speed=921600
mPython.menu.UploadSpeed.115200=115200
mPython.menu.UploadSpeed.115200.upload.speed=115200
mPython.menu.UploadSpeed.256000.windows=256000
mPython.menu.UploadSpeed.256000.upload.speed=256000
mPython.menu.UploadSpeed.230400.windows.upload.speed=256000
mPython.menu.UploadSpeed.230400=230400
mPython.menu.UploadSpeed.230400.upload.speed=230400
mPython.menu.UploadSpeed.460800.linux=460800
mPython.menu.UploadSpeed.460800.macosx=460800
mPython.menu.UploadSpeed.460800.upload.speed=460800
mPython.menu.UploadSpeed.512000.windows=512000
mPython.menu.UploadSpeed.512000.upload.speed=512000
mPython.menu.DebugLevel.none=None
mPython.menu.DebugLevel.none.build.code_debug=0
mPython.menu.DebugLevel.error=Error
mPython.menu.DebugLevel.error.build.code_debug=1
mPython.menu.DebugLevel.warn=Warn
mPython.menu.DebugLevel.warn.build.code_debug=2
mPython.menu.DebugLevel.info=Info
mPython.menu.DebugLevel.info.build.code_debug=3
mPython.menu.DebugLevel.debug=Debug
mPython.menu.DebugLevel.debug.build.code_debug=4
mPython.menu.DebugLevel.verbose=Verbose
mPython.menu.DebugLevel.verbose.build.code_debug=5
##############################################################

View File

@ -540,12 +540,8 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
}
}
void spiStopBus(spi_t * spi)
static void spiInitBus(spi_t * spi)
{
if(!spi) {
return;
}
SPI_MUTEX_LOCK();
spi->dev->slave.trans_done = 0;
spi->dev->slave.slave_mode = 0;
#if CONFIG_IDF_TARGET_ESP32S2
@ -559,8 +555,19 @@ void spiStopBus(spi_t * spi)
spi->dev->ctrl1.val = 0;
spi->dev->ctrl2.val = 0;
spi->dev->clock.val = 0;
SPI_MUTEX_UNLOCK();
}
void spiStopBus(spi_t * spi)
{
if(!spi) {
return;
}
removeApbChangeCallback(spi, _on_apb_change);
SPI_MUTEX_LOCK();
spiInitBus(spi);
SPI_MUTEX_UNLOCK();
}
spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder)
@ -604,12 +611,8 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
}
#endif
spiStopBus(spi);
spiSetDataMode(spi, dataMode);
spiSetBitOrder(spi, bitOrder);
spiSetClockDiv(spi, clockDiv);
SPI_MUTEX_LOCK();
spiInitBus(spi);
spi->dev->user.usr_mosi = 1;
spi->dev->user.usr_miso = 1;
spi->dev->user.doutdin = 1;
@ -620,6 +623,10 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
}
SPI_MUTEX_UNLOCK();
spiSetDataMode(spi, dataMode);
spiSetBitOrder(spi, bitOrder);
spiSetClockDiv(spi, clockDiv);
addApbChangeCallback(spi, _on_apb_change);
return spi;
}

View File

@ -118,7 +118,7 @@ static void IRAM_ATTR _uart_isr(void *arg)
while(uart->dev->status.rxfifo_cnt) {
c = uart->dev->ahb_fifo.rw_byte;
#endif
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
if(uart->queue != NULL) {
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
}
}
@ -247,6 +247,11 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
uart->dev->conf0.stop_bit_num = ONE_STOP_BITS_CONF;
uart->dev->rs485_conf.dl1_en = 1;
}
// tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate)
// Setting it to 0 prevents line idle time/delays when sending messages with small intervals
uart->dev->idle_conf.tx_idle_num = 0; //
UART_MUTEX_UNLOCK();
if(rxPin != -1) {
@ -304,7 +309,7 @@ uint32_t uartAvailable(uart_t* uart)
if(uart == NULL || uart->queue == NULL) {
return 0;
}
return uxQueueMessagesWaiting(uart->queue);
return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ;
}
uint32_t uartAvailableForWrite(uart_t* uart)
@ -315,12 +320,35 @@ uint32_t uartAvailableForWrite(uart_t* uart)
return 0x7f - uart->dev->status.txfifo_cnt;
}
void uartRxFifoToQueue(uart_t* uart)
{
uint8_t c;
UART_MUTEX_LOCK();
//disable interrupts
uart->dev->int_ena.val = 0;
uart->dev->int_clr.val = 0xffffffff;
while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
c = uart->dev->fifo.rw_byte;
xQueueSend(uart->queue, &c, 0);
}
//enable interrupts
uart->dev->int_ena.rxfifo_full = 1;
uart->dev->int_ena.frm_err = 1;
uart->dev->int_ena.rxfifo_tout = 1;
uart->dev->int_clr.val = 0xffffffff;
UART_MUTEX_UNLOCK();
}
uint8_t uartRead(uart_t* uart)
{
if(uart == NULL || uart->queue == NULL) {
return 0;
}
uint8_t c;
if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0))
{
uartRxFifoToQueue(uart);
}
if(xQueueReceive(uart->queue, &c, 0)) {
return c;
}
@ -333,6 +361,10 @@ uint8_t uartPeek(uart_t* uart)
return 0;
}
uint8_t c;
if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0))
{
uartRxFifoToQueue(uart);
}
if(xQueuePeek(uart->queue, &c, 0)) {
return c;
}

View File

@ -403,6 +403,9 @@ static esp_err_t stream_handler(httpd_req_t *req){
}
}
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
@ -410,9 +413,6 @@ static esp_err_t stream_handler(httpd_req_t *req){
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(fb){
esp_camera_fb_return(fb);
fb = NULL;

View File

@ -0,0 +1,126 @@
# Provisioning for Arduino
This sketch implements provisioning using various IDF components
# Description
This example allows Arduino user to choose either BLE or SOFTAP as a mode of transport, over which the provisioning related communication is to take place, between the device (to be provisioned) and the client (owner of the device).
# APIs introduced for provisioning
## WiFi.onEvent()
Using this API user can register to receive WiFi Events and Provisioning Events
#### Parameters passed
A function with following signature
* void SysProvEvent(system_event_t * , wifi_prov_event_t * );
#### structure [ wifi_prov_event_t ]
* wifi_prov_cb_event_t event;
* void * event_data;
## WiFi.beginProvision()
WiFi.beginProvision(scheme prov_scheme, wifi_prov_scheme_event_handler_t scheme_event_handler, wifi_prov_security_t security, char * pop, char * service_name, char * service_key, uint8_t * uuid);
#### Parameters passed
* prov_scheme : choose the mode of transfer
* WIFI_PROV_SCHEME_BLE - Using BLE
* WIFI_PROV_SCHEME_SOFTAP - Using SoftAP
* security : choose security type
* WIFI_PROV_SECURITY_1 - It allows secure communication which consists of secure handshake using key exchange and proof of possession (pop) and encryption/decryption of messages.
* WIFI_PROV_SECURITY_0 - It do not provide application level security, it involve simply plain text communication.
* scheme_event_handler : specify the handlers according to the mode chosen
* BLE :
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM - This scheme event handler is used when application doesn't need BT and BLE after provisioning is finised
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE - This scheme event handler is used when application doesn't need BLE to be active after provisioning is finised
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT - This scheme event handler is used when application doesn't need BT to be active after provisioning is finised
* SoftAp :
- WIFI_PROV_EVENT_HANDLER_NONE
* pop : It is the string that is used to provide the authentication.
* service_name : Specify service name for the device, if it is not specified then default chosen name via SoftAP is WIFI_XXX and via BLE is BLE_XXX where XXX are the last 3 bytes of the MAC address.
* service_key : Specify service key, if chosen mode of provisioning is BLE then service_key is always NULL
* uuid : user can specify there own 128 bit UUID while provisioning using BLE, if not specified then default value taken is
- { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, }
# NOTE
* If none of the parameters are specified in beginProvision then default provisioning takes place using SoftAP with
* scheme = WIFI_PROV_SCHEME_SOFTAP
* scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE
* security = WIFI_PROV_SECURITY_1
* pop = "abcd1234"
* service_name = "WiFi_XXX"
* service_key = NULL
* uuid = NULL
# Log Output
* Enable debuger : [ Tools -> Core Debug Level -> Info ]
# Provisioning Tools
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/provisioning/wifi_provisioning.html#provisioning-tools
# Example output
## Provisioning using SoftAP
```
[I][WiFiProv.cpp:117] beginProvision(): Starting AP using SOFTAP
service_name : WIFI_XXX
password : 123456789
pop : abcd1234
Provisioning started
Give Credentials of your access point using " Android app "
Received Wi-Fi credentials
SSID : GIONEE M2
Password : 123456789
Connected IP address : 192.168.43.120
Provisioning Successful
Provisioning Ends
```
## Provisioning using BLE
```
[I][WiFiProv.cpp:115] beginProvision(): Starting AP using BLE
service_name : BLE_XXX
pop : abcd1234
Provisioning started
Give Credentials of your access point using " Android app "
Received Wi-Fi credentials
SSID : GIONEE M2
Password : 123456789
Connected IP address : 192.168.43.120
Provisioning Successful
Provisioning Ends
```
## Credentials are available on device
```
[I][WiFiProv.cpp:125] beginProvision(): Aleardy Provisioned, starting Wi-Fi STA
[I][WiFiProv.cpp:126] beginProvision(): CONNECTING ACCESS POINT CREDENTIALS :
[I][WiFiProv.cpp:126] beginProvision(): SSID : GIONEE M2
```

View File

@ -0,0 +1,63 @@
#include "WiFi.h"
void SysProvEvent(system_event_t *sys_event,wifi_prov_event_t *prov_event)
{
if(sys_event) {
switch (sys_event->event_id) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.print("\nConnected IP address : ");
Serial.println(ip4addr_ntoa(&sys_event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("\nDisconnected. Connecting to the AP again... ");
break;
default:
break;
}
}
if(prov_event) {
switch (prov_event->event) {
case WIFI_PROV_START:
Serial.println("\nProvisioning started\nGive Credentials of your access point using \" Android app \"");
break;
case WIFI_PROV_CRED_RECV: {
Serial.println("\nReceived Wi-Fi credentials");
wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)prov_event->event_data;
Serial.print("\tSSID : ");
Serial.println((const char *) wifi_sta_cfg->ssid);
Serial.print("\tPassword : ");
Serial.println((char const *) wifi_sta_cfg->password);
break;
}
case WIFI_PROV_CRED_FAIL: {
wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)prov_event->event_data;
Serial.println("\nProvisioning failed!\nPlease reset to factory and retry provisioning\n");
if(*reason == WIFI_PROV_STA_AUTH_ERROR)
Serial.println("\nWi-Fi AP password incorrect");
else
Serial.println("\nWi-Fi AP not found....Add API \" nvs_flash_erase() \" before beginProvision()");
break;
}
case WIFI_PROV_CRED_SUCCESS:
Serial.println("\nProvisioning Successful");
break;
case WIFI_PROV_END:
Serial.println("\nProvisioning Ends");
break;
default:
break;
}
}
}
void setup() {
Serial.begin(115200);
//Sample uuid that user can pass during provisioning using BLE
/* uint8_t uuid[16] = {0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02 };*/
WiFi.onEvent(SysProvEvent);
WiFi.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, "abcd1234", "BLE_XXX", NULL, NULL);
}
void loop() {
}

View File

@ -37,8 +37,9 @@
#include "WiFiClient.h"
#include "WiFiServer.h"
#include "WiFiUdp.h"
#include "WiFiProv.h"
class WiFiClass : public WiFiGenericClass, public WiFiSTAClass, public WiFiScanClass, public WiFiAPClass
class WiFiClass : public WiFiGenericClass, public WiFiSTAClass, public WiFiScanClass, public WiFiAPClass, public WiFiProvClass
{
public:
using WiFiGenericClass::channel;
@ -54,8 +55,7 @@ public:
using WiFiScanClass::BSSID;
using WiFiScanClass::BSSIDstr;
using WiFiScanClass::channel;
public:
public:
void printDiag(Print& dest);
friend class WiFiClient;
friend class WiFiServer;

View File

@ -42,7 +42,6 @@ extern "C" {
#include "lwip/dns.h"
#include "esp_ipc.h"
} //extern "C"
#include "esp32-hal-log.h"
@ -53,29 +52,47 @@ static xQueueHandle _network_event_queue;
static TaskHandle_t _network_event_task_handle = NULL;
static EventGroupHandle_t _network_event_group = NULL;
esp_err_t postToSysQueue(system_prov_event_t *data)
{
if (xQueueSend(_network_event_queue, &data, portMAX_DELAY) != pdPASS) {
log_w("Network Event Queue Send Failed!");
return ESP_FAIL;
}
return ESP_OK;
}
static void _network_event_task(void * arg){
system_event_t event;
system_prov_event_t *data;
for (;;) {
if(xQueueReceive(_network_event_queue, &event, portMAX_DELAY) == pdTRUE){
WiFiGenericClass::_eventCallback(arg, &event);
}
if(xQueueReceive(_network_event_queue, &data, portMAX_DELAY) == pdTRUE){
if(data->prov_event != NULL){
WiFiGenericClass::_eventCallback(arg, data->sys_event, data->prov_event);
free(data->sys_event);
free(data->prov_event);
} else {
WiFiGenericClass::_eventCallback(arg, data->sys_event, NULL);
}
free(data);
}
}
vTaskDelete(NULL);
_network_event_task_handle = NULL;
}
static void _network_event_cb(void* arg, esp_event_base_t base, int32_t id, void* data) {
if (xQueueSend(_network_event_queue, (system_event_t *)data, portMAX_DELAY) != pdPASS) {
log_w("Network Event Queue Send Failed!");
system_event_t *event = (system_event_t *)data;
system_prov_event_t *sys_prov_data = (system_prov_event_t *)malloc(sizeof(system_prov_event_t));
if(sys_prov_data == NULL) {
return;
}
sys_prov_data->sys_event = event;
sys_prov_data->prov_event = NULL;
if (postToSysQueue(sys_prov_data) != ESP_OK){
free(sys_prov_data);
return;
}
}
// static esp_err_t _network_event_cb(void *arg, system_event_t *event){
// if (xQueueSend(_network_event_queue, event, portMAX_DELAY) != pdPASS) {
// log_w("Network Event Queue Send Failed!");
// return ESP_FAIL;
// }
// return ESP_OK;
// }
ESP_EVENT_DEFINE_BASE(SYSTEM_EVENT);
static bool _start_network_event_task(){
@ -88,7 +105,7 @@ static bool _start_network_event_task(){
xEventGroupSetBits(_network_event_group, WIFI_DNS_IDLE_BIT);
}
if(!_network_event_queue){
_network_event_queue = xQueueCreate(32, sizeof(system_event_t));
_network_event_queue = xQueueCreate(32, sizeof(system_prov_event_t));
if(!_network_event_queue){
log_e("Network Event Queue Create Failed!");
return false;
@ -164,7 +181,7 @@ static bool espWiFiStart(){
_esp_wifi_started = true;
system_event_t event;
event.event_id = SYSTEM_EVENT_WIFI_READY;
WiFiGenericClass::_eventCallback(nullptr, &event);
WiFiGenericClass::_eventCallback(nullptr, &event, NULL);
return true;
}
@ -193,9 +210,10 @@ typedef struct WiFiEventCbList {
WiFiEventCb cb;
WiFiEventFuncCb fcb;
WiFiEventSysCb scb;
WiFiProvEventCb provcb;
system_event_id_t event;
WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), event(SYSTEM_EVENT_WIFI_READY) {}
WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), provcb(NULL), event(SYSTEM_EVENT_WIFI_READY) {}
} WiFiEventCbList_t;
wifi_event_id_t WiFiEventCbList::current_id = 1;
@ -250,6 +268,20 @@ int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){
* @param cbEvent WiFiEventCb
* @param event optional filter (WIFI_EVENT_MAX is all events)
*/
wifi_event_id_t WiFiGenericClass::onEvent(WiFiProvEventCb cbEvent, system_event_id_t event)
{
if(!cbEvent){
return 0;
}
WiFiEventCbList_t newEventHandler;
newEventHandler.cb = NULL;
newEventHandler.fcb = NULL;
newEventHandler.scb = NULL;
newEventHandler.provcb = cbEvent;
newEventHandler.event = event;
cbEventList.push_back(newEventHandler);
return newEventHandler.id;
}
wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t event)
{
if(!cbEvent) {
@ -259,6 +291,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t
newEventHandler.cb = cbEvent;
newEventHandler.fcb = NULL;
newEventHandler.scb = NULL;
newEventHandler.provcb = NULL;
newEventHandler.event = event;
cbEventList.push_back(newEventHandler);
return newEventHandler.id;
@ -273,6 +306,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, system_event_
newEventHandler.cb = NULL;
newEventHandler.fcb = cbEvent;
newEventHandler.scb = NULL;
newEventHandler.provcb = NULL;
newEventHandler.event = event;
cbEventList.push_back(newEventHandler);
return newEventHandler.id;
@ -287,6 +321,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_i
newEventHandler.cb = NULL;
newEventHandler.fcb = NULL;
newEventHandler.scb = cbEvent;
newEventHandler.provcb = NULL;
newEventHandler.event = event;
cbEventList.push_back(newEventHandler);
return newEventHandler.id;
@ -346,8 +381,11 @@ const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "S
const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "UNSPECIFIED", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT", "CONNECTION_FAIL" };
#define reason2str(r) ((r>176)?system_event_reasons[r-176]:system_event_reasons[r-1])
#endif
esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event, wifi_prov_event_t *prov_event)
{
if(WiFi.isProvEnabled()) {
wifi_prov_mgr_event_handler(arg,event);
}
if(event->event_id < 26) {
log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]);
}
@ -442,7 +480,7 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP6_BIT);
}
}
for(uint32_t i = 0; i < cbEventList.size(); i++) {
WiFiEventCbList_t entry = cbEventList[i];
if(entry.cb || entry.fcb || entry.scb) {
@ -456,6 +494,10 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
}
}
}
if(entry.provcb) {
entry.provcb(event,prov_event);
}
}
return ESP_OK;
}

View File

@ -27,10 +27,25 @@
#include <esp_event.h>
#include <functional>
#include "WiFiType.h"
#include "IPAddress.h"
#include <wifi_provisioning/manager.h>
typedef struct
{
wifi_prov_cb_event_t event;
void *event_data;
}wifi_prov_event_t;
typedef struct
{
wifi_prov_event_t *prov_event;
system_event_t *sys_event;
}system_prov_event_t;
typedef void (*WiFiEventCb)(system_event_id_t event);
typedef std::function<void(system_event_id_t event, system_event_info_t info)> WiFiEventFuncCb;
typedef void (*WiFiEventSysCb)(system_event_t *event);
typedef void (*WiFiProvEventCb)(system_event_t *sys_event, wifi_prov_event_t *prov_event);
typedef size_t wifi_event_id_t;
@ -73,6 +88,7 @@ class WiFiGenericClass
wifi_event_id_t onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
wifi_event_id_t onEvent(WiFiProvEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
void removeEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
void removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
void removeEvent(wifi_event_id_t id);
@ -97,7 +113,7 @@ class WiFiGenericClass
bool setTxPower(wifi_power_t power);
wifi_power_t getTxPower();
static esp_err_t _eventCallback(void *arg, system_event_t *event);
static esp_err_t _eventCallback(void *arg, system_event_t *event, wifi_prov_event_t *prov_event);
protected:
static bool _persistent;

View File

@ -0,0 +1,161 @@
/*
WiFiProv.cpp - WiFiProv class for provisioning
All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <esp_err.h>
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp32-hal.h>
#include <nvs_flash.h>
#include <wifi_provisioning/scheme_ble.h>
#include <wifi_provisioning/scheme_softap.h>
#include <wifi_provisioning/manager.h>
#undef IPADDR_NONE
#include "WiFi.h"
extern esp_err_t postToSysQueue(system_prov_event_t *);
static const uint8_t custom_service_uuid[16] = { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, };
#define SERV_NAME_PREFIX_BLE "BLE_"
#define SERV_NAME_PREFIX_WIFI "WIFI_"
bool WiFiProvClass::prov_enable = true;
bool WiFiProvClass::isProvEnabled()
{
return prov_enable;
}
static void prov_event_handler(void *user_data, wifi_prov_cb_event_t event, void *event_data)
{
if (!event) {
return;
}
system_prov_event_t *sys_prov = (system_prov_event_t *)malloc(sizeof(system_prov_event_t));
if(sys_prov == NULL) {
log_e("Malloc Failed");
return;
}
sys_prov->prov_event = (wifi_prov_event_t *)malloc(sizeof(wifi_prov_event_t));
if(sys_prov->prov_event == NULL) {
log_e("Malloc Failed");
free(sys_prov);
return;
}
sys_prov->sys_event = (system_event_t *)malloc(sizeof(system_event_t));
if(sys_prov->sys_event == NULL) {
log_e("Malloc Failed");
free(sys_prov->prov_event);
free(sys_prov);
return;
}
sys_prov->prov_event->event = event;
sys_prov->prov_event->event_data = event_data;
sys_prov->sys_event->event_id = SYSTEM_EVENT_MAX;
esp_err_t check = postToSysQueue(sys_prov);
if(check == ESP_FAIL) {
log_e("Provisioning event not send to queue");
free(sys_prov->sys_event);
free(sys_prov->prov_event);
free(sys_prov);
}
}
static void get_device_service_name(scheme prov_scheme, char *service_name, size_t max)
{
uint8_t eth_mac[6];
WiFi.macAddress(eth_mac);
if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
snprintf(service_name, max, "%s%02X%02X%02X",SERV_NAME_PREFIX_BLE, eth_mac[3], eth_mac[4], eth_mac[5]);
} else {
snprintf(service_name, max, "%s%02X%02X%02X",SERV_NAME_PREFIX_WIFI, eth_mac[3], eth_mac[4], eth_mac[5]);
}
}
void WiFiProvClass :: beginProvision(scheme prov_scheme, wifi_prov_event_handler_t scheme_event_handler, wifi_prov_security_t security, const char * pop, const char *service_name, const char *service_key, uint8_t * uuid)
{
prov_enable = true;
bool provisioned = false;
wifi_prov_mgr_config_t config;
config.scheme_event_handler = scheme_event_handler;
config.app_event_handler = {
.event_cb = prov_event_handler,
.user_data = NULL
};
if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
config.scheme = wifi_prov_scheme_ble;
} else {
config.scheme = wifi_prov_scheme_softap;
}
wifi_prov_mgr_init(config);
WiFi.mode(WIFI_MODE_AP);
wifi_prov_mgr_is_provisioned(&provisioned);
if(provisioned == false) {
if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
service_key = NULL;
if(uuid == NULL) {
uuid=(uint8_t *)custom_service_uuid;
}
wifi_prov_scheme_ble_set_service_uuid(uuid);
}
if(service_name == NULL) {
char service_name_temp[12];
get_device_service_name(prov_scheme,service_name_temp,sizeof(service_name_temp));
service_name = (const char *)service_name_temp;
}
if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
log_i("Starting AP using BLE\n service_name : %s\n pop : %s",service_name,pop);
} else {
if(service_key == NULL) {
log_i("Starting AP using SOFTAP\n service_name : %s\n pop : %s",service_name,pop);
} else {
log_i("Starting AP using SOFTAP\n service_name : %s\n password : %s\n pop : %s",service_name,service_key,pop);
}
}
wifi_prov_mgr_start_provisioning(security,pop,service_name,service_key);
} else {
wifi_prov_mgr_deinit();
WiFi.mode(WIFI_MODE_STA);
log_i("Aleardy Provisioned, starting Wi-Fi STA");
log_i("CONNECTING ACCESS POINT CREDENTIALS : ");
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
wifi_config_t conf;
esp_wifi_get_config(WIFI_IF_STA,&conf);
log_i("SSID : %s\n",conf.sta.ssid);
#endif
}
}

View File

@ -0,0 +1,55 @@
/*
WiFiProv.h - Base class for provisioning support
All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "wifi_provisioning/manager.h"
#include "wifi_provisioning/scheme_ble.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "SimpleBLE.h"
//Select the scheme using which you want to provision
enum scheme
{
WIFI_PROV_SCHEME_BLE,
WIFI_PROV_SCHEME_SOFTAP,
WIFI_PROV_SCHEME_CONSOLE
};
//Provisioning class
class WiFiProvClass
{
protected:
static bool prov_enable;
public:
WiFiProvClass() {
prov_enable = false;
}
bool isProvEnabled();
void beginProvision(scheme prov_scheme = WIFI_PROV_SCHEME_SOFTAP, wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE, wifi_prov_security_t security = WIFI_PROV_SECURITY_1, const char * pop = "abcd1234", const char * service_name = NULL, const char * service_key = NULL, uint8_t *uuid = NULL);
};
/*
Event Handler for BLE
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT
Event Handler for SOFTAP
- WIFI_PROV_EVENT_HANDLER_NONE
*/

View File

@ -0,0 +1,90 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t SDA = 23;
static const uint8_t SCL = 22;
static const uint8_t SS = 5;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 19;
static const uint8_t SCK = 18;
static const uint8_t A0 = 36;
static const uint8_t A3 = 39;
static const uint8_t A4 = 32;
static const uint8_t A5 = 33;
static const uint8_t A6 = 34;
static const uint8_t A7 = 35;
static const uint8_t A10 = 4;
static const uint8_t A11 = 0;
static const uint8_t A12 = 2;
static const uint8_t A13 = 15;
static const uint8_t A14 = 13;
static const uint8_t A15 = 12;
static const uint8_t A16 = 14;
static const uint8_t A17 = 27;
static const uint8_t A18 = 25;
static const uint8_t A19 = 26;
static const uint8_t T0 = 4;
static const uint8_t T1 = 0;
static const uint8_t T2 = 2;
static const uint8_t T3 = 15;
static const uint8_t T4 = 13;
static const uint8_t T5 = 12;
static const uint8_t T6 = 14;
static const uint8_t T7 = 27;
static const uint8_t T8 = 33;
static const uint8_t T9 = 32;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
static const uint8_t P0 = 33;
static const uint8_t P1 = 32;
static const uint8_t P2 = 35;
static const uint8_t P3 = 34;
static const uint8_t P4 = 39;
static const uint8_t P5 = 0;
static const uint8_t P6 = 16;
static const uint8_t P7 = 17;
static const uint8_t P8 = 26;
static const uint8_t P9 = 25;
static const uint8_t P10 = 36;
static const uint8_t P11 = 2;
static const uint8_t P13 = 18;
static const uint8_t P14 = 19;
static const uint8_t P15 = 21;
static const uint8_t P16 = 5;
static const uint8_t P19 = 22;
static const uint8_t P20 = 23;
static const uint8_t P = 27;
static const uint8_t Y = 14;
static const uint8_t T = 12;
static const uint8_t H = 13;
static const uint8_t O = 15;
static const uint8_t N = 4;
static const uint8_t BTN_A = 0;
static const uint8_t BTN_B = 2;
static const uint8_t SOUND = 36;
static const uint8_t LIGHT = 39;
static const uint8_t BUZZER = 16;
#endif /* Pins_Arduino_h */

View File

@ -0,0 +1,45 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t SDA = 26;
static const uint8_t SCL = 32;
static const uint8_t G12 = 12;
static const uint8_t G19 = 19;
static const uint8_t G22 = 21;
static const uint8_t G22 = 22;
static const uint8_t G23 = 23;
static const uint8_t G25 = 25;
static const uint8_t G26 = 26;
static const uint8_t G27 = 27;
static const uint8_t G32 = 32;
static const uint8_t G33 = 33;
static const uint8_t G39 = 39;
static const uint8_t G9 = 9;
static const uint8_t G10 = 10;
static const uint8_t G37 = 37;
static const uint8_t G36 = 36;
static const uint8_t G0 = 0;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
static const uint8_t ADC1 = 35;
static const uint8_t ADC2 = 36;
#endif /* Pins_Arduino_h */