example: Add wifi station machine demo

This commit is contained in:
Espressif Systems
2017-03-16 19:41:43 +08:00
parent d587762e50
commit 4c58d9eee3
9 changed files with 1027 additions and 0 deletions

View File

@ -0,0 +1,132 @@
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of object file images to be generated ()
# GEN_BINS - list of binaries to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
TARGET = eagle
#FLAVOR = release
FLAVOR = debug
#EXTRA_CCFLAGS += -u
ifndef PDIR # {
GEN_IMAGES= eagle.app.v6.out
GEN_BINS= eagle.app.v6.bin
SPECIAL_MKTARGETS=$(APP_MKTARGETS)
SUBDIRS= \
user
endif # } PDIR
LDDIR = $(SDK_PATH)/ld
CCFLAGS += -Os
TARGET_LDFLAGS = \
-nostdlib \
-Wl,-EL \
--longcalls \
--text-section-literals
ifeq ($(FLAVOR),debug)
TARGET_LDFLAGS += -g -O2
endif
ifeq ($(FLAVOR),release)
TARGET_LDFLAGS += -g -O0
endif
COMPONENTS_eagle.app.v6 = \
user/libuser.a
LINKFLAGS_eagle.app.v6 = \
-L$(SDK_PATH)/lib \
-Wl,--gc-sections \
-nostdlib \
-T$(LD_FILE) \
-Wl,--no-check-sections \
-u call_user_start \
-Wl,-static \
-Wl,--start-group \
-lcirom \
-lcrypto \
-lespconn \
-lespnow \
-lfreertos \
-lgcc \
-lhal \
-ljson \
-llwip \
-lmain \
-lmesh \
-lmirom \
-lnet80211 \
-lnopoll \
-lphy \
-lpp \
-lpwm \
-lmbedtls \
-lopenssl \
-lsmartconfig \
-lspiffs \
-lwpa \
-lwps \
$(DEP_LIBS_eagle.app.v6) \
-Wl,--end-group
DEPENDS_eagle.app.v6 = \
$(LD_FILE) \
$(LDDIR)/eagle.rom.addr.v6.ld
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#UNIVERSAL_TARGET_DEFINES = \
# Other potential configuration flags include:
# -DTXRX_TXBUF_DEBUG
# -DTXRX_RXBUF_DEBUG
# -DWLAN_CONFIG_CCX
CONFIGURATION_DEFINES = -DICACHE_FLASH -D__STDC_NO_ATOMICS__=1 -DESP8266_RTOS -D__STDC_VERSION__=201112L -DFREERTOS_ARCH_ESP8266
#-DNO_LOGGING=1
DEFINES += \
$(UNIVERSAL_TARGET_DEFINES) \
$(CONFIGURATION_DEFINES)
DDEFINES += \
$(UNIVERSAL_TARGET_DEFINES) \
$(CONFIGURATION_DEFINES)
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
sinclude $(SDK_PATH)/Makefile
.PHONY: FORCE
FORCE:

View File

@ -0,0 +1,172 @@
@echo off
Rem ******NOTICE******
Rem MUST set SDK_PATH & BIN_PATH firstly!!!
Rem example:
Rem set SDK_PATH=/c/esp_iot_sdk_freertos
Rem set BIN_PATH=/c/esp8266_bin
set SDK_PATH=""
set BIN_PATH=""
echo gen_misc.bat version 20150911
echo .
if not %SDK_PATH% == "" (
echo SDK_PATH: %SDK_PATH%
) else (
echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!!
goto end
)
if not %BIN_PATH% == "" (
echo BIN_PATH: %BIN_PATH%
) else (
echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!!
goto end
)
echo .
echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue:
set input=default
set /p input=
if not %input% == Y (
if not %input% == y (
goto end
)
)
echo .
echo Please follow below steps(1-5) to generate specific bin(s):
echo STEP 1: use boot_v1.2+ by default
set boot=new
echo boot mode: %boot%
echo.
echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)
set input=default
set /p input=enter (0/1/2, default 0):
if %input% equ 1 (
if %boot% equ none (
set app=0
echo choose no boot before
echo generate bin: eagle.flash.bin+eagle.irom0text.bin
) else (
set app=1
echo generate bin: user1.bin
)
) else (
if %input% equ 2 (
if %boot% equ none (
set app=0
echo choose no boot before
echo generate bin: eagle.flash.bin+eagle.irom0text.bin
) else (
set app=2
echo generate bin: user2.bin
)
) else (
if %boot% neq none (
set boot=none
echo ignore boot
)
set app=0
echo generate bin: eagle.flash.bin+eagle.irom0text.bin
))
echo.
echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)
set input=default
set /p input=enter (0/1/2/3, default 2):
if %input% equ 0 (
set spi_speed=20
) else (
if %input% equ 1 (
set spi_speed=26.7
) else (
if %input% equ 3 (
set spi_speed=80
) else (
set spi_speed=40
)))
echo spi speed: %spi_speed% MHz
echo.
echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)
set input=default
set /p input=enter (0/1/2/3, default 0):
if %input% equ 1 (
set spi_mode=QOUT
) else (
if %input% equ 2 (
set spi_mode=DIO
) else (
if %input% equ 3 (
set spi_mode=DOUT
) else (
set spi_mode=QIO
)))
echo spi mode: %spi_mode%
echo.
echo STEP 5: choose flash size and map
echo 0= 512KB( 256KB+ 256KB)
echo 2=1024KB( 512KB+ 512KB)
echo 3=2048KB( 512KB+ 512KB)
echo 4=4096KB( 512KB+ 512KB)
echo 5=2048KB(1024KB+1024KB)
echo 6=4096KB(1024KB+1024KB)
set input=default
set /p input=enter (0/1/2/3/4/5/6, default 0):
if %input% equ 2 (
set spi_size_map=2
echo spi size: 1024KB
echo spi ota map: 512KB + 512KB
) else (
if %input% equ 3 (
set spi_size_map=3
echo spi size: 2048KB
echo spi ota map: 512KB + 512KB
) else (
if %input% equ 4 (
set spi_size_map=4
echo spi size: 4096KB
echo spi ota map: 512KB + 512KB
) else (
if %input% equ 5 (
set spi_size_map=5
echo spi size: 2048KB
echo spi ota map: 1024KB + 1024KB
) else (
if %input% equ 6 (
set spi_size_map=6
echo spi size: 4096KB
echo spi ota map: 1024KB + 1024KB
) else (
set spi_size_map=0
echo spi size: 512KB
echo spi ota map: 256KB + 256KB
)
)
)
)
)
echo.
echo start...
echo.
make clean
make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map%
:end

View File

@ -0,0 +1,176 @@
#!/bin/bash
:<<!
******NOTICE******
MUST set SDK_PATH & BIN_PATH firstly!!!
example:
export SDK_PATH=~/esp_iot_sdk_freertos
export BIN_PATH=~/esp8266_bin
!
export SDK_PATH=$SDK_PATH
export BIN_PATH=$BIN_PATH
echo "gen_misc.sh version 20150911"
echo ""
if [ $SDK_PATH ]; then
echo "SDK_PATH:"
echo "$SDK_PATH"
echo ""
else
echo "ERROR: Please export SDK_PATH in gen_misc.sh firstly, exit!!!"
exit
fi
if [ $BIN_PATH ]; then
echo "BIN_PATH:"
echo "$BIN_PATH"
echo ""
else
echo "ERROR: Please export BIN_PATH in gen_misc.sh firstly, exit!!!"
exit
fi
echo "Please check SDK_PATH & BIN_PATH, enter (Y/y) to continue:"
read input
if [[ $input != Y ]] && [[ $input != y ]]; then
exit
fi
echo ""
echo "Please follow below steps(1-5) to generate specific bin(s):"
echo "STEP 1: use boot_v1.2+ by default"
boot=new
echo "boot mode: $boot"
echo ""
echo "STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)"
echo "enter (0/1/2, default 0):"
read input
if [ -z "$input" ]; then
if [ $boot != none ]; then
boot=none
echo "ignore boot"
fi
app=0
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
elif [ $input == 1 ]; then
if [ $boot == none ]; then
app=0
echo "choose no boot before"
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
else
app=1
echo "generate bin: user1.bin"
fi
elif [ $input == 2 ]; then
if [ $boot == none ]; then
app=0
echo "choose no boot before"
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
else
app=2
echo "generate bin: user2.bin"
fi
else
if [ $boot != none ]; then
boot=none
echo "ignore boot"
fi
app=0
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
fi
echo ""
echo "STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)"
echo "enter (0/1/2/3, default 2):"
read input
if [ -z "$input" ]; then
spi_speed=40
elif [ $input == 0 ]; then
spi_speed=20
elif [ $input == 1 ]; then
spi_speed=26.7
elif [ $input == 3 ]; then
spi_speed=80
else
spi_speed=40
fi
echo "spi speed: $spi_speed MHz"
echo ""
echo "STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)"
echo "enter (0/1/2/3, default 0):"
read input
if [ -z "$input" ]; then
spi_mode=QIO
elif [ $input == 1 ]; then
spi_mode=QOUT
elif [ $input == 2 ]; then
spi_mode=DIO
elif [ $input == 3 ]; then
spi_mode=DOUT
else
spi_mode=QIO
fi
echo "spi mode: $spi_mode"
echo ""
echo "STEP 5: choose spi size and map"
echo " 0= 512KB( 256KB+ 256KB)"
echo " 2=1024KB( 512KB+ 512KB)"
echo " 3=2048KB( 512KB+ 512KB)"
echo " 4=4096KB( 512KB+ 512KB)"
echo " 5=2048KB(1024KB+1024KB)"
echo " 6=4096KB(1024KB+1024KB)"
echo "enter (0/2/3/4/5/6, default 0):"
read input
if [ -z "$input" ]; then
spi_size_map=0
echo "spi size: 512KB"
echo "spi ota map: 256KB + 256KB"
elif [ $input == 2 ]; then
spi_size_map=2
echo "spi size: 1024KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 3 ]; then
spi_size_map=3
echo "spi size: 2048KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 4 ]; then
spi_size_map=4
echo "spi size: 4096KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 5 ]; then
spi_size_map=5
echo "spi size: 2048KB"
echo "spi ota map: 1024KB + 1024KB"
elif [ $input == 6 ]; then
spi_size_map=6
echo "spi size: 4096KB"
echo "spi ota map: 1024KB + 1024KB"
else
spi_size_map=0
echo "spi size: 512KB"
echo "spi ota map: 256KB + 256KB"
fi
echo ""
echo "start..."
echo ""
make clean
make BOOT=$boot APP=$app SPI_SPEED=$spi_speed SPI_MODE=$spi_mode SPI_SIZE_MAP=$spi_size_map

View File

@ -0,0 +1,32 @@
/*
* ESPRSSIF MIT License
*
* Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __USER_CONFIG_H__
#define __USER_CONFIG_H__
#define SSID "N600"
#define PASSWORD "espressif"
#endif

View File

@ -0,0 +1,50 @@
/*
* ESPRSSIF MIT License
*
* Copyright (c) 2017 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _WIFI_STATE_MACHINE_H_
#define _WIFI_STATE_MACHINE_H_
#include <stddef.h>
#include "espressif/c_types.h"
#include "espressif/esp_wifi.h"
typedef void (* wifi_state_cb_t)();
typedef void (* wifi_disco_cb_t)(uint8_t reason);
void set_on_station_first_connect(wifi_state_cb_t cb);
void set_on_station_connect(wifi_state_cb_t cb);
void set_on_station_disconnect(wifi_disco_cb_t cb);
void set_on_client_connect(wifi_state_cb_t cb);
void set_on_client_disconnect(wifi_state_cb_t cb);
WIFI_MODE init_esp_wifi();
bool start_wifi_station(const char * ssid, const char * pass);
bool stop_wifi_station();
bool start_wifi_ap(const char * ssid, const char * pass);
bool stop_wifi_ap();
bool wifi_station_connected();
bool wifi_ap_enabled();
#endif /* _WIFI_STATE_MACHINE_H_ */

View File

@ -0,0 +1,56 @@
This is a simple project template.
sample_lib is an example for multi-level folder Makefile, notice the folder structure and each Makefile, you can get the clue.
HOWTO:
1. Copy this folder to anywhere.
Example:
Copy to ~/workspace/project_template
You can rename this folder as you like.
2. Export SDK_PATH and BIN_PATH.
Example:
Your SDK path is ~/esp_iot_rtos_sdk, and want generate bin at ~/esp8266_bin.
Do follow steps:
1>. export SDK_PATH=~/esp_iot_rtos_sdk
2>. export BIN_PATH=~/esp8266_bin
SDK and project are seperate, you can update SDK without change your project.
3. Enter project_template folder, run ./gen_misc.sh, and follow the tips and steps.
Compile Options:
(1) COMPILE
Possible value: xcc
Default value:
If not set, use gcc by default.
(2) BOOT
Possible value: none/old/new
none: no need boot
old: use boot_v1.1
new: use boot_v1.2
Default value: new
(3) APP
Possible value: 0/1/2
0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin
1: generate user1
2: generate user2
Default value: 0
(3) SPI_SPEED
Possible value: 20/26.7/40/80
Default value: 40
(4) SPI_MODE
Possible value: QIO/QOUT/DIO/DOUT
Default value: QIO
(4) SPI_SIZE_MAP
Possible value: 0/2/3/4/5/6
Default value: 0
For example:
make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0

View File

@ -0,0 +1,51 @@
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libuser.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../sample_lib/azureiot/azure-c-shared-utility/inc
INCLUDES += -I ../sample_lib/azureiot/azure-umqtt-c/inc
INCLUDES += -I ../sample_lib/azureiot/parson
INCLUDES += -I ../sample_lib/azureiot/iothub_client/inc
INCLUDES += -I ../../../include/espressif/esp8266
INCLUDES += -I ../../../include
INCLUDES += -I ../../../include/openssl
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

View File

@ -0,0 +1,111 @@
/*
* ESPRSSIF MIT License
*
* Copyright (c) 2017 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "esp_common.h"
#include "user_config.h"
static os_timer_t timer;
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 user_rf_cal_sector_set(void)
{
flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
LOCAL void ICACHE_FLASH_ATTR wait_for_connection_ready(uint8 flag)
{
os_timer_disarm(&timer);
if(wifi_station_connected()){
os_printf("connected\n");
} else {
os_printf("reconnect after 2s\n");
os_timer_setfn(&timer, (os_timer_func_t *)wait_for_connection_ready, NULL);
os_timer_arm(&timer, 2000, 0);
}
}
LOCAL void ICACHE_FLASH_ATTR on_wifi_connect(){
os_timer_disarm(&timer);
os_timer_setfn(&timer, (os_timer_func_t *)wait_for_connection_ready, NULL);
os_timer_arm(&timer, 100, 0);
}
LOCAL void ICACHE_FLASH_ATTR on_wifi_disconnect(uint8_t reason){
os_printf("disconnect %d\n", reason);
}
/******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
printf("SDK version:%s\n", system_get_sdk_version());
set_on_station_connect(on_wifi_connect);
set_on_station_disconnect(on_wifi_disconnect);
init_esp_wifi();
stop_wifi_ap();
start_wifi_station(SSID, PASSWORD);
}

View File

@ -0,0 +1,247 @@
/*
* ESPRSSIF MIT License
*
* Copyright (c) 2017 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <stddef.h>
#include "espressif/c_types.h"
#include "lwipopts.h"
#include "lwip/ip_addr.h"
#include "espressif/esp_libc.h"
#include "espressif/esp_misc.h"
#include "espressif/esp_common.h"
#include "espressif/esp_wifi.h"
#include "espressif/esp_sta.h"
#include "espressif/esp_softap.h"
#include "wifi_state_machine.h"
typedef void (* wifi_state_cb_t)();
wifi_state_cb_t on_station_first_connect = NULL;
wifi_state_cb_t on_station_connect = NULL;
wifi_disco_cb_t on_station_disconnect = NULL;
wifi_state_cb_t on_client_connect = NULL;
wifi_state_cb_t on_client_disconnect = NULL;
volatile bool wifi_station_static_ip = false;
volatile bool wifi_station_is_connected = false;
void ICACHE_FLASH_ATTR wifi_event_handler_cb(System_Event_t *event)
{
static bool station_was_connected = false;
if (event == NULL) {
return;
}
//os_printf("[WiFi] event %u\n", event->event_id);
switch (event->event_id) {
case EVENT_STAMODE_DISCONNECTED:
wifi_station_is_connected = false;
Event_StaMode_Disconnected_t *ev = (Event_StaMode_Disconnected_t *)&event->event_info;
if(on_station_disconnect){
on_station_disconnect(ev->reason);
}
break;
case EVENT_STAMODE_CONNECTED:
if(wifi_station_static_ip){
wifi_station_is_connected = true;
if(!station_was_connected){
station_was_connected = true;
if(on_station_first_connect){
on_station_first_connect();
}
}
if(on_station_connect){
on_station_connect();
}
}
break;
case EVENT_STAMODE_DHCP_TIMEOUT:
if(wifi_station_is_connected){
wifi_station_is_connected = false;
if(on_station_disconnect){
on_station_disconnect(REASON_UNSPECIFIED);
}
}
break;
case EVENT_STAMODE_GOT_IP:
wifi_station_is_connected = true;
if(!station_was_connected){
station_was_connected = true;
if(on_station_first_connect){
on_station_first_connect();
}
}
if(on_station_connect){
on_station_connect();
}
break;
case EVENT_SOFTAPMODE_STACONNECTED:
if(on_client_connect){
on_client_connect();
}
break;
case EVENT_SOFTAPMODE_STADISCONNECTED:
if(on_client_disconnect){
on_client_disconnect();
}
break;
default:
break;
}
}
void ICACHE_FLASH_ATTR set_on_station_first_connect(wifi_state_cb_t cb){
on_station_first_connect = cb;
}
void ICACHE_FLASH_ATTR set_on_station_connect(wifi_state_cb_t cb){
on_station_connect = cb;
}
void ICACHE_FLASH_ATTR set_on_station_disconnect(wifi_disco_cb_t cb){
on_station_disconnect = cb;
}
void ICACHE_FLASH_ATTR set_on_client_connect(wifi_state_cb_t cb){
on_client_connect = cb;
}
void ICACHE_FLASH_ATTR set_on_client_disconnect(wifi_state_cb_t cb){
on_client_disconnect = cb;
}
bool ICACHE_FLASH_ATTR wifi_set_mode(WIFI_MODE mode){
if(!mode){
bool s = wifi_set_opmode(mode);
wifi_fpm_open();
wifi_fpm_set_sleep_type(MODEM_SLEEP_T);
wifi_fpm_do_sleep(0xFFFFFFFF);
return s;
}
wifi_fpm_close();
return wifi_set_opmode(mode);
}
WIFI_MODE ICACHE_FLASH_ATTR init_esp_wifi(){
wifi_set_event_handler_cb(wifi_event_handler_cb);
WIFI_MODE mode = wifi_get_opmode_default();
wifi_set_mode(mode);
return mode;
}
bool ICACHE_FLASH_ATTR start_wifi_station(const char * ssid, const char * pass){
WIFI_MODE mode = wifi_get_opmode();
if((mode & STATION_MODE) == 0){
mode |= STATION_MODE;
if(!wifi_set_mode(mode)){
os_printf("Failed to enable Station mode!\n");
return false;
}
}
if(!ssid){
os_printf("No SSID Given. Will connect to the station saved in flash\n");
return true;
}
struct station_config config;
memset(&config, 0, sizeof(struct station_config));
strcpy(config.ssid, ssid);
if(pass){
strcpy(config.password, pass);
}
if(!wifi_station_set_config(&config)){
os_printf("Failed to set Station config!\n");
return false;
}
if(!wifi_station_dhcpc_status()){
os_printf("DHCP is not started. Starting it...\n");
if(!wifi_station_dhcpc_start()){
os_printf("DHCP start failed!\n");
return false;
}
}
return wifi_station_connect();
}
bool ICACHE_FLASH_ATTR stop_wifi_station(){
WIFI_MODE mode = wifi_get_opmode();
mode &= ~STATION_MODE;
if(!wifi_set_mode(mode)){
os_printf("Failed to disable Station mode!\n");
return false;
}
return true;
}
bool ICACHE_FLASH_ATTR start_wifi_ap(const char * ssid, const char * pass){
WIFI_MODE mode = wifi_get_opmode();
if((mode & SOFTAP_MODE) == 0){
mode |= SOFTAP_MODE;
if(!wifi_set_mode(mode)){
os_printf("Failed to enable AP mode!\n");
return false;
}
}
if(!ssid){
os_printf("No SSID Given. Will start the AP saved in flash\n");
return true;
}
struct softap_config config;
bzero(&config, sizeof(struct softap_config));
sprintf(config.ssid, ssid);
if(pass){
sprintf(config.password, pass);
}
return wifi_softap_set_config(&config);
}
bool ICACHE_FLASH_ATTR stop_wifi_ap(){
WIFI_MODE mode = wifi_get_opmode();
mode &= ~SOFTAP_MODE;
if(!wifi_set_mode(mode)){
os_printf("Failed to disable AP mode!\n");
return false;
}
return true;
}
bool ICACHE_FLASH_ATTR wifi_station_connected(){
if(!wifi_station_is_connected){
return false;
}
WIFI_MODE mode = wifi_get_opmode();
if((mode & STATION_MODE) == 0){
return false;
}
STATION_STATUS wifistate = wifi_station_get_connect_status();
wifi_station_is_connected = (wifistate == STATION_GOT_IP || (wifi_station_static_ip && wifistate == STATION_CONNECTING));
return wifi_station_is_connected;
}
bool ICACHE_FLASH_ATTR wifi_ap_enabled(){
return !!(wifi_get_opmode() & SOFTAP_MODE);
}