1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Merge branch 'master' into master

This commit is contained in:
Krzysztof 2016-04-28 19:13:27 +02:00
commit 986aa86f53
134 changed files with 35620 additions and 1004 deletions

3
.gitignore vendored
View File

@ -5,3 +5,6 @@ tools/esptool/
tools/mkspiffs/
package/versions/
exclude.txt
tools/sdk/lib/liblwip_src.a
tools/sdk/lwip/src/build
tools/sdk/lwip/src/liblwip_src.a

View File

@ -34,12 +34,12 @@ If you find this forum or the ESP8266 Boards Manager package useful, please cons
##### Stable version ![](http://arduino.esp8266.com/stable/badge.svg)
Boards manager link: `http://arduino.esp8266.com/stable/package_esp8266com_index.json`
Documentation: [http://esp8266.github.io/Arduino/versions/2.1.0/](http://esp8266.github.io/Arduino/versions/2.1.0/)
Documentation: [http://esp8266.github.io/Arduino/versions/2.2.0/](http://esp8266.github.io/Arduino/versions/2.2.0/)
##### Staging version ![](http://arduino.esp8266.com/staging/badge.svg)
Boards manager link: `http://arduino.esp8266.com/staging/package_esp8266com_index.json`
Documentation: [http://esp8266.github.io/Arduino/versions/2.1.0-rc2/](http://esp8266.github.io/Arduino/versions/2.1.0-rc2/)
Documentation: [http://esp8266.github.io/Arduino/versions/2.2.0-rc1/](http://esp8266.github.io/Arduino/versions/2.2.0-rc1/)
### Using git version
[![Linux build status](https://travis-ci.org/esp8266/Arduino.svg)](https://travis-ci.org/esp8266/Arduino) [![codecov.io](https://codecov.io/github/esp8266/Arduino/coverage.svg?branch=master)](https://codecov.io/github/esp8266/Arduino?branch=master)

View File

@ -7,6 +7,7 @@ menu.ResetMethod=Reset Method
menu.ESPModule=Module
menu.Debug=Debug port
menu.DebugLevel=Debug Level
menu.LwIPVariant=lwIP Variant
##############################################################
generic.name=Generic ESP8266 Module
@ -29,6 +30,8 @@ generic.build.flash_mode=qio
generic.build.spiffs_pagesize=256
generic.build.debug_port=
generic.build.debug_level=
generic.build.lwip_lib=-llwip
generic.build.lwip_flags=
generic.menu.CpuFrequency.80=80 MHz
generic.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -247,6 +250,8 @@ espduino.build.flash_size=4M
espduino.build.flash_freq=40
espduino.build.debug_port=
espduino.build.debug_level=
espduino.build.lwip_lib=-llwip
espduino.build.lwip_flags=
espduino.menu.CpuFrequency.80=80 MHz
espduino.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -310,6 +315,8 @@ huzzah.build.flash_size=4M
huzzah.build.flash_freq=40
huzzah.build.debug_port=
huzzah.build.debug_level=
huzzah.build.lwip_lib=-llwip
huzzah.build.lwip_flags=
huzzah.menu.CpuFrequency.80=80 MHz
huzzah.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -359,6 +366,8 @@ espresso_lite_v1.build.variant=espresso_lite_v1
espresso_lite_v1.build.flash_mode=dio
espresso_lite_v1.build.flash_size=4M
espresso_lite_v1.build.flash_freq=40
espresso_lite_v1.build.lwip_lib=-llwip
espresso_lite_v1.build.lwip_flags=
espresso_lite_v1.menu.CpuFrequency.80=80 MHz
espresso_lite_v1.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -464,6 +473,8 @@ espresso_lite_v2.build.variant=espresso_lite_v2
espresso_lite_v2.build.flash_mode=dio
espresso_lite_v2.build.flash_size=4M
espresso_lite_v2.build.flash_freq=40
espresso_lite_v2.build.lwip_lib=-llwip
espresso_lite_v2.build.lwip_flags=
espresso_lite_v2.menu.CpuFrequency.80=80 MHz
espresso_lite_v2.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -567,7 +578,7 @@ nodemcu.serial.disableRTS=true
nodemcu.build.mcu=esp8266
nodemcu.build.f_cpu=80000000L
nodemcu.build.board=ESP8266_ESP12
nodemcu.build.board=ESP8266_NODEMCU
nodemcu.build.core=esp8266
nodemcu.build.variant=nodemcu
nodemcu.build.flash_mode=qio
@ -575,6 +586,8 @@ nodemcu.build.flash_size=4M
nodemcu.build.flash_freq=40
nodemcu.build.debug_port=
nodemcu.build.debug_level=
nodemcu.build.lwip_lib=-llwip
nodemcu.build.lwip_flags=
nodemcu.menu.CpuFrequency.80=80 MHz
nodemcu.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -631,7 +644,7 @@ nodemcuv2.serial.disableRTS=true
nodemcuv2.build.mcu=esp8266
nodemcuv2.build.f_cpu=80000000L
nodemcuv2.build.board=ESP8266_ESP12
nodemcuv2.build.board=ESP8266_NODEMCU
nodemcuv2.build.core=esp8266
nodemcuv2.build.variant=nodemcu
nodemcuv2.build.flash_mode=dio
@ -639,6 +652,8 @@ nodemcuv2.build.flash_size=4M
nodemcuv2.build.flash_freq=40
nodemcuv2.build.debug_port=
nodemcuv2.build.debug_level=
nodemcuv2.build.lwip_lib=-llwip
nodemcuv2.build.lwip_flags=
nodemcuv2.menu.CpuFrequency.80=80 MHz
nodemcuv2.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -710,6 +725,8 @@ modwifi.build.spiffs_pagesize=256
modwifi.build.spiffs_blocksize=8192
modwifi.build.debug_port=
modwifi.build.debug_level=
modwifi.build.lwip_lib=-llwip
modwifi.build.lwip_flags=
modwifi.menu.CpuFrequency.80=80 MHz
modwifi.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -764,6 +781,8 @@ thing.build.spiffs_blocksize=4096
thing.build.spiffs_pagesize=256
thing.build.debug_port=
thing.build.debug_level=
thing.build.lwip_lib=-llwip
thing.build.lwip_flags=
thing.menu.CpuFrequency.80=80 MHz
thing.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -813,6 +832,8 @@ thingdev.build.flash_ld=eagle.flash.512k64.ld
thingdev.build.flash_freq=40
thingdev.build.debug_port=
thingdev.build.debug_level=
thingdev.build.lwip_lib=-llwip
thingdev.build.lwip_flags=
thingdev.menu.CpuFrequency.80=80 MHz
thingdev.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -860,6 +881,8 @@ esp210.build.flash_size=4M
esp210.build.flash_freq=40
esp210.build.debug_port=
esp210.build.debug_level=
esp210.build.lwip_lib=-llwip
esp210.build.lwip_flags=
esp210.menu.CpuFrequency.80=80 MHz
esp210.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -943,7 +966,7 @@ d1_mini.serial.disableRTS=true
d1_mini.build.mcu=esp8266
d1_mini.build.f_cpu=80000000L
d1_mini.build.board=ESP8266_ESP12
d1_mini.build.board=ESP8266_NODEMCU
d1_mini.build.core=esp8266
d1_mini.build.variant=d1_mini
d1_mini.build.flash_mode=dio
@ -951,6 +974,8 @@ d1_mini.build.flash_size=4M
d1_mini.build.flash_freq=40
d1_mini.build.debug_port=
d1_mini.build.debug_level=
d1_mini.build.lwip_lib=-llwip
d1_mini.build.lwip_flags=
d1_mini.menu.CpuFrequency.80=80 MHz
d1_mini.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -1009,7 +1034,7 @@ d1.serial.disableRTS=true
d1.build.mcu=esp8266
d1.build.f_cpu=80000000L
d1.build.board=ESP8266_ESP12
d1.build.board=ESP8266_NODEMCU
d1.build.core=esp8266
d1.build.variant=d1
d1.build.flash_mode=dio
@ -1017,6 +1042,8 @@ d1.build.flash_size=4M
d1.build.flash_freq=40
d1.build.debug_port=
d1.build.debug_level=
d1.build.lwip_lib=-llwip
d1.build.lwip_flags=
d1.menu.CpuFrequency.80=80 MHz
d1.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -1085,6 +1112,8 @@ espino.build.flash_freq=40
espino.build.spiffs_pagesize=256
espino.build.debug_port=
espino.build.debug_level=
espino.build.lwip_lib=-llwip
espino.build.lwip_flags=
espino.menu.CpuFrequency.80=80 MHz
espino.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -1159,6 +1188,8 @@ espinotee.build.flash_size=4M
espinotee.build.flash_freq=40
espinotee.build.debug_port=
espinotee.build.debug_level=
espinotee.build.lwip_lib=-llwip
espinotee.build.lwip_flags=
espinotee.menu.CpuFrequency.80=80 MHz
espinotee.menu.CpuFrequency.80.build.f_cpu=80000000L
@ -1218,10 +1249,12 @@ wifinfo.build.f_cpu=160000000L
wifinfo.build.core=esp8266
wifinfo.build.variant=wifinfo
wifinfo.build.flash_mode=qio
wifinfo.build.board=ESP8266_ESP12
wifinfo.build.board=ESP8266_NODEMCU
wifinfo.build.spiffs_pagesize=256
wifinfo.build.debug_port=Serial1
wifinfo.build.debug_level=Wifinfo
wifinfo.build.lwip_lib=-llwip
wifinfo.build.lwip_flags=
wifinfo.menu.Debug.Disabled=Disabled
wifinfo.menu.Debug.Disabled.build.debug_port=
@ -1332,3 +1365,221 @@ wifinfo.menu.UploadSpeed.512000.windows=512000
wifinfo.menu.UploadSpeed.512000.upload.speed=512000
wifinfo.menu.UploadSpeed.921600=921600
wifinfo.menu.UploadSpeed.921600.upload.speed=921600
##############################################################
coredev.name=Core Development Module
coredev.upload.tool=esptool
coredev.upload.speed=115200
coredev.upload.resetmethod=ck
coredev.upload.maximum_size=434160
coredev.upload.maximum_data_size=81920
coredev.upload.wait_for_upload_port=true
coredev.serial.disableDTR=true
coredev.serial.disableRTS=true
coredev.build.mcu=esp8266
coredev.build.f_cpu=80000000L
coredev.build.board=ESP8266_ESP01
coredev.build.core=esp8266
coredev.build.variant=generic
coredev.build.flash_mode=qio
coredev.build.spiffs_pagesize=256
coredev.build.debug_port=
coredev.build.debug_level=
coredev.build.lwip_lib=-llwip
coredev.build.lwip_flags=
coredev.menu.LwIPVariant.Espressif=Espressif (xcc)
coredev.menu.LwIPVariant.Espressif.build.lwip_lib=-llwip
coredev.menu.LwIPVariant.Espressif.build.lwip_flags=
coredev.menu.LwIPVariant.Prebuilt=Prebuilt Source (gcc)
coredev.menu.LwIPVariant.Prebuilt.build.lwip_lib=-llwip_gcc
coredev.menu.LwIPVariant.Prebuilt.build.lwip_flags=-DLWIP_OPEN_SRC
coredev.menu.LwIPVariant.OpenSource=Open Source (gcc)
coredev.menu.LwIPVariant.OpenSource.build.lwip_lib=-llwip_src
coredev.menu.LwIPVariant.OpenSource.build.lwip_flags=-DLWIP_OPEN_SRC
coredev.menu.LwIPVariant.OpenSource.recipe.hooks.sketch.prebuild.1.pattern=make -C "{runtime.platform.path}/tools/sdk/lwip/src" install TOOLS_PATH="{runtime.tools.xtensa-lx106-elf-gcc.path}/bin/xtensa-lx106-elf-"
coredev.menu.CpuFrequency.80=80 MHz
coredev.menu.CpuFrequency.80.build.f_cpu=80000000L
coredev.menu.CpuFrequency.160=160 MHz
coredev.menu.CpuFrequency.160.build.f_cpu=160000000L
coredev.menu.FlashFreq.40=40MHz
coredev.menu.FlashFreq.40.build.flash_freq=40
coredev.menu.FlashFreq.80=80MHz
coredev.menu.FlashFreq.80.build.flash_freq=80
coredev.menu.FlashMode.dio=DIO
coredev.menu.FlashMode.dio.build.flash_mode=dio
coredev.menu.FlashMode.qio=QIO
coredev.menu.FlashMode.qio.build.flash_mode=qio
coredev.menu.UploadSpeed.115200=115200
coredev.menu.UploadSpeed.115200.upload.speed=115200
coredev.menu.UploadSpeed.9600=9600
coredev.menu.UploadSpeed.9600.upload.speed=9600
coredev.menu.UploadSpeed.57600=57600
coredev.menu.UploadSpeed.57600.upload.speed=57600
coredev.menu.UploadSpeed.256000.windows=256000
coredev.menu.UploadSpeed.256000.upload.speed=256000
coredev.menu.UploadSpeed.230400.linux=230400
coredev.menu.UploadSpeed.230400.macosx=230400
coredev.menu.UploadSpeed.230400.upload.speed=230400
coredev.menu.UploadSpeed.460800.linux=460800
coredev.menu.UploadSpeed.460800.macosx=460800
coredev.menu.UploadSpeed.460800.upload.speed=460800
coredev.menu.UploadSpeed.512000.windows=512000
coredev.menu.UploadSpeed.512000.upload.speed=512000
coredev.menu.UploadSpeed.921600=921600
coredev.menu.UploadSpeed.921600.upload.speed=921600
coredev.menu.FlashSize.512K64=512K (64K SPIFFS)
coredev.menu.FlashSize.512K64.build.flash_size=512K
coredev.menu.FlashSize.512K64.build.flash_ld=eagle.flash.512k64.ld
coredev.menu.FlashSize.512K64.build.spiffs_start=0x6B000
coredev.menu.FlashSize.512K64.build.spiffs_end=0x7B000
coredev.menu.FlashSize.512K64.build.spiffs_blocksize=4096
coredev.menu.FlashSize.512K64.upload.maximum_size=434160
coredev.menu.FlashSize.512K128=512K (128K SPIFFS)
coredev.menu.FlashSize.512K128.build.flash_size=512K
coredev.menu.FlashSize.512K128.build.flash_ld=eagle.flash.512k128.ld
coredev.menu.FlashSize.512K128.build.spiffs_start=0x5B000
coredev.menu.FlashSize.512K128.build.spiffs_end=0x7B000
coredev.menu.FlashSize.512K128.build.spiffs_blocksize=4096
coredev.menu.FlashSize.512K128.upload.maximum_size=368624
coredev.menu.FlashSize.512K0=512K (no SPIFFS)
coredev.menu.FlashSize.512K0.build.flash_size=512K
coredev.menu.FlashSize.512K0.build.flash_ld=eagle.flash.512k0.ld
coredev.menu.FlashSize.512K0.upload.maximum_size=499696
coredev.menu.FlashSize.1M512=1M (512K SPIFFS)
coredev.menu.FlashSize.1M512.build.flash_size=1M
coredev.menu.FlashSize.1M512.build.flash_ld=eagle.flash.1m512.ld
coredev.menu.FlashSize.1M512.build.spiffs_start=0x7B000
coredev.menu.FlashSize.1M512.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M512.build.spiffs_blocksize=8192
coredev.menu.FlashSize.1M512.upload.maximum_size=499696
coredev.menu.FlashSize.1M256=1M (256K SPIFFS)
coredev.menu.FlashSize.1M256.build.flash_size=1M
coredev.menu.FlashSize.1M256.build.flash_ld=eagle.flash.1m256.ld
coredev.menu.FlashSize.1M256.build.spiffs_start=0xBB000
coredev.menu.FlashSize.1M256.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M256.build.spiffs_blocksize=4096
coredev.menu.FlashSize.1M256.upload.maximum_size=761840
coredev.menu.FlashSize.1M192=1M (192K SPIFFS)
coredev.menu.FlashSize.1M192.build.flash_size=1M
coredev.menu.FlashSize.1M192.build.flash_ld=eagle.flash.1m192.ld
coredev.menu.FlashSize.1M192.build.spiffs_start=0xCB000
coredev.menu.FlashSize.1M192.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M192.build.spiffs_blocksize=4096
coredev.menu.FlashSize.1M192.upload.maximum_size=827376
coredev.menu.FlashSize.1M160=1M (160K SPIFFS)
coredev.menu.FlashSize.1M160.build.flash_size=1M
coredev.menu.FlashSize.1M160.build.flash_ld=eagle.flash.1m160.ld
coredev.menu.FlashSize.1M160.build.spiffs_start=0xD3000
coredev.menu.FlashSize.1M160.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M160.build.spiffs_blocksize=4096
coredev.menu.FlashSize.1M160.upload.maximum_size=860144
coredev.menu.FlashSize.1M144=1M (144K SPIFFS)
coredev.menu.FlashSize.1M144.build.flash_size=1M
coredev.menu.FlashSize.1M144.build.flash_ld=eagle.flash.1m144.ld
coredev.menu.FlashSize.1M144.build.spiffs_start=0xD7000
coredev.menu.FlashSize.1M144.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M144.build.spiffs_blocksize=4096
coredev.menu.FlashSize.1M144.upload.maximum_size=876528
coredev.menu.FlashSize.1M128=1M (128K SPIFFS)
coredev.menu.FlashSize.1M128.build.flash_size=1M
coredev.menu.FlashSize.1M128.build.flash_ld=eagle.flash.1m128.ld
coredev.menu.FlashSize.1M128.build.spiffs_start=0xDB000
coredev.menu.FlashSize.1M128.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M128.build.spiffs_blocksize=4096
coredev.menu.FlashSize.1M128.upload.maximum_size=892912
coredev.menu.FlashSize.1M64=1M (64K SPIFFS)
coredev.menu.FlashSize.1M64.build.flash_size=1M
coredev.menu.FlashSize.1M64.build.flash_ld=eagle.flash.1m64.ld
coredev.menu.FlashSize.1M64.build.spiffs_start=0xEB000
coredev.menu.FlashSize.1M64.build.spiffs_end=0xFB000
coredev.menu.FlashSize.1M64.build.spiffs_blocksize=4096
coredev.menu.FlashSize.1M64.upload.maximum_size=958448
coredev.menu.FlashSize.2M=2M (1M SPIFFS)
coredev.menu.FlashSize.2M.build.flash_size=2M
coredev.menu.FlashSize.2M.build.flash_ld=eagle.flash.2m.ld
coredev.menu.FlashSize.2M.build.spiffs_start=0x100000
coredev.menu.FlashSize.2M.build.spiffs_end=0x1FB000
coredev.menu.FlashSize.2M.build.spiffs_blocksize=8192
coredev.menu.FlashSize.2M.upload.maximum_size=1044464
coredev.menu.FlashSize.4M1M=4M (1M SPIFFS)
coredev.menu.FlashSize.4M1M.build.flash_size=4M
coredev.menu.FlashSize.4M1M.build.flash_ld=eagle.flash.4m1m.ld
coredev.menu.FlashSize.4M1M.build.spiffs_start=0x300000
coredev.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000
coredev.menu.FlashSize.4M1M.build.spiffs_blocksize=8192
coredev.menu.FlashSize.4M1M.build.spiffs_pagesize=256
coredev.menu.FlashSize.4M1M.upload.maximum_size=1044464
coredev.menu.FlashSize.4M3M=4M (3M SPIFFS)
coredev.menu.FlashSize.4M3M.build.flash_size=4M
coredev.menu.FlashSize.4M3M.build.flash_ld=eagle.flash.4m.ld
coredev.menu.FlashSize.4M3M.build.spiffs_start=0x100000
coredev.menu.FlashSize.4M3M.build.spiffs_end=0x3FB000
coredev.menu.FlashSize.4M3M.build.spiffs_blocksize=8192
coredev.menu.FlashSize.4M3M.upload.maximum_size=1044464
coredev.menu.ResetMethod.ck=ck
coredev.menu.ResetMethod.ck.upload.resetmethod=ck
coredev.menu.ResetMethod.nodemcu=nodemcu
coredev.menu.ResetMethod.nodemcu.upload.resetmethod=nodemcu
coredev.menu.Debug.Disabled=Disabled
coredev.menu.Debug.Disabled.build.debug_port=
coredev.menu.Debug.Serial=Serial
coredev.menu.Debug.Serial.build.debug_port=-DDEBUG_ESP_PORT=Serial
coredev.menu.Debug.Serial1=Serial1
coredev.menu.Debug.Serial1.build.debug_port=-DDEBUG_ESP_PORT=Serial1
coredev.menu.DebugLevel.None____=None
coredev.menu.DebugLevel.None____.build.debug_level=
coredev.menu.DebugLevel.Core____=Core
coredev.menu.DebugLevel.Core____.build.debug_level=-DDEBUG_ESP_CORE
coredev.menu.DebugLevel.SSL_____=Core + SSL
coredev.menu.DebugLevel.SSL_____.build.debug_level=-DDEBUG_ESP_CORE -DDEBUG_ESP_SSL
coredev.menu.DebugLevel.SSL_MEM_=Core + SSL + TLS Mem
coredev.menu.DebugLevel.SSL_MEM_.build.debug_level=-DDEBUG_ESP_CORE -DDEBUG_ESP_SSL -DDEBUG_TLS_MEM
coredev.menu.DebugLevel.WiFic___=Core + WiFi
coredev.menu.DebugLevel.WiFic___.build.debug_level=-DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI
coredev.menu.DebugLevel.WiFi____=WiFi
coredev.menu.DebugLevel.WiFi____.build.debug_level=-DDEBUG_ESP_WIFI
coredev.menu.DebugLevel.HTTPClient=HTTPClient
coredev.menu.DebugLevel.HTTPClient.build.debug_level=-DDEBUG_ESP_HTTP_CLIENT
coredev.menu.DebugLevel.HTTPClient2=HTTPClient + SSL
coredev.menu.DebugLevel.HTTPClient2.build.debug_level=-DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_SSL
coredev.menu.DebugLevel.HTTPUpdate=HTTPUpdate
coredev.menu.DebugLevel.HTTPUpdate.build.debug_level=-DDEBUG_ESP_HTTP_UPDATE
coredev.menu.DebugLevel.HTTPUpdate2=HTTPClient + HTTPUpdate
coredev.menu.DebugLevel.HTTPUpdate2.build.debug_level=-DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_UPDATE
coredev.menu.DebugLevel.HTTPUpdate3=HTTPClient + HTTPUpdate + Updater
coredev.menu.DebugLevel.HTTPUpdate3.build.debug_level=-DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER
coredev.menu.DebugLevel.HTTPServer=HTTPServer
coredev.menu.DebugLevel.HTTPServer.build.debug_level=-DDEBUG_ESP_HTTP_SERVER
coredev.menu.DebugLevel.UPDATER=Updater
coredev.menu.DebugLevel.UPDATER.build.debug_level=-DDEBUG_ESP_UPDATER
coredev.menu.DebugLevel.OTA_____=OTA
coredev.menu.DebugLevel.OTA_____.build.debug_level=-DDEBUG_ESP_OTA
coredev.menu.DebugLevel.OTA2____=OTA + Updater
coredev.menu.DebugLevel.OTA2____.build.debug_level=-DDEBUG_ESP_OTA -DDEBUG_ESP_UPDATER
coredev.menu.DebugLevel.all_____=All
coredev.menu.DebugLevel.all_____.build.debug_level=-DDEBUG_ESP_CORE -DDEBUG_ESP_SSL -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM

View File

@ -52,10 +52,9 @@ int ICACHE_RAM_ATTR putchar(int c) {
}
int ICACHE_RAM_ATTR printf(const char* format, ...) {
int ret;
va_list arglist;
va_start(arglist, format);
ret = ets_vprintf(format, arglist);
int ret = ets_vprintf(ets_putc, format, arglist);
va_end(arglist);
return ret;
}
@ -79,7 +78,7 @@ int ICACHE_RAM_ATTR snprintf(char* buffer, size_t size, const char* format, ...)
}
int ICACHE_RAM_ATTR vprintf(const char * format, va_list arg) {
return ets_vprintf(format, arg);
return ets_vprintf(ets_putc, format, arg);
}
int ICACHE_RAM_ATTR vsnprintf(char * buffer, size_t size, const char * format, va_list arg) {

View File

@ -5,8 +5,54 @@ title: Change Log
## Current version
### Core
- Leverage realloc() in String::changeBuffer()
- Clean up core files
- Add host side tests
- Fix possible null pointer in umm_malloc
- Remove "Upload Using" option from Tools menu
- Move attachInterrupt and detachInterrupt into IRAM (#1734)
- Implement strstr_P
- Allow indefinite duration for tone()
- Fix crashes when using tone()
- Fix RF_MODE and ADC_MODE
- Move micros, delayMicroseconds, millis to IRAM (#1326)
- Fix pulseIn (#1072, #1149)
- Accept both named constant and ADC channel number in analogRead (#1766)
- Enable heap poisoning only when debug options are enabled (#1800)
- Bootloader: don't touch RTC memory if it doesn't contain a valid command (#619)
- Update SDK to 1.5.2 (#1653)
- Clean up variants, fix digitalPinHasPWM definition (#1831)
- Don't set RF mode on boot unless it was overridden
- Change build.board property for boards which renumber pins like NodeMCU (#1878)
- Fix Exception 2 when using printf or vprintf
- Add ARM tools (#269)
### Libraries
- Update axTLS to 5b4be7d
- WiFiClientSecure: implement connection timeout, fix connected method behavior
- WiFiClient: fix write behavior when connection is closed by remote side
- ESP8266HTTPServer: add font MIME types, fix #1601
- ESP8266mDNS: add client support
- Update SPIFFS to 82aeac6
- Servo: move some functions into IRAM (#1742)
- Update SoftwareSerial to version 3.1.0
- ESP8266SSDP: change templates to include deviceType
- ESP8266WebServer: handle more file types
- SPI: add CPOL setting
- ESP8266WebServer: Fix buffer overflow in ESP8266WebServer::authenticate (#1790)
- ESP8266WiFi: fix undefined behavior in WiFiServer::setNoDelay (#1695)
- Servo: use peripheral clock frequency when calculating FRC1 tick count (#1789)
- ESP8266WiFi: avoid multiple instances of INADDR_NONE
- Add LwIP binary built with gcc
- ESP8266WiFi: Allow PSK instead of passphrase in WiFiSTA::begin
- SPI: Fix SPI.transfer16() using wrong endianness
- HTTPClient: decouple transport layer handling + save some RAM
- ESP8266httpUpdate: decouple HTTPS overloads + save some RAM
- Update and move lwIP headers, add options to use different lwIP build
- ESP8266WebServer: wait for data to arrive
- ESP8266WebServer: save RAM by moving response strings to flash (#1732)
- SPI: Speed up SPI.writePattern()
### Tools

View File

@ -106,6 +106,28 @@ Opens a file. `path` should be an absolute path starting with a slash
one of "r", "w", "a", "r+", "w+", "a+". Meaning of these modes is the same as
for `fopen` C function.
r Open text file for reading. The stream is positioned at the
beginning of the file.
r+ Open for reading and writing. The stream is positioned at the
beginning of the file.
w Truncate file to zero length or create text file for writing.
The stream is positioned at the beginning of the file.
w+ Open for reading and writing. The file is created if it does
not exist, otherwise it is truncated. The stream is
positioned at the beginning of the file.
a Open for appending (writing at end of file). The file is
created if it does not exist. The stream is positioned at the
end of the file.
a+ Open for reading and appending (writing at end of file). The
file is created if it does not exist. The initial file
position for reading is at the beginning of the file, but
output is always appended to the end of the file.
Returns *File* object. To check whether the file was opened successfully, use
the boolean operator.

View File

@ -147,6 +147,8 @@ Libraries that don't rely on low-level access to AVR registers should work well.
- [DimSwitch](https://github.com/krzychb/DimSwitch) - Control electronic dimmable ballasts for fluorescent light tubes remotely as if using a wall switch.
- [Encoder](https://github.com/PaulStoffregen/Encoder) - Arduino library for rotary encoders. Version 1.4 supports ESP8266.
- [esp8266_mdns](https://github.com/mrdunk/esp8266_mdns) - mDNS queries and responses on esp8266. Or to describe it another way: An mDNS Client or Bonjour Client library for the esp8266.
- [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) - Asynchronous TCP Library for ESP8266 and ESP32/31B
- [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) - Asynchronous Web Server Library for ESP8266 and ESP32/31B
- [Homie for ESP8266](https://github.com/marvinroger/homie-esp8266) - Arduino framework for ESP8266 implementing Homie, an MQTT convention for the IoT.
- [NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) - Adafruit's NeoPixel library, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager).
- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with ESP8266. Use the "DmaDriven" or "UartDriven" branches for ESP8266. Includes HSL color support and more.
@ -163,3 +165,6 @@ Libraries that don't rely on low-level access to AVR registers should work well.
- [Adafruit-PCD8544-Nokia-5110-LCD-Library](https://github.com/WereCatf/Adafruit-PCD8544-Nokia-5110-LCD-library) - Port of the Adafruit PCD8544 - library for the ESP8266.
- [PCF8574_ESP](https://github.com/WereCatf/PCF8574_ESP) - A very simplistic library for using the PCF8574/PCF8574A I2C 8-pin GPIO-expander.
- [Dot Matrix Display Library 2](https://github.com/freetronics/DMD2) - Freetronics DMD & Generic 16 x 32 P10 style Dot Matrix Display Library
- [SdFat-beta](https://github.com/greiman/SdFat-beta) - SD-card library with support for long filenames, software- and hardware-based SPI and lots more.
- [FastLED](https://github.com/FastLED/FastLED) - a library for easily & efficiently controlling a wide variety of LED chipsets, like the Neopixel (WS2812B), DotStar, LPD8806 and many more. Includes fading, gradient, color conversion functions.
- [OLED](https://github.com/klarsys/esp8266-OLED) - a library for controlling I2C connected OLED displays. Tested with 0.96 inch OLED graphics display.

View File

@ -1,4 +1,6 @@
#ifndef LWIP_OPEN_SRC
#define LWIP_OPEN_SRC
#endif
#include <functional>
#include <WiFiUdp.h>
#include "ArduinoOTA.h"

View File

@ -1,5 +1,5 @@
name=ESP8266HTTPClient
version=1.0
version=1.1
author=Markus Sattler
maintainer=Markus Sattler
sentence=http Client for ESP8266

View File

@ -30,85 +30,119 @@
#include "ESP8266HTTPClient.h"
class TransportTraits
{
public:
virtual ~TransportTraits()
{
}
virtual std::unique_ptr<WiFiClient> create()
{
return std::unique_ptr<WiFiClient>(new WiFiClient());
}
virtual bool verify(WiFiClient& client, const char* host)
{
return true;
}
};
class TLSTraits : public TransportTraits
{
public:
TLSTraits(const String& fingerprint) :
_fingerprint(fingerprint)
{
}
std::unique_ptr<WiFiClient> create() override
{
return std::unique_ptr<WiFiClient>(new WiFiClientSecure());
}
bool verify(WiFiClient& client, const char* host) override
{
auto wcs = reinterpret_cast<WiFiClientSecure&>(client);
return wcs.verify(_fingerprint.c_str(), host);
}
protected:
String _fingerprint;
};
/**
* constractor
* constructor
*/
HTTPClient::HTTPClient() {
_tcp = NULL;
_tcps = NULL;
_port = 0;
_reuse = false;
_tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
_useHTTP10 = false;
_https = false;
_userAgent = "ESP8266HTTPClient";
_headerKeysCount = 0;
_currentHeaders = NULL;
_returnCode = 0;
_size = -1;
_canReuse = false;
_transferEncoding = HTTPC_TE_IDENTITY;
HTTPClient::HTTPClient()
{
}
/**
* deconstractor
* destructor
*/
HTTPClient::~HTTPClient() {
if(_tcps) {
_tcps->stop();
delete _tcps;
_tcps = NULL;
_tcp = NULL;
} else if(_tcp) {
HTTPClient::~HTTPClient()
{
if(_tcp) {
_tcp->stop();
delete _tcp;
_tcp = NULL;
}
if(_currentHeaders) {
delete[] _currentHeaders;
}
}
/**
* phasing the url for all needed informations
* @param url const char *
* @param httpsFingerprint const char *
*/
void HTTPClient::begin(const char *url, const char * httpsFingerprint) {
begin(String(url), String(httpsFingerprint));
void HTTPClient::clear()
{
_returnCode = 0;
_size = -1;
_headers = "";
}
bool HTTPClient::begin(String url, String httpsFingerprint)
{
_transportTraits.reset(nullptr);
_port = 443;
if (httpsFingerprint.length() == 0) {
return false;
}
if (!beginInternal(url, "https")) {
return false;
}
_transportTraits = TransportTraitsPtr(new TLSTraits(httpsFingerprint));
DEBUG_HTTPCLIENT("[HTTP-Client][begin] httpsFingerprint: %s\n", httpsFingerprint.c_str());
return true;
}
/**
* phasing the url for all needed informations
* parsing the url for all needed parameters
* @param url String
* @param httpsFingerprint String
*/
void HTTPClient::begin(String url, String httpsFingerprint) {
bool HTTPClient::begin(String url)
{
_transportTraits.reset(nullptr);
_port = 80;
if (!beginInternal(url, "http")) {
return false;
}
_transportTraits = TransportTraitsPtr(new TransportTraits());
return true;
}
bool HTTPClient::beginInternal(String url, const char* expectedProtocol)
{
DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str());
bool hasPort = false;
clear();
_httpsFingerprint = httpsFingerprint;
_returnCode = 0;
_size = -1;
_Headers = "";
String protocol;
// check for : (http: or https:
int index = url.indexOf(':');
//int index2;
bool hasPort = false;
if(index >= 0) {
protocol = url.substring(0, index);
if(index < 0) {
DEBUG_HTTPCLIENT("[HTTP-Client][begin] failed to parse protocol\n");
return false;
}
_protocol = url.substring(0, index);
url.remove(0, (index + 3)); // remove http:// or https://
index = url.indexOf('/');
@ -130,68 +164,59 @@ void HTTPClient::begin(String url, String httpsFingerprint) {
_host = host.substring(0, index); // hostname
host.remove(0, (index + 1)); // remove hostname + :
_port = host.toInt(); // get port
hasPort = true;
} else {
_host = host;
}
_url = url;
if(protocol.equalsIgnoreCase("http")) {
_https = false;
if(!hasPort) {
_port = 80;
_uri = url;
if (_protocol != expectedProtocol) {
DEBUG_HTTPCLIENT("[HTTP-Client][begin] unexpected protocol: %s, expected %s\n", _protocol.c_str(), expectedProtocol);
return false;
}
} else if(protocol.equalsIgnoreCase("https")) {
_https = true;
if(!hasPort) {
_port = 443;
}
} else {
DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
return;
DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s\n", _host.c_str(), _port, _uri.c_str());
return true;
}
}
DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s https: %d httpsFingerprint: %s\n", _host.c_str(), _port, _url.c_str(), _https, _httpsFingerprint.c_str());
}
/**
* begin
* @param host const char *
* @param port uint16_t
* @param url const char *
* @param https bool
* @param httpsFingerprint const char *
*/
void HTTPClient::begin(const char *host, uint16_t port, const char * url, bool https, const char * httpsFingerprint) {
DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port:%d url: %s https: %d httpsFingerprint: %s\n", host, port, url, https, httpsFingerprint);
bool HTTPClient::begin(String host, uint16_t port, String uri)
{
clear();
_host = host;
_port = port;
_url = url;
_https = https;
_httpsFingerprint = httpsFingerprint;
_returnCode = 0;
_size = -1;
_Headers = "";
_uri = uri;
_transportTraits = TransportTraitsPtr(new TransportTraits());
DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d uri: %s\n", host.c_str(), port, uri.c_str());
return true;
}
void HTTPClient::begin(String host, uint16_t port, String url, bool https, String httpsFingerprint) {
begin(host.c_str(), port, url.c_str(), https, httpsFingerprint.c_str());
bool HTTPClient::begin(String host, uint16_t port, String uri, bool https, String httpsFingerprint)
{
if (https) {
return begin(host, port, uri, httpsFingerprint);
} else {
return begin(host, port, uri);
}
}
bool HTTPClient::begin(String host, uint16_t port, String uri, String httpsFingerprint)
{
clear();
_host = host;
_port = port;
_uri = uri;
if (httpsFingerprint.length() == 0) {
return false;
}
_transportTraits = TransportTraitsPtr(new TLSTraits(httpsFingerprint));
DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s httpsFingerprint: %s\n", host.c_str(), port, uri.c_str(), httpsFingerprint.c_str());
return true;
}
/**
* end
* called after the payload is handled
*/
void HTTPClient::end(void) {
void HTTPClient::end(void)
{
if(connected()) {
if(_tcp->available() > 0) {
DEBUG_HTTPCLIENT("[HTTP-Client][end] still data in buffer (%d), clean up.\n", _tcp->available());
@ -214,7 +239,8 @@ void HTTPClient::end(void) {
* connected
* @return connected status
*/
bool HTTPClient::connected() {
bool HTTPClient::connected()
{
if(_tcp) {
return (_tcp->connected() || (_tcp->available() > 0));
}
@ -226,7 +252,8 @@ bool HTTPClient::connected() {
* keep-alive
* @param reuse bool
*/
void HTTPClient::setReuse(bool reuse) {
void HTTPClient::setReuse(bool reuse)
{
_reuse = reuse;
}
@ -234,7 +261,8 @@ void HTTPClient::setReuse(bool reuse) {
* set User Agent
* @param userAgent const char *
*/
void HTTPClient::setUserAgent(const char * userAgent) {
void HTTPClient::setUserAgent(const String& userAgent)
{
_userAgent = userAgent;
}
@ -243,7 +271,8 @@ void HTTPClient::setUserAgent(const char * userAgent) {
* @param user const char *
* @param password const char *
*/
void HTTPClient::setAuthorization(const char * user, const char * password) {
void HTTPClient::setAuthorization(const char * user, const char * password)
{
if(user && password) {
String auth = user;
auth += ":";
@ -256,7 +285,8 @@ void HTTPClient::setAuthorization(const char * user, const char * password) {
* set the Authorizatio for the http request
* @param auth const char * base64
*/
void HTTPClient::setAuthorization(const char * auth) {
void HTTPClient::setAuthorization(const char * auth)
{
if(auth) {
_base64Authorization = auth;
}
@ -266,7 +296,8 @@ void HTTPClient::setAuthorization(const char * auth) {
* set the timeout for the TCP connection
* @param timeout unsigned int
*/
void HTTPClient::setTimeout(uint16_t timeout) {
void HTTPClient::setTimeout(uint16_t timeout)
{
_tcpTimeout = timeout;
if(connected()) {
_tcp->setTimeout(timeout);
@ -277,7 +308,8 @@ void HTTPClient::setTimeout(uint16_t timeout) {
* use HTTP1.0
* @param timeout
*/
void HTTPClient::useHTTP10(bool useHTTP10) {
void HTTPClient::useHTTP10(bool useHTTP10)
{
_useHTTP10 = useHTTP10;
}
@ -285,7 +317,8 @@ void HTTPClient::useHTTP10(bool useHTTP10) {
* send a GET request
* @return http code
*/
int HTTPClient::GET() {
int HTTPClient::GET()
{
return sendRequest("GET");
}
@ -295,11 +328,13 @@ int HTTPClient::GET() {
* @param size size_t
* @return http code
*/
int HTTPClient::POST(uint8_t * payload, size_t size) {
int HTTPClient::POST(uint8_t * payload, size_t size)
{
return sendRequest("POST", payload, size);
}
int HTTPClient::POST(String payload) {
int HTTPClient::POST(String payload)
{
return POST((uint8_t *) payload.c_str(), payload.length());
}
@ -309,7 +344,8 @@ int HTTPClient::POST(String payload) {
* @param payload String data for the message body
* @return
*/
int HTTPClient::sendRequest(const char * type, String payload) {
int HTTPClient::sendRequest(const char * type, String payload)
{
return sendRequest(type, (uint8_t *) payload.c_str(), payload.length());
}
@ -320,14 +356,15 @@ int HTTPClient::sendRequest(const char * type, String payload) {
* @param size size_t size for the message body if 0 not send
* @return -1 if no info or > 0 when Content-Length is set by server
*/
int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size)
{
// connect to server
if(!connect()) {
return returnError(HTTPC_ERROR_CONNECTION_REFUSED);
}
if(payload && size > 0) {
addHeader("Content-Length", String(size));
addHeader(F("Content-Length"), String(size));
}
// send Header
@ -353,7 +390,8 @@ int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
* @param size size_t size for the message body if 0 not Content-Length is send
* @return -1 if no info or > 0 when Content-Length is set by server
*/
int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size)
{
if(!stream) {
return returnError(HTTPC_ERROR_NO_STREAM);
@ -468,7 +506,8 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
free(buff);
if(size && (int) size != bytesWritten) {
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, size); DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!");
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, size);
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!");
return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED);
} else {
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload written: %d\n", bytesWritten);
@ -487,36 +526,38 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
* size of message body / payload
* @return -1 if no info or > 0 when Content-Length is set by server
*/
int HTTPClient::getSize(void) {
int HTTPClient::getSize(void)
{
return _size;
}
/**
* deprecated Note: this is not working with https!
* returns the stream of the tcp connection
* @return WiFiClient
*/
WiFiClient & HTTPClient::getStream(void) {
WiFiClient& HTTPClient::getStream(void)
{
if(connected()) {
return *_tcp;
}
DEBUG_HTTPCLIENT("[HTTP-Client] no stream to return!?\n");
// todo return error?
DEBUG_HTTPCLIENT("[HTTP-Client] getStream: not connected\n");
static WiFiClient empty;
return empty;
}
/**
* returns the stream of the tcp connection
* @return WiFiClient *
*/
WiFiClient * HTTPClient::getStreamPtr(void) {
WiFiClient* HTTPClient::getStreamPtr(void)
{
if(connected()) {
return _tcp;
return _tcp.get();
}
DEBUG_HTTPCLIENT("[HTTP-Client] no stream to return!?\n");
return NULL;
DEBUG_HTTPCLIENT("[HTTP-Client] getStreamPtr: not connected\n");
return nullptr;
}
/**
@ -524,7 +565,8 @@ WiFiClient * HTTPClient::getStreamPtr(void) {
* @param stream Stream *
* @return bytes written ( negative values are error codes )
*/
int HTTPClient::writeToStream(Stream * stream) {
int HTTPClient::writeToStream(Stream * stream)
{
if(!stream) {
return returnError(HTTPC_ERROR_NO_STREAM);
@ -586,6 +628,13 @@ int HTTPClient::writeToStream(Stream * stream) {
break;
}
// read trailing \r\n at the end of the chunk
char buf[2];
auto trailing_seq_len = _tcp->readBytes((uint8_t*)buf, 2);
if (trailing_seq_len != 2 || buf[0] != '\r' || buf[1] != '\n') {
return returnError(HTTPC_ERROR_READ_TIMEOUT);
}
delay(0);
}
} else {
@ -600,14 +649,15 @@ int HTTPClient::writeToStream(Stream * stream) {
* return all payload as String (may need lot of ram or trigger out of memory!)
* @return String
*/
String HTTPClient::getString(void) {
String HTTPClient::getString(void)
{
StreamString sstring;
if(_size) {
// try to reserve needed memmory
if(!sstring.reserve((_size + 1))) {
DEBUG_HTTPCLIENT("[HTTP-Client][getString] too less memory to reserve as string! need: %d\n", (_size + 1));
return String("--too less memory--");
DEBUG_HTTPCLIENT("[HTTP-Client][getString] not enough memory to reserve a string! need: %d\n", (_size + 1));
return "";
}
}
@ -620,30 +670,31 @@ String HTTPClient::getString(void) {
* @param error int
* @return String
*/
String HTTPClient::errorToString(int error) {
String HTTPClient::errorToString(int error)
{
switch(error) {
case HTTPC_ERROR_CONNECTION_REFUSED:
return String("connection refused");
return F("connection refused");
case HTTPC_ERROR_SEND_HEADER_FAILED:
return String("send header failed");
return F("send header failed");
case HTTPC_ERROR_SEND_PAYLOAD_FAILED:
return String("send payload failed");
return F("send payload failed");
case HTTPC_ERROR_NOT_CONNECTED:
return String("not connected");
return F("not connected");
case HTTPC_ERROR_CONNECTION_LOST:
return String("connection lost");
return F("connection lost");
case HTTPC_ERROR_NO_STREAM:
return String("no stream");
return F("no stream");
case HTTPC_ERROR_NO_HTTP_SERVER:
return String("no HTTP server");
return F("no HTTP server");
case HTTPC_ERROR_TOO_LESS_RAM:
return String("too less ram");
return F("too less ram");
case HTTPC_ERROR_ENCODING:
return String("Transfer-Encoding not supported");
return F("Transfer-Encoding not supported");
case HTTPC_ERROR_STREAM_WRITE:
return String("Stream write error");
return F("Stream write error");
case HTTPC_ERROR_READ_TIMEOUT:
return String("read Timeout");
return F("read Timeout");
default:
return String();
}
@ -655,63 +706,78 @@ String HTTPClient::errorToString(int error) {
* @param value
* @param first
*/
void HTTPClient::addHeader(const String& name, const String& value, bool first) {
void HTTPClient::addHeader(const String& name, const String& value, bool first)
{
// not allow set of Header handled by code
if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host") && !(_base64Authorization.length() && name.equalsIgnoreCase("Authorization"))) {
if(!name.equalsIgnoreCase(F("Connection")) &&
!name.equalsIgnoreCase(F("User-Agent")) &&
!name.equalsIgnoreCase(F("Host")) &&
!(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())){
String headerLine = name;
headerLine += ": ";
headerLine += value;
headerLine += "\r\n";
if(first) {
_Headers = headerLine + _Headers;
_headers = headerLine + _headers;
} else {
_Headers += headerLine;
_headers += headerLine;
}
}
}
void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount)
{
_headerKeysCount = headerKeysCount;
if(_currentHeaders)
if(_currentHeaders) {
delete[] _currentHeaders;
}
_currentHeaders = new RequestArgument[_headerKeysCount];
for(size_t i = 0; i < _headerKeysCount; i++) {
_currentHeaders[i].key = headerKeys[i];
}
}
String HTTPClient::header(const char* name) {
String HTTPClient::header(const char* name)
{
for(size_t i = 0; i < _headerKeysCount; ++i) {
if(_currentHeaders[i].key == name)
if(_currentHeaders[i].key == name) {
return _currentHeaders[i].value;
}
}
return String();
}
String HTTPClient::header(size_t i)
{
if(i < _headerKeysCount) {
return _currentHeaders[i].value;
}
return String();
}
String HTTPClient::header(size_t i) {
if(i < _headerKeysCount)
return _currentHeaders[i].value;
return String();
}
String HTTPClient::headerName(size_t i) {
if(i < _headerKeysCount)
String HTTPClient::headerName(size_t i)
{
if(i < _headerKeysCount) {
return _currentHeaders[i].key;
}
return String();
}
int HTTPClient::headers() {
int HTTPClient::headers()
{
return _headerKeysCount;
}
bool HTTPClient::hasHeader(const char* name) {
bool HTTPClient::hasHeader(const char* name)
{
for(size_t i = 0; i < _headerKeysCount; ++i) {
if((_currentHeaders[i].key == name) && (_currentHeaders[i].value.length() > 0))
if((_currentHeaders[i].key == name) && (_currentHeaders[i].value.length() > 0)) {
return true;
}
}
return false;
}
@ -719,7 +785,8 @@ bool HTTPClient::hasHeader(const char* name) {
* init TCP connection and handle ssl verify if needed
* @return true if connection is ok
*/
bool HTTPClient::connect(void) {
bool HTTPClient::connect(void)
{
if(connected()) {
DEBUG_HTTPCLIENT("[HTTP-Client] connect. already connected, try reuse!\n");
@ -729,24 +796,13 @@ bool HTTPClient::connect(void) {
return true;
}
if(_https) {
DEBUG_HTTPCLIENT("[HTTP-Client] connect https...\n");
if(_tcps) {
delete _tcps;
_tcps = NULL;
_tcp = NULL;
}
_tcps = new WiFiClientSecure();
_tcp = _tcps;
} else {
DEBUG_HTTPCLIENT("[HTTP-Client] connect http...\n");
if(_tcp) {
delete _tcp;
_tcp = NULL;
}
_tcp = new WiFiClient();
if (!_transportTraits) {
DEBUG_HTTPCLIENT("[HTTP-Client] connect: HTTPClient::begin was not called or returned error\n");
return false;
}
_tcp = _transportTraits->create();
if(!_tcp->connect(_host.c_str(), _port)) {
DEBUG_HTTPCLIENT("[HTTP-Client] failed connect to %s:%u\n", _host.c_str(), _port);
return false;
@ -754,15 +810,11 @@ bool HTTPClient::connect(void) {
DEBUG_HTTPCLIENT("[HTTP-Client] connected to %s:%u\n", _host.c_str(), _port);
if(_https && _httpsFingerprint.length() > 0) {
if(_tcps->verify(_httpsFingerprint.c_str(), _host.c_str())) {
DEBUG_HTTPCLIENT("[HTTP-Client] https certificate matches\n");
} else {
DEBUG_HTTPCLIENT("[HTTP-Client] https certificate doesn't match!\n");
if (!_transportTraits->verify(*_tcp, _host.c_str())) {
DEBUG_HTTPCLIENT("[HTTP-Client] transport level verify failed\n");
_tcp->stop();
return false;
}
}
// set Timeout for readBytesUntil and readStringUntil
_tcp->setTimeout(_tcpTimeout);
@ -778,12 +830,13 @@ bool HTTPClient::connect(void) {
* @param type (GET, POST, ...)
* @return status
*/
bool HTTPClient::sendHeader(const char * type) {
bool HTTPClient::sendHeader(const char * type)
{
if(!connected()) {
return false;
}
String header = String(type) + " " + _url + " HTTP/1.";
String header = String(type) + " " + _uri + F(" HTTP/1.");
if(_useHTTP10) {
header += "0";
@ -791,36 +844,38 @@ bool HTTPClient::sendHeader(const char * type) {
header += "1";
}
header += "\r\n"
"Host: " + _host + "\r\n"
"User-Agent: " + _userAgent + "\r\n"
"Connection: ";
header += String(F("\r\nHost: ")) + _host +
F("\r\nUser-Agent: ") + _userAgent +
F("\r\nConnection: ");
if(_reuse) {
header += "keep-alive";
header += F("keep-alive");
} else {
header += "close";
header += F("close");
}
header += "\r\n";
if(!_useHTTP10) {
header += "Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n";
header += F("Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n");
}
if(_base64Authorization.length()) {
header += "Authorization: Basic " + _base64Authorization + "\r\n";
header += F("Authorization: Basic ");
header += _base64Authorization;
header += "\r\n";
}
header += _Headers + "\r\n";
header += _headers + "\r\n";
return (_tcp->write(header.c_str(), header.length()) == header.length());
return (_tcp->write((const uint8_t *) header.c_str(), header.length()) == header.length());
}
/**
* reads the response from the server
* @return int http code
*/
int HTTPClient::handleHeaderResponse() {
int HTTPClient::handleHeaderResponse()
{
if(!connected()) {
return HTTPC_ERROR_NOT_CONNECTED;
@ -911,7 +966,8 @@ int HTTPClient::handleHeaderResponse() {
* @param size int
* @return < 0 = error >= 0 = size written
*/
int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) {
int HTTPClient::writeToStreamDataBlock(Stream * stream, int size)
{
int buff_size = HTTP_TCP_BUFFER_SIZE;
int len = size;
int bytesWritten = 0;
@ -1021,7 +1077,8 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) {
* @param error
* @return error
*/
int HTTPClient::returnError(int error) {
int HTTPClient::returnError(int error)
{
if(error < 0) {
DEBUG_HTTPCLIENT("[HTTP-Client][returnError] error(%d): %s\n", error, errorToString(error).c_str());
if(connected()) {

View File

@ -25,6 +25,10 @@
#ifndef ESP8266HTTPClient_H_
#define ESP8266HTTPClient_H_
#include <memory>
#include <Arduino.h>
#include <WiFiClient.h>
#ifdef DEBUG_ESP_HTTP_CLIENT
#ifdef DEBUG_ESP_PORT
#define DEBUG_HTTPCLIENT(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ )
@ -120,23 +124,28 @@ typedef enum {
HTTPC_TE_CHUNKED
} transferEncoding_t;
class HTTPClient {
class TransportTraits;
typedef std::unique_ptr<TransportTraits> TransportTraitsPtr;
class HTTPClient
{
public:
HTTPClient();
~HTTPClient();
void begin(const char *url, const char * httpsFingerprint = "");
void begin(String url, String httpsFingerprint = "");
void begin(const char *host, uint16_t port, const char * url = "/", bool https = false, const char * httpsFingerprint = "");
void begin(String host, uint16_t port, String url = "/", bool https = false, String httpsFingerprint = "");
bool begin(String url);
bool begin(String url, String httpsFingerprint);
bool begin(String host, uint16_t port, String uri = "/");
bool begin(String host, uint16_t port, String uri, String httpsFingerprint);
// deprecated, use the overload above instead
bool begin(String host, uint16_t port, String uri, bool https, String httpsFingerprint) __attribute__ ((deprecated));
void end(void);
bool connected(void);
void setReuse(bool reuse); /// keep-alive
void setUserAgent(const char * userAgent);
void setUserAgent(const String& userAgent);
void setAuthorization(const char * user, const char * password);
void setAuthorization(const char * auth);
void setTimeout(uint16_t timeout);
@ -164,7 +173,7 @@ class HTTPClient {
int getSize(void);
WiFiClient & getStream(void) __attribute__ ((deprecated)) ;
WiFiClient& getStream(void);
WiFiClient* getStreamPtr(void);
int writeToStream(Stream* stream);
String getString(void);
@ -172,45 +181,44 @@ class HTTPClient {
static String errorToString(int error);
protected:
struct RequestArgument {
String key;
String value;
};
WiFiClient * _tcp;
WiFiClientSecure * _tcps;
/// request handling
String _host;
uint16_t _port;
bool _reuse;
uint16_t _tcpTimeout;
bool _useHTTP10;
String _url;
bool _https;
String _httpsFingerprint;
String _Headers;
String _userAgent;
String _base64Authorization;
/// Response handling
RequestArgument* _currentHeaders;
size_t _headerKeysCount;
int _returnCode;
int _size;
bool _canReuse;
transferEncoding_t _transferEncoding;
bool beginInternal(String url, const char* expectedProtocol);
void clear();
int returnError(int error);
bool connect(void);
bool sendHeader(const char * type);
int handleHeaderResponse();
int writeToStreamDataBlock(Stream * stream, int len);
TransportTraitsPtr _transportTraits;
std::unique_ptr<WiFiClient> _tcp;
/// request handling
String _host;
uint16_t _port = 0;
bool _reuse = false;
uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _useHTTP10 = false;
String _uri;
String _protocol;
String _headers;
String _userAgent = "ESP8266HTTPClient";
String _base64Authorization;
/// Response handling
RequestArgument* _currentHeaders = nullptr;
size_t _headerKeysCount = 0;
int _returnCode = 0;
int _size = -1;
bool _canReuse = false;
transferEncoding_t _transferEncoding = HTTPC_TE_IDENTITY;
};

View File

@ -487,48 +487,48 @@ void ESP8266WebServer::_handleRequest() {
_currentUri = String();
}
const char* ESP8266WebServer::_responseCodeToString(int code) {
String ESP8266WebServer::_responseCodeToString(int code) {
switch (code) {
case 100: return "Continue";
case 101: return "Switching Protocols";
case 200: return "OK";
case 201: return "Created";
case 202: return "Accepted";
case 203: return "Non-Authoritative Information";
case 204: return "No Content";
case 205: return "Reset Content";
case 206: return "Partial Content";
case 300: return "Multiple Choices";
case 301: return "Moved Permanently";
case 302: return "Found";
case 303: return "See Other";
case 304: return "Not Modified";
case 305: return "Use Proxy";
case 307: return "Temporary Redirect";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 402: return "Payment Required";
case 403: return "Forbidden";
case 404: return "Not Found";
case 405: return "Method Not Allowed";
case 406: return "Not Acceptable";
case 407: return "Proxy Authentication Required";
case 408: return "Request Time-out";
case 409: return "Conflict";
case 410: return "Gone";
case 411: return "Length Required";
case 412: return "Precondition Failed";
case 413: return "Request Entity Too Large";
case 414: return "Request-URI Too Large";
case 415: return "Unsupported Media Type";
case 416: return "Requested range not satisfiable";
case 417: return "Expectation Failed";
case 500: return "Internal Server Error";
case 501: return "Not Implemented";
case 502: return "Bad Gateway";
case 503: return "Service Unavailable";
case 504: return "Gateway Time-out";
case 505: return "HTTP Version not supported";
case 100: return F("Continue");
case 101: return F("Switching Protocols");
case 200: return F("OK");
case 201: return F("Created");
case 202: return F("Accepted");
case 203: return F("Non-Authoritative Information");
case 204: return F("No Content");
case 205: return F("Reset Content");
case 206: return F("Partial Content");
case 300: return F("Multiple Choices");
case 301: return F("Moved Permanently");
case 302: return F("Found");
case 303: return F("See Other");
case 304: return F("Not Modified");
case 305: return F("Use Proxy");
case 307: return F("Temporary Redirect");
case 400: return F("Bad Request");
case 401: return F("Unauthorized");
case 402: return F("Payment Required");
case 403: return F("Forbidden");
case 404: return F("Not Found");
case 405: return F("Method Not Allowed");
case 406: return F("Not Acceptable");
case 407: return F("Proxy Authentication Required");
case 408: return F("Request Time-out");
case 409: return F("Conflict");
case 410: return F("Gone");
case 411: return F("Length Required");
case 412: return F("Precondition Failed");
case 413: return F("Request Entity Too Large");
case 414: return F("Request-URI Too Large");
case 415: return F("Unsupported Media Type");
case 416: return F("Requested range not satisfiable");
case 417: return F("Expectation Failed");
case 500: return F("Internal Server Error");
case 501: return F("Not Implemented");
case 502: return F("Bad Gateway");
case 503: return F("Service Unavailable");
case 504: return F("Gateway Time-out");
case 505: return F("HTTP Version not supported");
default: return "";
}
}

View File

@ -34,6 +34,7 @@ enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
#define HTTP_DOWNLOAD_UNIT_SIZE 1460
#define HTTP_UPLOAD_BUFLEN 2048
#define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
#define HTTP_MAX_POST_WAIT 1000 //ms to wait for POST data to arrive
#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
@ -133,7 +134,7 @@ protected:
void _handleRequest();
bool _parseRequest(WiFiClient& client);
void _parseArguments(String data);
static const char* _responseCodeToString(int code);
static String _responseCodeToString(int code);
bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
bool _parseFormUploadAborted();
void _uploadWriteByte(uint8_t b);

View File

@ -31,6 +31,38 @@
#define DEBUG_OUTPUT Serial
#endif
static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& dataLength, int timeout_ms)
{
char *buf = nullptr;
dataLength = 0;
while (dataLength < maxLength) {
int tries = timeout_ms;
size_t newLength;
while (!(newLength = client.available()) && tries--) delay(1);
if (!newLength) {
break;
}
if (!buf) {
buf = (char *) malloc(newLength + 1);
if (!buf) {
return nullptr;
}
}
else {
char* newBuf = (char *) realloc(buf, dataLength + newLength + 1);
if (!newBuf) {
free(buf);
return nullptr;
}
buf = newBuf;
}
client.readBytes(buf + dataLength, newLength);
dataLength += newLength;
buf[dataLength] = '\0';
}
return buf;
}
bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
@ -137,19 +169,18 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
}
if (!isForm){
if (searchStr != "") searchStr += '&';
//some clients send headers first and data after (like we do)
//give them a chance
int tries = 100;//100ms max wait
while(!client.available() && tries--)delay(1);
size_t plainLen = client.available();
char *plainBuf = (char*)malloc(plainLen+1);
client.readBytes(plainBuf, plainLen);
plainBuf[plainLen] = '\0';
size_t plainLength;
char* plainBuf = readBytesWithTimeout(client, contentLength, plainLength, HTTP_MAX_POST_WAIT);
if (plainLength < contentLength) {
free(plainBuf);
return false;
}
#ifdef DEBUG_ESP_HTTP_SERVER
DEBUG_OUTPUT.print("Plain: ");
DEBUG_OUTPUT.println(plainBuf);
#endif
if (contentLength > 0) {
if (searchStr != "") searchStr += '&';
if(plainBuf[0] == '{' || plainBuf[0] == '[' || strstr(plainBuf, "=") == NULL){
//plain post json or other data
searchStr += "plain=";
@ -159,6 +190,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
}
free(plainBuf);
}
}
_parseArguments(searchStr);
if (isForm){
if (!_parseForm(client, boundaryStr, contentLength)) {

View File

@ -89,13 +89,13 @@ bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int ch
return false;
}
if(!ssid || *ssid == 0 || strlen(ssid) > 31) {
if(!ssid || strlen(ssid) == 0 || strlen(ssid) > 31) {
// fail SSID too long or missing!
DEBUG_WIFI("[AP] SSID too long or missing!\n");
return false;
}
if(passphrase && (strlen(passphrase) > 63 || strlen(passphrase) < 8)) {
if(passphrase && strlen(passphrase) > 0 && (strlen(passphrase) > 63 || strlen(passphrase) < 8)) {
// fail passphrase to long or short!
DEBUG_WIFI("[AP] fail passphrase to long or short!\n");
return false;

View File

@ -1,6 +1,6 @@
/*
ESP8266WiFiAP.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Based on WiFi.h from Arduino WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 2015

View File

@ -106,7 +106,7 @@ wl_status_t ESP8266WiFiSTAClass::begin(const char* ssid, const char *passphrase,
return WL_CONNECT_FAILED;
}
if(passphrase && strlen(passphrase) > 63) {
if(passphrase && strlen(passphrase) > 64) {
// fail passphrase too long!
return WL_CONNECT_FAILED;
}
@ -115,6 +115,9 @@ wl_status_t ESP8266WiFiSTAClass::begin(const char* ssid, const char *passphrase,
strcpy(reinterpret_cast<char*>(conf.ssid), ssid);
if(passphrase) {
if (strlen(passphrase) == 64) // it's not a passphrase, is the PSK
memcpy(reinterpret_cast<char*>(conf.password), passphrase, 64);
else
strcpy(reinterpret_cast<char*>(conf.password), passphrase);
} else {
*conf.password = 0;

View File

@ -93,8 +93,8 @@ public:
}
}
void connect(ClientContext* ctx, uint32_t timeout_ms) {
_ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0);
void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms) {
_ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0, hostName);
uint32_t t = millis();
while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) {
@ -242,16 +242,21 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port) {
if (!WiFiClient::connect(ip, port))
return 0;
return _connectSSL();
return _connectSSL(nullptr);
}
int WiFiClientSecure::connect(const char* name, uint16_t port) {
if (!WiFiClient::connect(name, port))
IPAddress remote_addr;
if (!WiFi.hostByName(name, remote_addr)) {
return 0;
return 1;
}
if (!WiFiClient::connect(remote_addr, port)) {
return 0;
}
return _connectSSL(name);
}
int WiFiClientSecure::_connectSSL() {
int WiFiClientSecure::_connectSSL(const char* hostName) {
if (_ssl) {
_ssl->unref();
_ssl = nullptr;
@ -259,7 +264,7 @@ int WiFiClientSecure::_connectSSL() {
_ssl = new SSLContext;
_ssl->ref();
_ssl->connect(_client, 5000);
_ssl->connect(_client, hostName, 5000);
auto status = ssl_handshake_status(*_ssl);
if (status != SSL_OK) {

View File

@ -66,7 +66,7 @@ public:
}
protected:
int _connectSSL();
int _connectSSL(const char* hostName);
SSLContext* _ssl = nullptr;
};

View File

@ -213,7 +213,7 @@ public:
return size;
}
char peek()
int peek()
{
if (!_rx_buf || _rx_buf_offset == _rx_buf->len)
return -1;

View File

@ -243,10 +243,11 @@ EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
* can be null if no session resumption is being used or required. This option
* is not used in skeleton mode.
* @param sess_id_size The size of the session id (max 32)
* @param host_name If non-zero, host name to be sent to server for SNI support
* @return An SSL object reference. Use ssl_handshake_status() to check
* if a handshake succeeded.
*/
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size);
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, const char* host_name);
/**
* @brief Free any used resources on this connection.

View File

@ -1,81 +0,0 @@
#ifndef __MEM_MANAGER_H__
#define __MEM_MANAGER_H__
#include "c_types.h"
/*------------------------<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>------------------------*/
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#ifndef IOT_SIP_MODE
//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0x3fffc000 - (uint32)&_heap_start ) )//fix 16000 to 24000 on 14.2.26
#else
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 8000 ) )
#endif
#define portBYTE_ALIGNMENT 8
#define pdFALSE 0
#define pdTRUE 1
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if portBYTE_ALIGNMENT == 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
#endif
#if portBYTE_ALIGNMENT == 4
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
#endif
#if portBYTE_ALIGNMENT == 2
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
#endif
#if portBYTE_ALIGNMENT == 1
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
#endif
#ifndef portBYTE_ALIGNMENT_MASK
#error "Invalid portBYTE_ALIGNMENT definition"
#endif
#define configUSE_MALLOC_FAILED_HOOK 1
#define portPOINTER_SIZE_TYPE unsigned int
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
//#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
//static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
//static unsigned char *ucHeap;
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; //The next free block in the list.
size_t xBlockSize; //The size of the free block.
} xBlockLink;
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
//static const size_t xTotalHeapSize = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
//static xBlockLink xStart, *pxEnd = NULL;
//static size_t xFreeBytesRemaining = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
/*------------------------<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-----------------------------------*/
//static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ) ;//ICACHE_FLASH_ATTR;
//static void prvHeapInit( void ) ;//ICACHE_FLASH_ATTR;
void vApplicationMallocFailedHook( void ) ;//ICACHE_FLASH_ATTR;
void *pvPortMalloc( size_t xWantedSize, const char* file, int line ) __attribute__((malloc, alloc_size(1)));//ICACHE_FLASH_ATTR;
void vPortFree( void *pv, const char* file, int line ) ;//ICACHE_FLASH_ATTR;
size_t xPortGetFreeHeapSize( void ) ;//ICACHE_FLASH_ATTR;
void vPortInitialiseBlocks( void ) ;//ICACHE_FLASH_ATTR;
/*-----------------------------------------------------------*/
#endif

View File

@ -1,5 +1,5 @@
name=ESP8266httpUpdate
version=1.0
version=1.1
author=Markus Sattler
maintainer=Markus Sattler
sentence=Http Update for ESP8266

View File

@ -29,107 +29,127 @@
extern "C" uint32_t _SPIFFS_start;
extern "C" uint32_t _SPIFFS_end;
ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) {
ESP8266HTTPUpdate::ESP8266HTTPUpdate(void)
{
}
ESP8266HTTPUpdate::~ESP8266HTTPUpdate(void) {
ESP8266HTTPUpdate::~ESP8266HTTPUpdate(void)
{
}
/**
*
* @param url const char *
* @param current_version const char *
* @param httpsFingerprint const char *
* @return t_httpUpdate_return
*/
t_httpUpdate_return ESP8266HTTPUpdate::update(const char * url, const char * current_version, const char * httpsFingerprint, bool reboot) {
HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion,
const String& httpsFingerprint, bool reboot)
{
rebootOnUpdate(reboot);
return update(url, currentVersion, httpsFingerprint);
}
HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion)
{
HTTPClient http;
http.begin(url);
return handleUpdate(http, currentVersion, false);
}
HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion,
const String& httpsFingerprint)
{
HTTPClient http;
http.begin(url, httpsFingerprint);
return handleUpdate(&http, current_version, reboot, false);
return handleUpdate(http, currentVersion, false);
}
/**
*
* @param url const char *
* @param current_version const char *
* @param httpsFingerprint const char *
* @return t_httpUpdate_return
*/
t_httpUpdate_return ESP8266HTTPUpdate::updateSpiffs(const char * url, const char * current_version, const char * httpsFingerprint, bool reboot) {
HTTPUpdateResult ESP8266HTTPUpdate::updateSpiffs(const String& url, const String& currentVersion, const String& httpsFingerprint)
{
HTTPClient http;
http.begin(url, httpsFingerprint);
return handleUpdate(&http, current_version, reboot, true);
return handleUpdate(http, currentVersion, true);
}
/**
*
* @param host const char *
* @param port uint16_t
* @param url const char *
* @param current_version const char *
* @param httpsFingerprint const char *
* @return
*/
t_httpUpdate_return ESP8266HTTPUpdate::update(const char * host, uint16_t port, const char * url, const char * current_version, bool https, const char * httpsFingerprint, bool reboot) {
HTTPUpdateResult ESP8266HTTPUpdate::updateSpiffs(const String& url, const String& currentVersion)
{
HTTPClient http;
http.begin(host, port, url, https, httpsFingerprint);
return handleUpdate(&http, current_version, reboot, false);
http.begin(url);
return handleUpdate(http, currentVersion, true);
}
t_httpUpdate_return ESP8266HTTPUpdate::update(String host, uint16_t port, String url, String current_version, bool https, String httpsFingerprint, bool reboot) {
HTTPUpdateResult ESP8266HTTPUpdate::update(const String& host, uint16_t port, const String& uri, const String& currentVersion,
bool https, const String& httpsFingerprint, bool reboot)
{
rebootOnUpdate(reboot);
if (httpsFingerprint.length() == 0) {
return update(host, port, uri, currentVersion);
} else {
return update(host, port, uri, currentVersion, httpsFingerprint);
}
}
HTTPUpdateResult ESP8266HTTPUpdate::update(const String& host, uint16_t port, const String& uri,
const String& currentVersion)
{
HTTPClient http;
http.begin(host, port, url, https, httpsFingerprint);
return handleUpdate(&http, current_version.c_str(), reboot, false);
http.begin(host, port, uri);
return handleUpdate(http, currentVersion, false);
}
HTTPUpdateResult ESP8266HTTPUpdate::update(const String& host, uint16_t port, const String& url,
const String& currentVersion, const String& httpsFingerprint)
{
HTTPClient http;
http.begin(host, port, url, httpsFingerprint);
return handleUpdate(http, currentVersion, false);
}
/**
* return error code as int
* @return int error code
*/
int ESP8266HTTPUpdate::getLastError(void){
return lastError;
int ESP8266HTTPUpdate::getLastError(void)
{
return _lastError;
}
/**
* return error code as String
* @return String error
*/
String ESP8266HTTPUpdate::getLastErrorString(void) {
String ESP8266HTTPUpdate::getLastErrorString(void)
{
if(lastError == 0) {
if(_lastError == 0) {
return String(); // no error
}
// error from Update class
if(lastError > 0) {
if(_lastError > 0) {
StreamString error;
Update.printError(error);
error.trim(); // remove line ending
return "Update error: " + error;
return String(F("Update error: ")) + error;
}
// error from http client
if(lastError > -100) {
return "HTTP error: " + HTTPClient::errorToString(lastError);
if(_lastError > -100) {
return String(F("HTTP error: ")) + HTTPClient::errorToString(_lastError);
}
switch(lastError) {
switch(_lastError) {
case HTTP_UE_TOO_LESS_SPACE:
return String("To less space");
return F("To less space");
case HTTP_UE_SERVER_NOT_REPORT_SIZE:
return String("Server not Report Size");
return F("Server not Report Size");
case HTTP_UE_SERVER_FILE_NOT_FOUND:
return String("File not Found (404)");
return F("File not Found (404)");
case HTTP_UE_SERVER_FORBIDDEN:
return String("Forbidden (403)");
return F("Forbidden (403)");
case HTTP_UE_SERVER_WRONG_HTTP_CODE:
return String("Wrong HTTP code");
return F("Wrong HTTP code");
case HTTP_UE_SERVER_FAULTY_MD5:
return String("Faulty MD5");
return F("Faulty MD5");
case HTTP_UE_BIN_VERIFY_HEADER_FAILED:
return String("Verify bin header failed");
return F("Verify bin header failed");
case HTTP_UE_BIN_FOR_WRONG_FLASH:
return String("bin for wrong flash size");
return F("bin for wrong flash size");
}
return String();
@ -139,48 +159,49 @@ String ESP8266HTTPUpdate::getLastErrorString(void) {
/**
*
* @param http HTTPClient *
* @param current_version const char *
* @return t_httpUpdate_return
* @param currentVersion const char *
* @return HTTPUpdateResult
*/
t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const char * current_version, bool reboot, bool spiffs) {
HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs)
{
t_httpUpdate_return ret = HTTP_UPDATE_FAILED;
HTTPUpdateResult ret = HTTP_UPDATE_FAILED;
// use HTTP/1.0 for update since the update handler not support any transfer Encoding
http->useHTTP10(true);
http->setTimeout(8000);
http->setUserAgent("ESP8266-http-Update");
http->addHeader("x-ESP8266-STA-MAC", WiFi.macAddress());
http->addHeader("x-ESP8266-AP-MAC", WiFi.softAPmacAddress());
http->addHeader("x-ESP8266-free-space", String(ESP.getFreeSketchSpace()));
http->addHeader("x-ESP8266-sketch-size", String(ESP.getSketchSize()));
http->addHeader("x-ESP8266-chip-size", String(ESP.getFlashChipRealSize()));
http->addHeader("x-ESP8266-sdk-version", ESP.getSdkVersion());
http.useHTTP10(true);
http.setTimeout(8000);
http.setUserAgent(F("ESP8266-http-Update"));
http.addHeader(F("x-ESP8266-STA-MAC"), WiFi.macAddress());
http.addHeader(F("x-ESP8266-AP-MAC"), WiFi.softAPmacAddress());
http.addHeader(F("x-ESP8266-free-space"), String(ESP.getFreeSketchSpace()));
http.addHeader(F("x-ESP8266-sketch-size"), String(ESP.getSketchSize()));
http.addHeader(F("x-ESP8266-chip-size"), String(ESP.getFlashChipRealSize()));
http.addHeader(F("x-ESP8266-sdk-version"), ESP.getSdkVersion());
if(spiffs) {
http->addHeader("x-ESP8266-mode", "spiffs");
http.addHeader(F("x-ESP8266-mode"), F("spiffs"));
} else {
http->addHeader("x-ESP8266-mode", "sketch");
http.addHeader(F("x-ESP8266-mode"), F("sketch"));
}
if(current_version && current_version[0] != 0x00) {
http->addHeader("x-ESP8266-version", current_version);
if(currentVersion && currentVersion[0] != 0x00) {
http.addHeader(F("x-ESP8266-version"), currentVersion);
}
const char * headerkeys[] = { "x-MD5" };
size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*);
// track these headers
http->collectHeaders(headerkeys, headerkeyssize);
http.collectHeaders(headerkeys, headerkeyssize);
int code = http->GET();
int len = http->getSize();
int code = http.GET();
int len = http.getSize();
if(code <= 0) {
DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http->errorToString(code).c_str());
lastError = code;
http->end();
DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http.errorToString(code).c_str());
_lastError = code;
http.end();
return HTTP_UPDATE_FAILED;
}
@ -190,16 +211,16 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
DEBUG_HTTP_UPDATE("[httpUpdate] - code: %d\n", code);
DEBUG_HTTP_UPDATE("[httpUpdate] - len: %d\n", len);
if(http->hasHeader("x-MD5")) {
DEBUG_HTTP_UPDATE("[httpUpdate] - MD5: %s\n", http->header("x-MD5").c_str());
if(http.hasHeader("x-MD5")) {
DEBUG_HTTP_UPDATE("[httpUpdate] - MD5: %s\n", http.header("x-MD5").c_str());
}
DEBUG_HTTP_UPDATE("[httpUpdate] ESP8266 info:\n");
DEBUG_HTTP_UPDATE("[httpUpdate] - free Space: %d\n", ESP.getFreeSketchSpace());
DEBUG_HTTP_UPDATE("[httpUpdate] - current Sketch Size: %d\n", ESP.getSketchSize());
if(current_version && current_version[0] != 0x00) {
DEBUG_HTTP_UPDATE("[httpUpdate] - current version: %s\n", current_version);
if(currentVersion && currentVersion[0] != 0x00) {
DEBUG_HTTP_UPDATE("[httpUpdate] - current version: %s\n", currentVersion.c_str() );
}
switch(code) {
@ -220,11 +241,11 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
}
if(!startUpdate) {
lastError = HTTP_UE_TOO_LESS_SPACE;
_lastError = HTTP_UE_TOO_LESS_SPACE;
ret = HTTP_UPDATE_FAILED;
} else {
WiFiClient * tcp = http->getStreamPtr();
WiFiClient * tcp = http.getStreamPtr();
WiFiUDP::stopAll();
WiFiClient::stopAllExcept(tcp);
@ -245,16 +266,16 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
uint8_t buf[4];
if(tcp->peekBytes(&buf[0], 4) != 4) {
DEBUG_HTTP_UPDATE("[httpUpdate] peekBytes magic header failed\n");
lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
http->end();
_lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
http.end();
return HTTP_UPDATE_FAILED;
}
// check for valid first magic byte
if(buf[0] != 0xE9) {
DEBUG_HTTP_UPDATE("[httpUpdate] magic header not starts with 0xE9\n");
lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
http->end();
_lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
http.end();
return HTTP_UPDATE_FAILED;
}
@ -264,18 +285,18 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
// check if new bin fits to SPI flash
if(bin_flash_size > ESP.getFlashChipRealSize()) {
DEBUG_HTTP_UPDATE("[httpUpdate] magic header, new bin not fits SPI Flash\n");
lastError = HTTP_UE_BIN_FOR_WRONG_FLASH;
http->end();
_lastError = HTTP_UE_BIN_FOR_WRONG_FLASH;
http.end();
return HTTP_UPDATE_FAILED;
}
}
if(runUpdate(*tcp, len, http->header("x-MD5"), command)) {
if(runUpdate(*tcp, len, http.header("x-MD5"), command)) {
ret = HTTP_UPDATE_OK;
DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");
http->end();
http.end();
if(reboot) {
if(_rebootOnUpdate) {
ESP.restart();
}
@ -285,7 +306,7 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
}
}
} else {
lastError = HTTP_UE_SERVER_NOT_REPORT_SIZE;
_lastError = HTTP_UE_SERVER_NOT_REPORT_SIZE;
ret = HTTP_UPDATE_FAILED;
DEBUG_HTTP_UPDATE("[httpUpdate] Content-Length is 0 or not set by Server?!\n");
}
@ -295,22 +316,22 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
ret = HTTP_UPDATE_NO_UPDATES;
break;
case HTTP_CODE_NOT_FOUND:
lastError = HTTP_UE_SERVER_FILE_NOT_FOUND;
_lastError = HTTP_UE_SERVER_FILE_NOT_FOUND;
ret = HTTP_UPDATE_FAILED;
break;
case HTTP_CODE_FORBIDDEN:
lastError = HTTP_UE_SERVER_FORBIDDEN;
_lastError = HTTP_UE_SERVER_FORBIDDEN;
ret = HTTP_UPDATE_FAILED;
break;
default:
lastError = HTTP_UE_SERVER_WRONG_HTTP_CODE;
_lastError = HTTP_UE_SERVER_WRONG_HTTP_CODE;
ret = HTTP_UPDATE_FAILED;
DEBUG_HTTP_UPDATE("[httpUpdate] HTTP Code is (%d)\n", code);
//http->writeToStream(&Serial1);
//http.writeToStream(&Serial1);
break;
}
http->end();
http.end();
return ret;
}
@ -321,12 +342,13 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
* @param md5 String
* @return true if Update ok
*/
bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int command) {
bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int command)
{
StreamString error;
if(!Update.begin(size, command)) {
lastError = Update.getError();
_lastError = Update.getError();
Update.printError(error);
error.trim(); // remove line ending
DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed! (%s)\n", error.c_str());
@ -335,14 +357,14 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int com
if(md5.length()) {
if(!Update.setMD5(md5.c_str())) {
lastError = HTTP_UE_SERVER_FAULTY_MD5;
_lastError = HTTP_UE_SERVER_FAULTY_MD5;
DEBUG_HTTP_UPDATE("[httpUpdate] Update.setMD5 failed! (%s)\n", md5.c_str());
return false;
}
}
if(Update.writeStream(in) != size) {
lastError = Update.getError();
_lastError = Update.getError();
Update.printError(error);
error.trim(); // remove line ending
DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed! (%s)\n", error.c_str());
@ -350,7 +372,7 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int com
}
if(!Update.end()) {
lastError = Update.getError();
_lastError = Update.getError();
Update.printError(error);
error.trim(); // remove line ending
DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed! (%s)\n", error.c_str());

View File

@ -52,31 +52,57 @@
#define HTTP_UE_BIN_VERIFY_HEADER_FAILED (-106)
#define HTTP_UE_BIN_FOR_WRONG_FLASH (-107)
typedef enum {
enum HTTPUpdateResult {
HTTP_UPDATE_FAILED,
HTTP_UPDATE_NO_UPDATES,
HTTP_UPDATE_OK
} t_httpUpdate_return;
};
class ESP8266HTTPUpdate {
typedef HTTPUpdateResult t_httpUpdate_return; // backward compatibility
class ESP8266HTTPUpdate
{
public:
ESP8266HTTPUpdate(void);
~ESP8266HTTPUpdate(void);
t_httpUpdate_return update(const char * url, const char * current_version = "", const char * httpsFingerprint = "", bool reboot = true);
t_httpUpdate_return update(const char * host, uint16_t port, const char * url = "/", const char * current_version = "", bool https = false, const char * httpsFingerprint = "", bool reboot = true);
t_httpUpdate_return update(String host, uint16_t port, String url = "/", String current_version = "", bool https = false, String httpsFingerprint = "", bool reboot = true);
void rebootOnUpdate(bool reboot)
{
_rebootOnUpdate = reboot;
}
// This function is deprecated, use rebootOnUpdate and the next one instead
t_httpUpdate_return update(const String& url, const String& currentVersion,
const String& httpsFingerprint, bool reboot) __attribute__((deprecated));
t_httpUpdate_return update(const String& url, const String& currentVersion = "");
t_httpUpdate_return update(const String& url, const String& currentVersion,
const String& httpsFingerprint);
// This function is deprecated, use one of the overloads below along with rebootOnUpdate
t_httpUpdate_return update(const String& host, uint16_t port, const String& uri, const String& currentVersion,
bool https, const String& httpsFingerprint, bool reboot) __attribute__((deprecated));
t_httpUpdate_return update(const String& host, uint16_t port, const String& uri = "/",
const String& currentVersion = "");
t_httpUpdate_return update(const String& host, uint16_t port, const String& url,
const String& currentVersion, const String& httpsFingerprint);
// This function is deprecated, use rebootOnUpdate and the next one instead
t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion,
const String& httpsFingerprint, bool reboot) __attribute__((deprecated));
t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion = "");
t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion, const String& httpsFingerprint);
t_httpUpdate_return updateSpiffs(const char * url, const char * current_version = "", const char * httpsFingerprint = "", bool reboot = false);
int getLastError(void);
String getLastErrorString(void);
protected:
t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version, bool reboot = true, bool spiffs = false);
t_httpUpdate_return handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs = false);
bool runUpdate(Stream& in, uint32_t size, String md5, int command = U_FLASH);
int lastError;
int _lastError;
bool _rebootOnUpdate = true;
};
extern ESP8266HTTPUpdate ESPhttpUpdate;

View File

@ -34,7 +34,9 @@ License (MIT license):
// - Multicast DNS: http://www.ietf.org/rfc/rfc6762.txt
// - MDNS-SD: https://tools.ietf.org/html/rfc6763
#ifndef LWIP_OPEN_SRC
#define LWIP_OPEN_SRC
#endif
#include "ESP8266mDNS.h"
#include <functional>

View File

@ -246,13 +246,13 @@ uint16_t SPIClass::transfer16(uint16_t data) {
in.val = data;
if((SPI1C & (SPICWBO | SPICRBO))) {
//MSBFIRST
out.msb = transfer(in.msb);
out.lsb = transfer(in.lsb);
} else {
//LSBFIRST
out.lsb = transfer(in.lsb);
out.msb = transfer(in.msb);
} else {
//MSBFIRST
out.msb = transfer(in.msb);
out.lsb = transfer(in.lsb);
}
return out.val;
}
@ -350,11 +350,7 @@ void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
while(SPI1CMD & SPIBUSY) {}
}
/**
* Note:
* data need to be aligned to 32Bit
* or you get an Fatal exception (9)
* @param data uint8_t *
* @param size uint8_t max for size is 64Byte
* @param repeat uint32_t
@ -362,37 +358,72 @@ void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
if(size > 64) return; //max Hardware FIFO
uint32_t byte = (size * repeat);
uint8_t r = (64 / size);
while(SPI1CMD & SPIBUSY) {}
while(byte) {
if(byte > 64) {
writePattern_(data, size, r);
byte -= 64;
} else {
writePattern_(data, size, (byte / size));
byte = 0;
}
}
}
uint32_t buffer[16];
uint8_t *bufferPtr=(uint8_t *)&buffer;
uint8_t *dataPtr = data;
volatile uint32_t * fifoPtr = &SPI1W0;
uint8_t r;
uint32_t repeatRem;
uint8_t i;
void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
uint8_t bytes = (size * repeat);
uint8_t buffer[64];
uint8_t * bufferPtr = &buffer[0];
uint8_t * dataPtr;
uint8_t dataSize = bytes;
for(uint8_t i = 0; i < repeat; i++) {
dataSize = size;
if((repeat * size) <= 64){
repeatRem = repeat * size;
r = repeat;
while(r--){
dataPtr = data;
while(dataSize--) {
for(i=0; i<size; i++){
*bufferPtr = *dataPtr;
dataPtr++;
bufferPtr++;
dataPtr++;
}
}
writeBytes(&buffer[0], bytes);
r = repeatRem;
if(r & 3) r = r / 4 + 1;
else r = r / 4;
for(i=0; i<r; i++){
*fifoPtr = buffer[i];
fifoPtr++;
}
SPI1U = SPIUMOSI | SPIUSSE;
} else {
//Orig
r = 64 / size;
repeatRem = repeat % r * size;
repeat = repeat / r;
while(r--){
dataPtr = data;
for(i=0; i<size; i++){
*bufferPtr = *dataPtr;
bufferPtr++;
dataPtr++;
}
}
//Fill fifo with data
for(i=0; i<16; i++){
*fifoPtr = buffer[i];
fifoPtr++;
}
r = 64 / size;
SPI1U = SPIUMOSI | SPIUSSE;
setDataBits(r * size * 8);
while(repeat--){
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
}
//End orig
setDataBits(repeatRem * 8);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE;
}
/**

View File

@ -75,7 +75,6 @@ public:
private:
bool useHwCs;
void writeBytes_(uint8_t * data, uint8_t size);
void writePattern_(uint8_t * data, uint8_t size, uint8_t repeat);
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
inline void setDataBits(uint16_t bits);
};

View File

@ -126,6 +126,13 @@
"archiveFileName": "esptool-0.4.8-linux32.tar.gz",
"checksum": "SHA-256:b0d6e71e6f41d4ed7e167bb4b3f4f0b1b3e49d69af50ab7fbe952cbfed83f164",
"size": "15444"
},
{
"host": "arm-linux-gnueabihf",
"url": "https://github.com/igrr/esptool-ck/releases/download/0.4.8/esptool-0.4.8-linux-armhf.tar.gz",
"archiveFileName": "esptool-0.4.8-linux-armhf.tar.gz",
"checksum": "SHA-256:e9c4dfb81781610556a6af0377c8efc7cde359e0e2cda2fd48e0a32bae10f506",
"size": "13630"
}
]
},
@ -167,6 +174,13 @@
"archiveFileName": "linux32-xtensa-lx106-elf.tar.gz",
"checksum": "SHA-256:b24817819f0078fb05895a640e806e0aca9aa96b47b80d2390ac8e2d9ddc955a",
"size": "32734156"
},
{
"host": "arm-linux-gnueabihf",
"url": "http://arduino.esp8266.com/linuxarm-xtensa-lx106-elf-g46f160f.tar.gz",
"archiveFileName": "linuxarm-xtensa-lx106-elf-g46f160f.tar.gz",
"checksum": "SHA-256:1ac752bac7fff6be95ce10f56689f155fefea09e4ef710dbd75cb573798ff9c0",
"size": "34929527"
}
]
},
@ -208,6 +222,13 @@
"archiveFileName": "mkspiffs-0.1.2-linux32.tar.gz",
"checksum": "SHA-256:e990d545dfcae308aabaac5fa9e1db734cc2b08167969e7eedac88bd0839667c",
"size": "45272"
},
{
"host": "arm-linux-gnueabihf",
"url": "https://github.com/igrr/mkspiffs/releases/download/0.1.2/mkspiffs-0.1.2-linux-armhf.tar.gz",
"archiveFileName": "mkspiffs-0.1.2-linux-armhf.tar.gz",
"checksum": "SHA-256:5a8836932cd24325d69054cebdd46359eba02919ffaa87b130c54acfecc13f46",
"size": "41685"
}
]
}

View File

@ -6,7 +6,7 @@
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
name=ESP8266 Modules
version=2.1.0
version=2.2.0
runtime.tools.xtensa-lx106-elf-gcc.path={runtime.platform.path}/tools/xtensa-lx106-elf
runtime.tools.esptool.path={runtime.platform.path}/tools/esptool
@ -19,7 +19,7 @@ compiler.warning_flags.all=-Wall -Wextra
compiler.path={runtime.tools.xtensa-lx106-elf-gcc.path}/bin/
compiler.sdk.path={runtime.platform.path}/tools/sdk
compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include"
compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include" "-I{compiler.sdk.path}/lwip/include"
compiler.c.cmd=xtensa-lx106-elf-gcc
compiler.c.flags=-c {compiler.warning_flags} -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=gnu99 -ffunction-sections -fdata-sections
@ -30,7 +30,7 @@ compiler.S.flags=-c -g -x assembler-with-cpp -MMD -mlongcalls
compiler.c.elf.flags=-g {compiler.warning_flags} -Os -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-T{build.flash_ld}" -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,register_chipv6_phy
compiler.c.elf.cmd=xtensa-lx106-elf-gcc
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lcrypto -lmain -lwps -laxtls -lsmartconfig -lmesh -lwpa2
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lpp -lnet80211 -lwpa -lcrypto -lmain -lwps -laxtls -lsmartconfig -lmesh -lwpa2 {build.lwip_lib}
compiler.cpp.cmd=xtensa-lx106-elf-g++
compiler.cpp.flags=-c {compiler.warning_flags} -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD -ffunction-sections -fdata-sections
@ -61,13 +61,13 @@ compiler.objcopy.eep.extra_flags=
compiler.elf2hex.extra_flags=
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.c.flags} -DF_CPU={build.f_cpu} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.c.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} -DF_CPU={build.f_cpu} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.S.flags} -DF_CPU={build.f_cpu} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.S.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Create archives
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/arduino.ar" "{object_file}"

View File

@ -4,7 +4,6 @@
# Written by Ivan Grokhotkov, 2015.
#
from __future__ import print_function
import urllib
import os
import shutil
import errno
@ -16,6 +15,11 @@ import sys
import tarfile
import zipfile
import re
if sys.version_info[0] == 3:
from urllib.request import urlretrieve
else:
# Not Python 3 - today, it is most likely to be Python 2
from urllib import urlretrieve
dist_dir = 'dist/'
@ -54,7 +58,7 @@ def unpack(filename, destination):
raise NotImplementedError('Unsupported archive type')
# a little trick to rename tool directories so they don't contain version number
rename_to = re.match(r'^([a-z][^\-]*\-*)+', dirname).group(0).encode('ascii').strip('-')
rename_to = re.match(r'^([a-z][^\-]*\-*)+', dirname).group(0).strip('-')
if rename_to != dirname:
print('Renaming {0} to {1}'.format(dirname, rename_to))
if os.path.isdir(rename_to):
@ -68,7 +72,7 @@ def get_tool(tool):
real_hash = tool['checksum'].split(':')[1]
if not os.path.isfile(local_path):
print('Downloading ' + archive_name);
urllib.urlretrieve(url, local_path, report_progress)
urlretrieve(url, local_path, report_progress)
sys.stdout.write("\rDone\n")
sys.stdout.flush()
else:
@ -92,11 +96,14 @@ def load_tools_list(filename, platform):
def identify_platform():
arduino_platform_names = {'Darwin' : {32 : 'i386-apple-darwin', 64 : 'x86_64-apple-darwin'},
'Linux' : {32 : 'i686-pc-linux-gnu', 64 : 'x86_64-pc-linux-gnu'},
'LinuxARM': {32 : 'arm-linux-gnueabihf', 64 : 'aarch64-linux-gnu'},
'Windows' : {32 : 'i686-mingw32', 64 : 'i686-mingw32'}}
bits = 32
if sys.maxsize > 2**32:
bits = 64
sys_name = platform.system()
if 'Linux' in sys_name and platform.platform().find('arm') > 0:
sys_name = 'LinuxARM'
if 'CYGWIN_NT' in sys_name:
sys_name = 'Windows'
return arduino_platform_names[sys_name][bits]

View File

@ -10,6 +10,7 @@
#include "c_types.h"
#include "eagle_soc.h"
#include <stddef.h>
typedef uint32_t ETSSignal;
typedef uint32_t ETSParam;
@ -182,7 +183,8 @@ void ets_isr_attach(int intr, int_handler_t handler, void *arg);
void ets_intr_lock();
void ets_intr_unlock();
int ets_vsnprintf(char * s, size_t n, const char * format, va_list arg) __attribute__ ((format (printf, 3, 0)));
int ets_vprintf(const char * format, va_list arg) __attribute__ ((format (printf, 1, 0)));
int ets_vprintf(int (*print_function)(int), const char * format, va_list arg) __attribute__ ((format (printf, 2, 0)));
int ets_putc(int);
bool ets_task(ETSTask task, uint8 prio, ETSEvent *queue, uint8 qlen);
bool ets_post(uint8 prio, ETSSignal sig, ETSParam par);

View File

@ -78,6 +78,8 @@ SECTIONS
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
. = ALIGN(4);
_Pri_3_HandlerAddress = ABSOLUTE(.);
_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr

Binary file not shown.

View File

@ -0,0 +1,101 @@
#ifndef __DHCPS_H__
#define __DHCPS_H__
#define USE_DNS
typedef struct dhcps_state{
sint16_t state;
} dhcps_state;
typedef struct dhcps_msg {
uint8_t op, htype, hlen, hops;
uint8_t xid[4];
uint16_t secs, flags;
uint8_t ciaddr[4];
uint8_t yiaddr[4];
uint8_t siaddr[4];
uint8_t giaddr[4];
uint8_t chaddr[16];
uint8_t sname[64];
uint8_t file[128];
uint8_t options[312];
}dhcps_msg;
#ifndef LWIP_OPEN_SRC
struct dhcps_lease {
bool enable;
struct ip_addr start_ip;
struct ip_addr end_ip;
};
enum dhcps_offer_option{
OFFER_START = 0x00,
OFFER_ROUTER = 0x01,
OFFER_END
};
#endif
struct dhcps_pool{
struct ip_addr ip;
uint8 mac[6];
uint32 lease_timer;
};
typedef struct _list_node{
void *pnode;
struct _list_node *pnext;
}list_node;
extern uint32 dhcps_lease_time;
#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0
#define DHCPS_MAX_LEASE 0x64
#define BOOTP_BROADCAST 0x8000
#define DHCP_REQUEST 1
#define DHCP_REPLY 2
#define DHCP_HTYPE_ETHERNET 1
#define DHCP_HLEN_ETHERNET 6
#define DHCP_MSG_LEN 236
#define DHCPS_SERVER_PORT 67
#define DHCPS_CLIENT_PORT 68
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCP_OPTION_SUBNET_MASK 1
#define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6
#define DHCP_OPTION_REQ_IPADDR 50
#define DHCP_OPTION_LEASE_TIME 51
#define DHCP_OPTION_MSG_TYPE 53
#define DHCP_OPTION_SERVER_ID 54
#define DHCP_OPTION_INTERFACE_MTU 26
#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31
#define DHCP_OPTION_BROADCAST_ADDRESS 28
#define DHCP_OPTION_REQ_LIST 55
#define DHCP_OPTION_END 255
//#define USE_CLASS_B_NET 1
#define DHCPS_DEBUG 0
#define MAX_STATION_NUM 8
#define DHCPS_STATE_OFFER 1
#define DHCPS_STATE_DECLINE 2
#define DHCPS_STATE_ACK 3
#define DHCPS_STATE_NAK 4
#define DHCPS_STATE_IDLE 5
#define DHCPS_STATE_RELEASE 6
#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0)
void dhcps_start(struct ip_info *info);
void dhcps_stop(void);
#endif

View File

@ -0,0 +1,664 @@
#ifndef __ESPCONN_H__
#define __ESPCONN_H__
#include "lwip/dns.h"
#include "os_type.h"
#if 0
#define espconn_printf(fmt, args...) os_printf(fmt,## args)
#else
#define espconn_printf(fmt, args...)
#endif
typedef void *espconn_handle;
typedef void (* espconn_connect_callback)(void *arg);
typedef void (* espconn_reconnect_callback)(void *arg, sint8 err);
/* Definitions for error constants. */
#define ESPCONN_OK 0 /* No error, everything OK. */
#define ESPCONN_MEM -1 /* Out of memory error. */
#define ESPCONN_TIMEOUT -3 /* Timeout. */
#define ESPCONN_RTE -4 /* Routing problem. */
#define ESPCONN_INPROGRESS -5 /* Operation in progress */
#define ESPCONN_MAXNUM -7 /* Total number exceeds the set maximum*/
#define ESPCONN_ABRT -8 /* Connection aborted. */
#define ESPCONN_RST -9 /* Connection reset. */
#define ESPCONN_CLSD -10 /* Connection closed. */
#define ESPCONN_CONN -11 /* Not connected. */
#define ESPCONN_ARG -12 /* Illegal argument. */
#define ESPCONN_IF -14 /* Low_level error */
#define ESPCONN_ISCONN -15 /* Already connected. */
#define ESPCONN_HANDSHAKE -28 /* ssl handshake failed */
#define ESPCONN_RESP_TIMEOUT -29 /* ssl handshake no response*/
#define ESPCONN_PROTO_MSG -61 /* ssl application invalid */
#define ESPCONN_SSL 0x01
#define ESPCONN_NORM 0x00
#define ESPCONN_STA 0x01
#define ESPCONN_AP 0x02
#define ESPCONN_AP_STA 0x03
#define STA_NETIF 0x00
#define AP_NETIF 0x01
/** Protocol family and type of the espconn */
enum espconn_type {
ESPCONN_INVALID = 0,
/* ESPCONN_TCP Group */
ESPCONN_TCP = 0x10,
/* ESPCONN_UDP Group */
ESPCONN_UDP = 0x20,
};
/** Current state of the espconn. Non-TCP espconn are always in state ESPCONN_NONE! */
enum espconn_state {
ESPCONN_NONE,
ESPCONN_WAIT,
ESPCONN_LISTEN,
ESPCONN_CONNECT,
ESPCONN_WRITE,
ESPCONN_READ,
ESPCONN_CLOSE
};
typedef struct _esp_tcp {
int remote_port;
int local_port;
uint8 local_ip[4];
uint8 remote_ip[4];
espconn_connect_callback connect_callback;
espconn_reconnect_callback reconnect_callback;
espconn_connect_callback disconnect_callback;
espconn_connect_callback write_finish_fn;
} esp_tcp;
typedef struct _esp_udp {
int remote_port;
int local_port;
uint8 local_ip[4];
uint8 remote_ip[4];
} esp_udp;
typedef struct _remot_info{
enum espconn_state state;
int remote_port;
uint8 remote_ip[4];
}remot_info;
/** A callback prototype to inform about events for a espconn */
typedef void (* espconn_recv_callback)(void *arg, char *pdata, unsigned short len);
typedef void (* espconn_sent_callback)(void *arg);
/** A espconn descriptor */
struct espconn {
/** type of the espconn (TCP, UDP) */
enum espconn_type type;
/** current state of the espconn */
enum espconn_state state;
union {
esp_tcp *tcp;
esp_udp *udp;
} proto;
/** A callback function that is informed about events for this espconn */
espconn_recv_callback recv_callback;
espconn_sent_callback sent_callback;
uint8 link_cnt;
void *reverse;
};
enum espconn_option{
ESPCONN_START = 0x00,
ESPCONN_REUSEADDR = 0x01,
ESPCONN_NODELAY = 0x02,
ESPCONN_COPY = 0x04,
ESPCONN_KEEPALIVE = 0x08,
ESPCONN_END
};
enum espconn_level{
ESPCONN_KEEPIDLE,
ESPCONN_KEEPINTVL,
ESPCONN_KEEPCNT
};
struct espconn_packet{
uint16 sent_length; /* sent length successful*/
uint16 snd_buf_size; /* Available buffer size for sending */
uint16 snd_queuelen; /* Available buffer space for sending */
uint16 total_queuelen; /* total Available buffer space for sending */
uint32 packseqno; /* seqno to be sent */
uint32 packseq_nxt; /* seqno expected */
uint32 packnum;
};
typedef struct _espconn_buf{
uint8 *payload;
uint8 *punsent;
uint16 unsent;
uint16 len;
uint16 tot_len;
struct _espconn_buf *pnext;
} espconn_buf;
typedef struct _comon_pkt{
void *pcb;
int remote_port;
uint8 remote_ip[4];
uint32 local_port;
uint32 local_ip;
espconn_buf *pbuf;
espconn_buf *ptail;
uint8* ptrbuf;
uint16 cntr;
sint8 err;
uint32 timeout;
uint32 recv_check;
uint8 pbuf_num;
struct espconn_packet packet_info;
bool write_flag;
enum espconn_option espconn_opt;
}comon_pkt;
typedef struct _espconn_msg{
struct espconn *pespconn;
comon_pkt pcommon;
uint8 count_opt;
sint16_t hs_status; //the status of the handshake
void *preverse;
void *pssl;
struct _espconn_msg *pnext;
//***********Code for WIFI_BLOCK from upper**************
uint8 recv_hold_flag;
uint16 recv_holded_buf_Len;
}espconn_msg;
#ifndef _MDNS_INFO
#define _MDNS_INFO
struct mdns_info {
char *host_name;
char *server_name;
uint16 server_port;
unsigned long ipAddr;
char *txt_data[10];
};
#endif
#define linkMax 15
#define espconn_delay_disabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_NODELAY) != 0)
#define espconn_delay_enabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_NODELAY) == 0)
#define espconn_reuse_disabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_REUSEADDR) != 0)
#define espconn_copy_disabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_COPY) != 0)
#define espconn_copy_enabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_COPY) == 0)
#define espconn_keepalive_disabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_KEEPALIVE) != 0)
#define espconn_keepalive_enabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_KEEPALIVE) == 0)
#define espconn_TaskPrio 26
#define espconn_TaskQueueLen 15
enum espconn_sig {
SIG_ESPCONN_NONE,
SIG_ESPCONN_ERRER,
SIG_ESPCONN_LISTEN,
SIG_ESPCONN_CONNECT,
SIG_ESPCONN_WRITE,
SIG_ESPCONN_SEND,
SIG_ESPCONN_READ,
SIG_ESPCONN_CLOSE
};
/******************************************************************************
* FunctionName : espconn_copy_partial
* Description : reconnect with host
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
void espconn_copy_partial(struct espconn *pesp_dest, struct espconn *pesp_source);
/******************************************************************************
* FunctionName : espconn_copy_partial
* Description : insert the node to the active connection list
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
void espconn_list_creat(espconn_msg **phead, espconn_msg* pinsert);
/******************************************************************************
* FunctionName : espconn_list_delete
* Description : remove the node from the active connection list
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
void espconn_list_delete(espconn_msg **phead, espconn_msg* pdelete);
/******************************************************************************
* FunctionName : espconn_find_connection
* Description : Initialize the server: set up a listening PCB and bind it to
* the defined port
* Parameters : espconn -- the espconn used to build server
* Returns : none
*******************************************************************************/
bool espconn_find_connection(struct espconn *pespconn, espconn_msg **pnode);
/******************************************************************************
* FunctionName : espconn_get_connection_info
* Description : used to specify the function that should be called when disconnect
* Parameters : espconn -- espconn to set the err callback
* discon_cb -- err callback function to call when err
* Returns : none
*******************************************************************************/
sint8 espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, uint8 typeflags);
/******************************************************************************
* FunctionName : espconn_get_packet_info
* Description : get the packet info with host
* Parameters : espconn -- the espconn used to disconnect the connection
* infoarg -- the packet info
* Returns : the errur code
*******************************************************************************/
sint8 espconn_get_packet_info(struct espconn *espconn, struct espconn_packet* infoarg);
/******************************************************************************
* FunctionName : espconn_connect
* Description : The function given as the connect
* Parameters : espconn -- the espconn used to listen the connection
* Returns : none
*******************************************************************************/
extern sint8 espconn_connect(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_disconnect
* Description : disconnect with host
* Parameters : espconn -- the espconn used to disconnect the connection
* Returns : none
*******************************************************************************/
extern sint8 espconn_disconnect(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_delete
* Description : disconnect with host
* Parameters : espconn -- the espconn used to disconnect the connection
* Returns : none
*******************************************************************************/
extern sint8 espconn_delete(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_accept
* Description : The function given as the listen
* Parameters : espconn -- the espconn used to listen the connection
* Returns : none
*******************************************************************************/
extern sint8 espconn_accept(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_create
* Description : sent data for client or server
* Parameters : espconn -- espconn to the data transmission
* Returns : result
*******************************************************************************/
extern sint8 espconn_create(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_tcp_get_wnd
* Description : get the window size of simulatenously active TCP connections
* Parameters : none
* Returns : the number of TCP_MSS active TCP connections
*******************************************************************************/
extern uint8 espconn_tcp_get_wnd(void);
/******************************************************************************
* FunctionName : espconn_tcp_set_max_con
* Description : set the window size simulatenously active TCP connections
* Parameters : num -- the number of TCP_MSS
* Returns : ESPCONN_ARG -- Illegal argument
* ESPCONN_OK -- No error
*******************************************************************************/
extern sint8 espconn_tcp_set_wnd(uint8 num);
/******************************************************************************
* FunctionName : espconn_tcp_get_max_con
* Description : get the number of simulatenously active TCP connections
* Parameters : none
* Returns : none
*******************************************************************************/
extern uint8 espconn_tcp_get_max_con(void);
/******************************************************************************
* FunctionName : espconn_tcp_set_max_con
* Description : set the number of simulatenously active TCP connections
* Parameters : num -- total number
* Returns : none
*******************************************************************************/
extern sint8 espconn_tcp_set_max_con(uint8 num);
/******************************************************************************
* FunctionName : espconn_tcp_get_max_retran
* Description : get the Maximum number of retransmissions of data active TCP connections
* Parameters : none
* Returns : the Maximum number of retransmissions
*******************************************************************************/
extern uint8 espconn_tcp_get_max_retran(void);
/******************************************************************************
* FunctionName : espconn_tcp_set_max_retran
* Description : set the Maximum number of retransmissions of data active TCP connections
* Parameters : num -- the Maximum number of retransmissions
* Returns : result
*******************************************************************************/
extern sint8 espconn_tcp_set_max_retran(uint8 num);
/******************************************************************************
* FunctionName : espconn_tcp_get_max_syn
* Description : get the Maximum number of retransmissions of SYN segments
* Parameters : none
* Returns : the Maximum number of retransmissions
*******************************************************************************/
extern uint8 espconn_tcp_get_max_syn(void);
/******************************************************************************
* FunctionName : espconn_tcp_set_max_syn
* Description : set the Maximum number of retransmissions of SYN segments
* Parameters : num -- the Maximum number of retransmissions
* Returns : result
*******************************************************************************/
extern sint8 espconn_tcp_set_max_syn(uint8 num);
/******************************************************************************
* FunctionName : espconn_tcp_get_max_con_allow
* Description : get the count of simulatenously active connections on the server
* Parameters : espconn -- espconn to get the count
* Returns : result
*******************************************************************************/
extern sint8 espconn_tcp_get_max_con_allow(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_tcp_set_max_con_allow
* Description : set the count of simulatenously active connections on the server
* Parameters : espconn -- espconn to set the count
* Returns : result
*******************************************************************************/
extern sint8 espconn_tcp_set_max_con_allow(struct espconn *espconn, uint8 num);
/******************************************************************************
* FunctionName : espconn_tcp_set_buf_count
* Description : set the total number of espconn_buf on the unsent lists
* Parameters : espconn -- espconn to set the count
* num -- the total number of espconn_buf
* Returns : result
*******************************************************************************/
extern sint8 espconn_tcp_set_buf_count(struct espconn *espconn, uint8 num);
/******************************************************************************
* FunctionName : espconn_regist_time
* Description : used to specify the time that should be called when don't recv data
* Parameters : espconn -- the espconn used to the connection
* interval -- the timer when don't recv data
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_time(struct espconn *espconn, uint32 interval, uint8 type_flag);
/******************************************************************************
* FunctionName : espconn_regist_sentcb
* Description : Used to specify the function that should be called when data
* has been successfully delivered to the remote host.
* Parameters : struct espconn *espconn -- espconn to set the sent callback
* espconn_sent_callback sent_cb -- sent callback function to
* call for this espconn when data is successfully sent
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_cb);
/******************************************************************************
* FunctionName : espconn_regist_sentcb
* Description : Used to specify the function that should be called when data
* has been successfully delivered to the remote host.
* Parameters : espconn -- espconn to set the sent callback
* sent_cb -- sent callback function to call for this espconn
* when data is successfully sent
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback write_finish_fn);
/******************************************************************************
* FunctionName : espconn_sent
* Description : sent data for client or server
* Parameters : espconn -- espconn to set for client or server
* psent -- data to send
* length -- length of data to send
* Returns : none
*******************************************************************************/
extern sint8 espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length);
/******************************************************************************
* FunctionName : espconn_regist_connectcb
* Description : used to specify the function that should be called when
* connects to host.
* Parameters : espconn -- espconn to set the connect callback
* connect_cb -- connected callback function to call when connected
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_connectcb(struct espconn *espconn, espconn_connect_callback connect_cb);
/******************************************************************************
* FunctionName : espconn_regist_recvcb
* Description : used to specify the function that should be called when recv
* data from host.
* Parameters : espconn -- espconn to set the recv callback
* recv_cb -- recv callback function to call when recv data
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_recvcb(struct espconn *espconn, espconn_recv_callback recv_cb);
/******************************************************************************
* FunctionName : espconn_regist_reconcb
* Description : used to specify the function that should be called when connection
* because of err disconnect.
* Parameters : espconn -- espconn to set the err callback
* recon_cb -- err callback function to call when err
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_reconcb(struct espconn *espconn, espconn_reconnect_callback recon_cb);
/******************************************************************************
* FunctionName : espconn_regist_disconcb
* Description : used to specify the function that should be called when disconnect
* Parameters : espconn -- espconn to set the err callback
* discon_cb -- err callback function to call when err
* Returns : none
*******************************************************************************/
extern sint8 espconn_regist_disconcb(struct espconn *espconn, espconn_connect_callback discon_cb);
/******************************************************************************
* FunctionName : espconn_port
* Description : access port value for client so that we don't end up bouncing
* all connections at the same time .
* Parameters : none
* Returns : access port value
*******************************************************************************/
extern uint32 espconn_port(void);
/******************************************************************************
* FunctionName : espconn_set_opt
* Description : access port value for client so that we don't end up bouncing
* all connections at the same time .
* Parameters : none
* Returns : access port value
*******************************************************************************/
extern sint8 espconn_set_opt(struct espconn *espconn, uint8 opt);
/******************************************************************************
* FunctionName : espconn_set_keepalive
* Description : access level value for connection so that we set the value for
* keep alive
* Parameters : espconn -- the espconn used to set the connection
* level -- the connection's level
* value -- the value of time(s)
* Returns : access port value
*******************************************************************************/
extern sint8 espconn_set_keepalive(struct espconn *espconn, uint8 level, void* optarg);
/******************************************************************************
* FunctionName : espconn_get_keepalive
* Description : access level value for connection so that we get the value for
* keep alive
* Parameters : espconn -- the espconn used to get the connection
* level -- the connection's level
* Returns : access keep alive value
*******************************************************************************/
extern sint8 espconn_get_keepalive(struct espconn *espconn, uint8 level, void *optarg);
/******************************************************************************
* FunctionName : espconn_gethostbyname
* Description : Resolve a hostname (string) into an IP address.
* Parameters : pespconn -- espconn to resolve a hostname
* hostname -- the hostname that is to be queried
* addr -- pointer to a ip_addr_t where to store the address if
* it is already cached in the dns_table (only valid if
* ESPCONN_OK is returned!)
* found -- a callback function to be called on success, failure
* or timeout (only if ERR_INPROGRESS is returned!)
* Returns : err_t return code
* - ESPCONN_OK if hostname is a valid IP address string or the host
* name is already in the local names table.
* - ESPCONN_INPROGRESS enqueue a request to be sent to the DNS server
* for resolution if no errors are present.
* - ESPCONN_ARG: dns client not initialized or invalid hostname
*******************************************************************************/
extern sint8 espconn_gethostbyname(struct espconn *pespconn, const char *name, ip_addr_t *addr, dns_found_callback found);
/******************************************************************************
* FunctionName : espconn_igmp_join
* Description : join a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
extern sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
/******************************************************************************
* FunctionName : espconn_igmp_leave
* Description : leave a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
extern sint8 espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
/******************************************************************************
* FunctionName : espconn_mdns_init
* Description : register a device with mdns
* Parameters : ipAddr -- the ip address of device
* hostname -- the hostname of device
* Returns : none
*******************************************************************************/
extern void espconn_mdns_init(struct mdns_info *info);
/******************************************************************************
* FunctionName : espconn_mdns_init
* Description : close mdns socket
* Parameters : void
* Returns : none
*******************************************************************************/
extern void espconn_mdns_close(void);
/******************************************************************************
* FunctionName : mdns_server_register
* Description : register a server and join a multicast group
* Parameters : none
* Returns : none
*******************************************************************************/
extern void espconn_mdns_server_register(void);
/******************************************************************************
* FunctionName : mdns_server_register
* Description : unregister server and leave multicast group
* Parameters : none
* Returns : none
*******************************************************************************/
extern void espconn_mdns_server_unregister(void);
/******************************************************************************
* FunctionName : espconn_mdns_get_servername
* Description : get server name
* Parameters : none
* Returns : server name
*******************************************************************************/
extern char* espconn_mdns_get_servername(void);
/******************************************************************************
* FunctionName : espconn_mdns_get_servername
* Description : set server name
* Parameters : server name
* Returns : none
*******************************************************************************/
extern void espconn_mdns_set_servername(const char *name);
/******************************************************************************
* FunctionName : espconn_mdns_set_hostname
* Description : set host name
* Parameters : host name
* Returns : none
*******************************************************************************/
extern void espconn_mdns_set_hostname(char *name);
/******************************************************************************
* FunctionName : espconn_mdns_init
* Description : get host name
* Parameters : void
* Returns : hostname
*******************************************************************************/
extern char* espconn_mdns_get_hostname(void);
/******************************************************************************
* FunctionName : espconn_mdns_disable
* Description : join a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
extern void espconn_mdns_disable(void);
/******************************************************************************
* FunctionName : espconn_mdns_enable
* Description : enable mdns
* Parameters : void
* Returns : none
*******************************************************************************/
extern void espconn_mdns_enable(void);
/******************************************************************************
* FunctionName : espconn_dns_setserver
* Description : Initialize one of the DNS servers.
* Parameters : numdns -- the index of the DNS server to set must
* be < DNS_MAX_SERVERS = 2
* dnsserver -- IP address of the DNS server to set
* Returns : none
*******************************************************************************/
extern void espconn_dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
#endif

View File

@ -0,0 +1,55 @@
#ifndef __ESPCONN_TCP_H__
#define __ESPCONN_TCP_H__
#ifndef ESPCONN_TCP_DEBUG
#define ESPCONN_TCP_DEBUG LWIP_DBG_OFF
#endif
#include "lwip/app/espconn.h"
#ifndef ESPCONN_TCP_TIMER
#define ESPCONN_TCP_TIMER 40
#endif
#define espconn_keepalive_enable(pcb) ((pcb)->so_options |= SOF_KEEPALIVE)
#define espconn_keepalive_disable(pcb) ((pcb)->so_options &= ~SOF_KEEPALIVE)
/******************************************************************************
* FunctionName : espconn_kill_oldest_pcb
* Description : A oldest incoming connection has been killed.
* Parameters : none
* Returns : none
*******************************************************************************/
extern void espconn_kill_oldest_pcb(void);
/******************************************************************************
* FunctionName : espconn_tcp_disconnect
* Description : A new incoming connection has been disconnected.
* Parameters : espconn -- the espconn used to disconnect with host
* Returns : none
*******************************************************************************/
extern void espconn_tcp_disconnect(espconn_msg *pdiscon,u8 type);
/******************************************************************************
* FunctionName : espconn_tcp_client
* Description : Initialize the client: set up a connect PCB and bind it to
* the defined port
* Parameters : espconn -- the espconn used to build client
* Returns : none
*******************************************************************************/
extern sint8 espconn_tcp_client(struct espconn* espconn);
/******************************************************************************
* FunctionName : espconn_tcp_server
* Description : Initialize the server: set up a listening PCB and bind it to
* the defined port
* Parameters : espconn -- the espconn used to build server
* Returns : none
*******************************************************************************/
extern sint8 espconn_tcp_server(struct espconn *espconn);
#endif /* __CLIENT_TCP_H__ */

View File

@ -0,0 +1,64 @@
#ifndef __ESPCONN_UDP_H__
#define __ESPCONN_UDP_H__
#ifndef ESPCONN_UDP_DEBUG
#define ESPCONN_UDP_DEBUG LWIP_DBG_OFF
#endif
#include "lwip/app/espconn.h"
/******************************************************************************
* FunctionName : espconn_udp_client
* Description : Initialize the client: set up a PCB and bind it to the port
* Parameters : pespconn -- the espconn used to build client
* Returns : none
*******************************************************************************/
extern sint8 espconn_udp_client(struct espconn *pespconn);
/******************************************************************************
* FunctionName : espconn_udp_disconnect
* Description : A new incoming connection has been disconnected.
* Parameters : espconn -- the espconn used to disconnect with host
* Returns : none
*******************************************************************************/
extern void espconn_udp_disconnect(espconn_msg *pdiscon);
/******************************************************************************
* FunctionName : espconn_udp_server
* Description : Initialize the server: set up a PCB and bind it to the port
* Parameters : pespconn -- the espconn used to build server
* Returns : none
*******************************************************************************/
extern sint8 espconn_udp_server(struct espconn *espconn);
/******************************************************************************
* FunctionName : espconn_udp_sent
* Description : sent data for client or server
* Parameters : void *arg -- client or server to send
* uint8* psent -- Data to send
* uint16 length -- Length of data to send
* Returns : none
*******************************************************************************/
extern err_t espconn_udp_sent(void *arg, uint8 *psent, uint16 length);
/******************************************************************************
* FunctionName : espconn_udp_sendto
* Description : sent data for UDP
* Parameters : void *arg -- UDP to send
* uint8* psent -- Data to send
* uint16 length -- Length of data to send
* Returns : return espconn error code.
* - ESPCONN_OK. Successful. No error occured.
* - ESPCONN_MEM. Out of memory.
* - ESPCONN_RTE. Could not find route to destination address.
* - More errors could be returned by lower protocol layers.
*******************************************************************************/
extern err_t espconn_udp_sendto(void *arg, uint8 *psent, uint16 length);
#endif /* __ESPCONN_UDP_H__ */

View File

@ -0,0 +1,85 @@
#ifndef __PING_H__
#define __PING_H__
#include "lwip/ip_addr.h"
#include "lwip/icmp.h"
/**
* PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used
*/
#ifndef PING_USE_SOCKETS
#define PING_USE_SOCKETS LWIP_SOCKET
#endif
/**
* PING_DEBUG: Enable debugging for PING.
*/
#ifndef PING_DEBUG
#define PING_DEBUG LWIP_DBG_OFF
#endif
/** ping receive timeout - in milliseconds */
#ifndef PING_RCV_TIMEO
#define PING_RCV_TIMEO 1000
#endif
/** ping delay - in milliseconds */
#ifndef PING_COARSE
#define PING_COARSE 1000
#endif
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
#define PING_ID 0xAFAF
#endif
/** ping additional data size to include in the packet */
#ifndef PING_DATA_SIZE
#define PING_DATA_SIZE 32
#endif
/** ping result action - no default action */
#ifndef PING_RESULT
#define PING_RESULT(ping_ok)
#endif
#define DEFAULT_PING_MAX_COUNT 4
#define PING_TIMEOUT_MS 1000
typedef void (* ping_recv_function)(void* arg, void *pdata);
typedef void (* ping_sent_function)(void* arg, void *pdata);
struct ping_option{
uint32 count;
uint32 ip;
uint32 coarse_time;
ping_recv_function recv_function;
ping_sent_function sent_function;
void* reverse;
};
struct ping_msg{
struct ping_option *ping_opt;
struct raw_pcb *ping_pcb;
uint32 ping_start;
uint32 ping_sent;
uint32 timeout_count;
uint32 max_count;
uint32 sent_count;
uint32 coarse_time;
};
struct ping_resp{
uint32 total_count;
uint32 resp_time;
uint32 seqno;
uint32 timeout_count;
uint32 bytes;
uint32 total_bytes;
uint32 total_time;
sint8 ping_err;
};
bool ping_start(struct ping_option *ping_opt);
bool ping_regist_recv(struct ping_option *ping_opt, ping_recv_function ping_recv);
bool ping_regist_sent(struct ping_option *ping_opt, ping_sent_function ping_sent);
#endif /* __PING_H__ */

View File

@ -207,6 +207,15 @@ void dhcp_fine_tmr(void);
#define DHCP_OPTION_TCP_TTL 37
#define DHCP_OPTION_END 255
/**add options for support more router by liuHan**/
#define DHCP_OPTION_DOMAIN_NAME 15
#define DHCP_OPTION_PRD 31
#define DHCP_OPTION_STATIC_ROUTER 33
#define DHCP_OPTION_VSN 43
#define DHCP_OPTION_NB_TINS 44
#define DHCP_OPTION_NB_TINT 46
#define DHCP_OPTION_NB_TIS 47
#define DHCP_OPTION_CLASSLESS_STATIC_ROUTER 121
/** DHCP options */
#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */

View File

@ -96,7 +96,7 @@ void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)ICACHE_FLAS
err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr)ICACHE_FLASH_ATTR;
err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr)ICACHE_FLASH_ATTR;
void igmp_tmr(void)ICACHE_FLASH_ATTR;
#define LWIP_RAND() rand()
#define LWIP_RAND() r_rand()
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,114 @@
/**
* lwip MDNS resolver header file.
*
* Created on: Jul 29, 2010
* Author: Daniel Toma
* ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LWIP_DNS_H__
#define __LWIP_DNS_H__
#include "lwip/opt.h"
#if LWIP_MDNS /* don't build if not configured for use in lwipopts.h */
/** DNS timer period */
#define DNS_TMR_INTERVAL 1000
/** mDNS Address offset flag*/
#define DNS_OFFSET_FLAG 0xC0 /* the offset flag in the DNS message */
#define DNS_DEFAULT_OFFSET 0x0C /* the offset is set at the beginning of the DNS message */
#define DNS_IP_ADDR_LEN 4
/** DNS field TYPE used for "Resource Records" */
#define DNS_RRTYPE_A 1 /* a host address */
#define DNS_RRTYPE_NS 2 /* an authoritative name server */
#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */
#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */
#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */
#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */
#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */
#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */
#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */
#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */
#define DNS_RRTYPE_WKS 11 /* a well known service description */
#define DNS_RRTYPE_PTR 12 /* a domain name pointer */
#define DNS_RRTYPE_HINFO 13 /* host information */
#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */
#define DNS_RRTYPE_MX 15 /* mail exchange */
#define DNS_RRTYPE_TXT 16 /* text strings */
#define DNS_RRTYPE_SRV 33 /* Service record */
#define DNS_RRTYPE_OPT 41 /* EDNS0 OPT record */
#define DNS_RRTYPE_TSIG 250 /* Transaction Signature */
#define DNS_RRTYPE_ANY 255 /*Not a DNS type, but a DNS query type, meaning "all types"*/
/* DNS field CLASS used for "Resource Records" */
#define DNS_RRCLASS_IN 1 /* the Internet */
#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
#define DNS_RRCLASS_CH 3 /* the CHAOS class */
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
#define DNS_RRCLASS_FLUSH_IN 0x8001/* Flush bit and Internet*/
/** Callback which is invoked when a hostname is found.
* A function of this type must be implemented by the application using the DNS resolver.
* @param name pointer to the name that was looked up.
* @param ipaddr pointer to a struct ip_addr containing the IP address of the hostname,
* or NULL if the name could not be found (or on any other error).
* @param callback_arg a user-specified callback argument passed to dns_gethostbyname
*/
#ifndef _MDNS_INFO
#define _MDNS_INFO
struct mdns_info {
char *host_name;
char *server_name;
uint16 server_port;
unsigned long ipAddr;
char *txt_data[10];
};
#endif
//void mdns_enable(void);
//void mdns_disable(void);
//void mdns_init(struct mdns_info *info);
//void mdns_close(void);
//char* mdns_get_hostname(void);
//void mdns_set_hostname(char *name);
//void mdns_set_servername(const char *name);
//char* mdns_get_servername(void);
//void mdns_server_unregister(void);
//void mdns_server_register(void) ;
//void mdns_tmr(void);
//void Delay(unsigned long ulSeconds);
#endif /* LWIP_DNS */
#endif /* __LWIP_DNS_H__ */

View File

@ -33,7 +33,7 @@
#define __LWIP_MEM_H__
#include "lwip/opt.h"
#include "mem_manager.h"
//#include "mem_manager.h"
#ifdef __cplusplus
extern "C" {

View File

@ -76,7 +76,7 @@ typedef enum {
#endif /* MEM_USE_POOLS */
#if MEMP_MEM_MALLOC || MEM_USE_POOLS
extern const u16_t memp_sizes[MEMP_MAX];
extern const u32_t memp_sizes[MEMP_MAX];
#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */
#if MEMP_MEM_MALLOC

View File

@ -130,6 +130,9 @@ typedef void (*netif_status_callback_fn)(struct netif *netif);
typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif,
ip_addr_t *group, u8_t action);
/*add DHCP event processing by LiuHan*/
typedef void (*dhcp_event_fn)(void);
/** Generic data structure used for all lwIP network interfaces.
* The following fields should be filled in by the initialization
* function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
@ -169,6 +172,8 @@ struct netif {
#if LWIP_DHCP
/** the DHCP client state information for this netif */
struct dhcp *dhcp;
struct udp_pcb *dhcps_pcb; //dhcps
dhcp_event_fn dhcp_event;
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
/** the AutoIP client state information for this netif */

View File

@ -42,7 +42,7 @@
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
#include "include/lwipopts.h"
#include "lwipopts.h"
#include "lwip/debug.h"
/*

View File

@ -0,0 +1,44 @@
/*
* puck_def.h
*
* Created on: Jul 22, 2010
* Author: dtoma
*/
#ifndef PUCK_DEF_H_
#define PUCK_DEF_H_
#define INSTRUMENT_PORT 8760
#define INSTRUMENT_LENGTH 80
#define MDNS_NAME_LENGTH 68 //68
char* PUCK_SERVICE = NULL;
//#define PUCK_SERVICE "_Escpressif._tcp.local"
#define DNS_SD_SERVICE "_services._dns-sd._udp.local"
#define SERVICE_DESCRIPTION "PUCK PROTOCOL"
#define PUCK_SERVICE_LENGTH 30
#define UUID_LEN 16
#define DS_VERS_LEN 2
#define DS_SIZE_LEN 2
#define MAN_ID_LEN 4
#define MAN_MODEL_LEN 2
#define MAN_VERS_LEN 2
#define SER_NUM_LEN 4
#define NAME_LEN 64
#define PUCK_DATASHEET_SIZE 96
#define UUID_OFFSET 0
#define DS_VERS_OFFSET UUID_LEN + UUID_OFFSET
#define DS_SIZE_OFFSET DS_VERS_LEN + DS_VERS_OFFSET
#define MAN_ID_OFFSET DS_SIZE_LEN + DS_SIZE_OFFSET
#define MAN_MODEL_OFFSET MAN_ID_LEN + MAN_ID_OFFSET
#define MAN_VERS_OFFSET MAN_MODEL_LEN + MAN_MODEL_OFFSET
#define SER_NUM_OFFSET MAN_VERS_LEN + MAN_VERS_OFFSET
#define NAME_OFFSET SER_NUM_LEN + SER_NUM_OFFSET
#endif /* __PUCK_DEF_H__ */

View File

@ -0,0 +1,56 @@
#ifndef LWIP_SNTP_H
#define LWIP_SNTP_H
#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
/** The maximum number of SNTP servers that can be set */
#ifndef SNTP_MAX_SERVERS
#define SNTP_MAX_SERVERS 3
#endif
/** Set this to 1 to implement the callback function called by dhcp when
* NTP servers are received. */
#ifndef SNTP_GET_SERVERS_FROM_DHCP
#define SNTP_GET_SERVERS_FROM_DHCP 0//LWIP_DHCP_GET_NTP_SRV
#endif
/* Set this to 1 to support DNS names (or IP address strings) to set sntp servers */
#ifndef SNTP_SERVER_DNS
#define SNTP_SERVER_DNS 1
#endif
/** One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
* #define SNTP_SERVER_ADDRESS "pool.ntp.org"
*/
uint32 sntp_get_current_timestamp();
char* sntp_get_real_time(long t);
void sntp_init(void);
void sntp_stop(void);
sint8 sntp_get_timezone(void);
bool sntp_set_timezone(sint8 timezone);
void sntp_setserver(u8_t idx, ip_addr_t *addr);
ip_addr_t sntp_getserver(u8_t idx);
#if SNTP_SERVER_DNS
void sntp_setservername(u8_t idx, char *server);
char *sntp_getservername(u8_t idx);
#endif /* SNTP_SERVER_DNS */
#if SNTP_GET_SERVERS_FROM_DHCP
void sntp_servermode_dhcp(int set_servers_from_dhcp);
#else /* SNTP_GET_SERVERS_FROM_DHCP */
#define sntp_servermode_dhcp(x)
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_SNTP_H */

View File

@ -113,7 +113,7 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
#define TCP_HLEN 20
#ifndef TCP_TMR_INTERVAL
#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */
#define TCP_TMR_INTERVAL 125 /* The TCP timer interval in milliseconds. */
#endif /* TCP_TMR_INTERVAL */
#ifndef TCP_FAST_INTERVAL
@ -135,15 +135,15 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
#ifndef TCP_KEEPIDLE_DEFAULT
#define TCP_KEEPIDLE_DEFAULT 3000UL /* Default KEEPALIVE timer in milliseconds */
#define TCP_KEEPIDLE_DEFAULT 120000UL /* Default KEEPALIVE timer in milliseconds */
#endif
#ifndef TCP_KEEPINTVL_DEFAULT
#define TCP_KEEPINTVL_DEFAULT 1000UL /* Default Time between KEEPALIVE probes in milliseconds */
#define TCP_KEEPINTVL_DEFAULT 10000UL /* Default Time between KEEPALIVE probes in milliseconds */
#endif
#ifndef TCP_KEEPCNT_DEFAULT
#define TCP_KEEPCNT_DEFAULT 3U /* Default Counter for KEEPALIVE probes */
#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */
#endif
#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
@ -156,14 +156,14 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
#endif
PACK_STRUCT_BEGIN
struct tcp_hdr {
PACK_STRUCT_FIELD(u16_t src); //源端口
PACK_STRUCT_FIELD(u16_t dest); //目的端口
PACK_STRUCT_FIELD(u32_t seqno); //序号
PACK_STRUCT_FIELD(u32_t ackno); //应答序号
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);//首部长度+保留位+标志位
PACK_STRUCT_FIELD(u16_t wnd); //窗口大小
PACK_STRUCT_FIELD(u16_t chksum); //校验和
PACK_STRUCT_FIELD(u16_t urgp); //紧急指针
PACK_STRUCT_FIELD(u16_t src); //Դ<EFBFBD>˿<EFBFBD>
PACK_STRUCT_FIELD(u16_t dest); //Ŀ<EFBFBD>Ķ˿<EFBFBD>
PACK_STRUCT_FIELD(u32_t seqno); //<EFBFBD><EFBFBD><EFBFBD>
PACK_STRUCT_FIELD(u32_t ackno); //Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);//<EFBFBD>ײ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD><EFBFBD>λ+<2B><>־λ
PACK_STRUCT_FIELD(u16_t wnd); //<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>С
PACK_STRUCT_FIELD(u16_t chksum); //У<EFBFBD><EFBFBD><EFBFBD>
PACK_STRUCT_FIELD(u16_t urgp); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES

View File

@ -38,10 +38,9 @@
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#define PBUF_RSV_FOR_WLAN
#define EBUF_LWIP
#define EBUF_LWIP 1
#define LWIP_ESP 1
#define EP_OFFSET 36
/*
-----------------------------------------------
---------- Platform specific locking ----------
@ -245,7 +244,7 @@
* (requires the LWIP_TCP option)
*/
#ifndef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB (*((volatile uint32*)0x600011FC))
#define MEMP_NUM_TCP_PCB (*(volatile uint32*)0x600011FC)
#endif
/**
@ -308,7 +307,7 @@
* (requires NO_SYS==0)
*/
#ifndef MEMP_NUM_SYS_TIMEOUT
#define MEMP_NUM_SYS_TIMEOUT 6
#define MEMP_NUM_SYS_TIMEOUT 8
#endif
/**
@ -534,7 +533,7 @@
* in this time, the whole packet is discarded.
*/
#ifndef IP_REASS_MAXAGE
#define IP_REASS_MAXAGE 0
#define IP_REASS_MAXAGE 3
#endif
/**
@ -544,7 +543,7 @@
* packets even if the maximum amount of fragments is enqueued for reassembly!
*/
#ifndef IP_REASS_MAX_PBUFS
#define IP_REASS_MAX_PBUFS 0
#define IP_REASS_MAX_PBUFS 10
#endif
/**
@ -633,7 +632,7 @@
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
*/
#ifndef LWIP_RAW
#define LWIP_RAW 0
#define LWIP_RAW 1
#endif
/**
@ -662,6 +661,13 @@
#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP))
#endif
/**
* DHCP_MAXRTX: Maximum number of retries of current request.
*/
#ifndef DHCP_MAXRTX
#define DHCP_MAXRTX (*(volatile uint32*)0x600011E0)
#endif
/*
------------------------------------
---------- AUTOIP options ----------
@ -774,6 +780,17 @@
#ifndef LWIP_IGMP
#define LWIP_IGMP 1
#endif
/*
----------------------------------
---------- MDNS options ----------
----------------------------------
*/
/**
* LWIP_MDNS==1: Turn on MDNS module.
*/
#ifndef LWIP_MDNS
#define LWIP_MDNS 1
#endif
/*
----------------------------------
@ -890,21 +907,35 @@
* (2 * TCP_MSS) for things to work well
*/
#ifndef TCP_WND
#define TCP_WND (4 * TCP_MSS)
#define TCP_WND (*(volatile uint32*)0x600011F0)
#endif
/**
* TCP_MAXRTX: Maximum number of retransmissions of data segments.
*/
#ifndef TCP_MAXRTX
#define TCP_MAXRTX 5
#define TCP_MAXRTX (*(volatile uint32*)0x600011E8)
#endif
/**
* TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments.
*/
#ifndef TCP_SYNMAXRTX
#define TCP_SYNMAXRTX 5
#define TCP_SYNMAXRTX (*(volatile uint32*)0x600011E4)
#endif
/**
* TCP_MAXRTO: Maximum retransmission timeout of data segments.
*/
#ifndef TCP_MAXRTO
#define TCP_MAXRTO 10
#endif
/**
* TCP_MINRTO: Minimum retransmission timeout of data segments.
*/
#ifndef TCP_MINRTO
#define TCP_MINRTO 2
#endif
/**
@ -912,9 +943,10 @@
* Define to 0 if your device is low on memory.
*/
#ifndef TCP_QUEUE_OOSEQ
#define TCP_QUEUE_OOSEQ 0
#define TCP_QUEUE_OOSEQ 1
#endif
#if 1
/**
* TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
* you might want to increase this.)
@ -925,6 +957,7 @@
#ifndef TCP_MSS
#define TCP_MSS 1460
#endif
#endif
/**
* TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really
@ -1070,7 +1103,7 @@
* field.
*/
#ifndef LWIP_NETIF_HOSTNAME
#define LWIP_NETIF_HOSTNAME 0
#define LWIP_NETIF_HOSTNAME 1
#endif
/**

View File

@ -0,0 +1,254 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
* Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_ETHARP_H__
#define __NETIF_ETHARP_H__
#include "lwip/opt.h"
#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ETHARP_HWADDR_LEN
#define ETHARP_HWADDR_LEN 6
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct eth_addr {
PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** Ethernet header */
struct eth_hdr {
#if ETH_PAD_SIZE
PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
#endif
PACK_STRUCT_FIELD(struct eth_addr dest);
PACK_STRUCT_FIELD(struct eth_addr src);
PACK_STRUCT_FIELD(u16_t type);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE)
#if ETHARP_SUPPORT_VLAN
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** VLAN header inserted between ethernet header and payload
* if 'type' in ethernet header is ETHTYPE_VLAN.
* See IEEE802.Q */
struct eth_vlan_hdr {
PACK_STRUCT_FIELD(u16_t tpid);
PACK_STRUCT_FIELD(u16_t prio_vid);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_VLAN_HDR 4
#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF)
#endif /* ETHARP_SUPPORT_VLAN */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** the ARP message, see RFC 826 ("Packet format") */
struct etharp_hdr {
PACK_STRUCT_FIELD(u16_t hwtype);
PACK_STRUCT_FIELD(u16_t proto);
PACK_STRUCT_FIELD(u8_t hwlen);
PACK_STRUCT_FIELD(u8_t protolen);
PACK_STRUCT_FIELD(u16_t opcode);
PACK_STRUCT_FIELD(struct eth_addr shwaddr);
PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);
PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_ETHARP_HDR 28
#define SIZEOF_ETHARP_MINSIZE 46
#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR)
#define SIZEOF_ETHARP_WITHPAD (SIZEOF_ETH_HDR + SIZEOF_ETHARP_MINSIZE)
/** 5 seconds period */
#define ARP_TMR_INTERVAL 5000
#define ETHTYPE_ARP 0x0806
#define ETHTYPE_IP 0x0800
#define ETHTYPE_VLAN 0x8100
#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
#define ETHTYPE_PAE 0x888e
/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
* or known to be 32-bit aligned within the protocol header. */
#ifndef ETHADDR32_COPY
#define ETHADDR32_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN)
#endif
/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local
* variables and known to be 16-bit aligned within the protocol header. */
#ifndef ETHADDR16_COPY
#define ETHADDR16_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN)
#endif
#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
/** ARP message types (opcodes) */
#define ARP_REQUEST 1
#define ARP_REPLY 2
/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type)
* to a filter function that returns the correct netif when using multiple
* netifs on one hardware interface where the netif's low-level receive
* routine cannot decide for the correct netif (e.g. when mapping multiple
* IP addresses to one hardware interface).
*/
#ifndef LWIP_ARP_FILTER_NETIF
#define LWIP_ARP_FILTER_NETIF 0
#endif
#if ARP_QUEUEING
/** struct for queueing outgoing packets for unknown address
* defined here to be accessed by memp.h
*/
struct etharp_q_entry {
struct etharp_q_entry *next;
struct pbuf *p;
};
#endif /* ARP_QUEUEING */
#define etharp_init() /* Compatibility define, not init needed. */
void etharp_tmr(void)ICACHE_FLASH_ATTR;
s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,
struct eth_addr **eth_ret, ip_addr_t **ip_ret)ICACHE_FLASH_ATTR;
err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)ICACHE_FLASH_ATTR;
err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
/** For Ethernet network interfaces, we might want to send "gratuitous ARP";
* this is an ARP packet sent by a node in order to spontaneously cause other
* nodes to update an entry in their ARP cache.
* From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */
#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr)
void etharp_cleanup_netif(struct netif *netif);
#if ETHARP_SUPPORT_STATIC_ENTRIES
err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)ICACHE_FLASH_ATTR;
err_t etharp_remove_static_entry(ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
#if LWIP_AUTOIP
err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
const struct eth_addr *ethdst_addr,
const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr,
const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr,
const u16_t opcode)ICACHE_FLASH_ATTR;
#endif /* LWIP_AUTOIP */
#endif /* LWIP_ARP */
err_t ethernet_input(struct pbuf *p, struct netif *netif)ICACHE_FLASH_ATTR;
#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0)
extern const struct eth_addr ethbroadcast, ethzero;
#endif /* LWIP_ARP || LWIP_ETHERNET */
#if 0
/** Ethernet header */
#ifndef ETHARP_HWADDR_LEN
#define ETHARP_HWADDR_LEN 6
#endif
struct eth_addr {
PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]);
} PACK_STRUCT_STRUCT;
struct eth_hdr {
#if ETH_PAD_SIZE
PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
#endif
PACK_STRUCT_FIELD(struct eth_addr dest);
PACK_STRUCT_FIELD(struct eth_addr src);
PACK_STRUCT_FIELD(u16_t type);
} PACK_STRUCT_STRUCT;
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE)
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NETIF_ARP_H__ */

View File

@ -0,0 +1,173 @@
/* $NetBSD: if_llc.h,v 1.12 1999/11/19 20:41:19 thorpej Exp $ */
/*-
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_llc.h 8.1 (Berkeley) 6/10/93
* $FreeBSD$
*/
#ifndef _NET_IF_LLC_H_
#define _NET_IF_LLC_H_
/*
* IEEE 802.2 Link Level Control headers, for use in conjunction with
* 802.{3,4,5} media access control methods.
*
* Headers here do not use bit fields due to shortcommings in many
* compilers.
*/
struct llc {
uint8_t llc_dsap;
uint8_t llc_ssap;
union {
struct {
uint8_t control;
uint8_t format_id;
uint8_t class;
uint8_t window_x2;
} __packed type_u;
struct {
uint8_t num_snd_x2;
uint8_t num_rcv_x2;
} __packed type_i;
struct {
uint8_t control;
uint8_t num_rcv_x2;
} __packed type_s;
struct {
uint8_t control;
/*
* We cannot put the following fields in a structure because
* the structure rounding might cause padding.
*/
uint8_t frmr_rej_pdu0;
uint8_t frmr_rej_pdu1;
uint8_t frmr_control;
uint8_t frmr_control_ext;
uint8_t frmr_cause;
} __packed type_frmr;
struct {
uint8_t control;
uint8_t org_code[3];
uint16_t ether_type;
} __packed type_snap;
struct {
uint8_t control;
uint8_t control_ext;
} __packed type_raw;
} __packed llc_un;
} __packed;
struct frmrinfo {
uint8_t frmr_rej_pdu0;
uint8_t frmr_rej_pdu1;
uint8_t frmr_control;
uint8_t frmr_control_ext;
uint8_t frmr_cause;
} __packed;
#define llc_control llc_un.type_u.control
#define llc_control_ext llc_un.type_raw.control_ext
#define llc_fid llc_un.type_u.format_id
#define llc_class llc_un.type_u.class
#define llc_window llc_un.type_u.window_x2
#define llc_frmrinfo llc_un.type_frmr.frmr_rej_pdu0
#define llc_frmr_pdu0 llc_un.type_frmr.frmr_rej_pdu0
#define llc_frmr_pdu1 llc_un.type_frmr.frmr_rej_pdu1
#define llc_frmr_control llc_un.type_frmr.frmr_control
#define llc_frmr_control_ext llc_un.type_frmr.frmr_control_ext
#define llc_frmr_cause llc_un.type_frmr.frmr_cause
#define llc_snap llc_un.type_snap
/*
* Don't use sizeof(struct llc_un) for LLC header sizes
*/
#define LLC_ISFRAMELEN 4
#define LLC_UFRAMELEN 3
#define LLC_FRMRLEN 7
#define LLC_SNAPFRAMELEN 8
#ifdef CTASSERT
CTASSERT(sizeof (struct llc) == LLC_SNAPFRAMELEN);
#endif
/*
* Unnumbered LLC format commands
*/
#define LLC_UI 0x3
#define LLC_UI_P 0x13
#define LLC_DISC 0x43
#define LLC_DISC_P 0x53
#define LLC_UA 0x63
#define LLC_UA_P 0x73
#define LLC_TEST 0xe3
#define LLC_TEST_P 0xf3
#define LLC_FRMR 0x87
#define LLC_FRMR_P 0x97
#define LLC_DM 0x0f
#define LLC_DM_P 0x1f
#define LLC_XID 0xaf
#define LLC_XID_P 0xbf
#define LLC_SABME 0x6f
#define LLC_SABME_P 0x7f
/*
* Supervisory LLC commands
*/
#define LLC_RR 0x01
#define LLC_RNR 0x05
#define LLC_REJ 0x09
/*
* Info format - dummy only
*/
#define LLC_INFO 0x00
/*
* ISO PDTR 10178 contains among others
*/
#define LLC_8021D_LSAP 0x42
#define LLC_X25_LSAP 0x7e
#define LLC_SNAP_LSAP 0xaa
#define LLC_ISO_LSAP 0xfe
#define RFC1042_LEN 6
#define RFC1042 {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
#define ETHERNET_TUNNEL {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}
/*
* copied from sys/net/ethernet.h
*/
#define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */
#define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */
#endif /* _NET_IF_LLC_H_ */

View File

@ -0,0 +1,190 @@
/*****************************************************************************
* ppp_oe.h - PPP Over Ethernet implementation for lwIP.
*
* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice and the following disclaimer are included verbatim in any
* distributions. No written agreement, license, or royalty fee is required
* for any of the authorized uses.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
* REVISION HISTORY
*
* 06-01-01 Marc Boucher <marc@mbsi.ca>
* Ported to lwIP.
*****************************************************************************/
/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Martin Husemann <martin@NetBSD.org>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PPP_OE_H
#define PPP_OE_H
#include "lwip/opt.h"
#if PPPOE_SUPPORT > 0
#include "netif/etharp.h"
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct pppoehdr {
PACK_STRUCT_FIELD(u8_t vertype);
PACK_STRUCT_FIELD(u8_t code);
PACK_STRUCT_FIELD(u16_t session);
PACK_STRUCT_FIELD(u16_t plen);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct pppoetag {
PACK_STRUCT_FIELD(u16_t tag);
PACK_STRUCT_FIELD(u16_t len);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define PPPOE_STATE_INITIAL 0
#define PPPOE_STATE_PADI_SENT 1
#define PPPOE_STATE_PADR_SENT 2
#define PPPOE_STATE_SESSION 3
#define PPPOE_STATE_CLOSING 4
/* passive */
#define PPPOE_STATE_PADO_SENT 1
#define PPPOE_HEADERLEN sizeof(struct pppoehdr)
#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */
#define PPPOE_TAG_EOL 0x0000 /* end of list */
#define PPPOE_TAG_SNAME 0x0101 /* service name */
#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */
#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */
#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */
#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */
#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */
#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */
#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */
#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */
#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */
#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */
#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */
#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */
#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */
#ifndef ETHERMTU
#define ETHERMTU 1500
#endif
/* two byte PPP protocol discriminator, then IP data */
#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2)
#ifndef PPPOE_MAX_AC_COOKIE_LEN
#define PPPOE_MAX_AC_COOKIE_LEN 64
#endif
struct pppoe_softc {
struct pppoe_softc *next;
struct netif *sc_ethif; /* ethernet interface we are using */
int sc_pd; /* ppp unit number */
void (*sc_linkStatusCB)(int pd, int up);
int sc_state; /* discovery phase or session connected */
struct eth_addr sc_dest; /* hardware address of concentrator */
u16_t sc_session; /* PPPoE session id */
#ifdef PPPOE_TODO
char *sc_service_name; /* if != NULL: requested name of service */
char *sc_concentrator_name; /* if != NULL: requested concentrator id */
#endif /* PPPOE_TODO */
u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */
size_t sc_ac_cookie_len; /* length of cookie data */
#ifdef PPPOE_SERVER
u8_t *sc_hunique; /* content of host unique we must echo back */
size_t sc_hunique_len; /* length of host unique */
#endif
int sc_padi_retried; /* number of PADI retries already done */
int sc_padr_retried; /* number of PADR retries already done */
};
#define pppoe_init() /* compatibility define, no initialization needed */
err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr);
err_t pppoe_destroy(struct netif *ifp);
int pppoe_connect(struct pppoe_softc *sc);
void pppoe_disconnect(struct pppoe_softc *sc);
void pppoe_disc_input(struct netif *netif, struct pbuf *p);
void pppoe_data_input(struct netif *netif, struct pbuf *p);
err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb);
/** used in ppp.c */
#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN)
#endif /* PPPOE_SUPPORT */
#endif /* PPP_OE_H */

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2010-2011 Espressif System
*
*/
#ifndef _WLAN_LWIP_IF_H_
#define _WLAN_LWIP_IF_H_
#define LWIP_IF0_PRIO 28
#define LWIP_IF1_PRIO 29
enum {
SIG_LWIP_RX = 0,
};
struct netif * eagle_lwip_if_alloc(struct ieee80211_conn *conn, const uint8 *macaddr, struct ip_info *info);
struct netif * eagle_lwip_getif(uint8 index);
#ifndef IOT_SIP_MODE
sint8 ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb);
#else
sint8 ieee80211_output_pbuf(struct ieee80211_conn *conn, esf_buf *eb);
#endif
#endif /* _WLAN_LWIP_IF_H_ */

View File

@ -0,0 +1,32 @@
TOOLS_PATH ?= ../../../xtensa-lx106-elf/bin/xtensa-lx106-elf-
LWIP_LIB ?= liblwip_src.a
SDK_PATH ?= $(abspath ../../)
BUILD_PATH = build
LWIP_SRCS = $(patsubst %.c,$(BUILD_PATH)/%.o,$(wildcard */*.c)) $(patsubst %.c,$(BUILD_PATH)/%.o,$(wildcard */*/*.c))
LWIP_INCLUDE = -Ibuild -I$(SDK_PATH)/include -I$(SDK_PATH)/lwip/include
BUILD_FLAGS = -c -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=gnu99 -ffunction-sections -fdata-sections
BUILD_DEFINES = -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ -DLWIP_OPEN_SRC
CC=$(TOOLS_PATH)gcc
AR=$(TOOLS_PATH)ar
$(BUILD_PATH)/%.h:
@mkdir -p $(dir $@)
@touch $@
$(BUILD_PATH)/%.o: %.c
@mkdir -p $(dir $@)
$(CC) $(BUILD_FLAGS) $(BUILD_DEFINES) $(LWIP_INCLUDE) $< -o $@
$(LWIP_LIB): $(BUILD_PATH)/user_config.h $(LWIP_SRCS)
$(AR) cru $(LWIP_LIB) $(LWIP_SRCS)
all: $(LWIP_LIB)
install: all
cp -f $(LWIP_LIB) $(SDK_PATH)/lib/$(LWIP_LIB)
clean:
@rm -rf $(BUILD_PATH) $(LWIP_LIB)

View File

@ -0,0 +1,740 @@
/**
* @file
* Sequential API External module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* This is the part of the API that is linked with
the application */
#include "lwip/opt.h"
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include <string.h>
/**
* Create a new netconn (of a specific type) that has a callback function.
* The corresponding pcb is also created.
*
* @param t the type of 'connection' to create (@see enum netconn_type)
* @param proto the IP protocol for RAW IP pcbs
* @param callback a function to call on status changes (RX available, TX'ed)
* @return a newly allocated struct netconn or
* NULL on memory error
*/
struct netconn*
netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
{
struct netconn *conn;
struct api_msg msg;
conn = netconn_alloc(t, callback);
if (conn != NULL) {
msg.function = do_newconn;
msg.msg.msg.n.proto = proto;
msg.msg.conn = conn;
if (TCPIP_APIMSG(&msg) != ERR_OK) {
LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
#if LWIP_TCP
LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
#endif /* LWIP_TCP */
sys_sem_free(&conn->op_completed);
sys_mbox_free(&conn->recvmbox);
memp_free(MEMP_NETCONN, conn);
return NULL;
}
}
return conn;
}
/**
* Close a netconn 'connection' and free its resources.
* UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
* after this returns.
*
* @param conn the netconn to delete
* @return ERR_OK if the connection was deleted
*/
err_t
netconn_delete(struct netconn *conn)
{
struct api_msg msg;
/* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
if (conn == NULL) {
return ERR_OK;
}
msg.function = do_delconn;
msg.msg.conn = conn;
tcpip_apimsg(&msg);
netconn_free(conn);
/* don't care for return value of do_delconn since it only calls void functions */
return ERR_OK;
}
/**
* Get the local or remote IP address and port of a netconn.
* For RAW netconns, this returns the protocol instead of a port!
*
* @param conn the netconn to query
* @param addr a pointer to which to save the IP address
* @param port a pointer to which to save the port (or protocol for RAW)
* @param local 1 to get the local IP address, 0 to get the remote one
* @return ERR_CONN for invalid connections
* ERR_OK if the information was retrieved
*/
err_t
netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
msg.function = do_getaddr;
msg.msg.conn = conn;
msg.msg.msg.ad.ipaddr = addr;
msg.msg.msg.ad.port = port;
msg.msg.msg.ad.local = local;
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Bind a netconn to a specific local IP address and port.
* Binding one netconn twice might not always be checked correctly!
*
* @param conn the netconn to bind
* @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY
* to bind to all addresses)
* @param port the local port to bind the netconn to (not used for RAW)
* @return ERR_OK if bound, any other err_t on failure
*/
err_t
netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
msg.function = do_bind;
msg.msg.conn = conn;
msg.msg.msg.bc.ipaddr = addr;
msg.msg.msg.bc.port = port;
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Connect a netconn to a specific remote IP address and port.
*
* @param conn the netconn to connect
* @param addr the remote IP address to connect to
* @param port the remote port to connect to (no used for RAW)
* @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise
*/
err_t
netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
msg.function = do_connect;
msg.msg.conn = conn;
msg.msg.msg.bc.ipaddr = addr;
msg.msg.msg.bc.port = port;
/* This is the only function which need to not block tcpip_thread */
err = tcpip_apimsg(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Disconnect a netconn from its current peer (only valid for UDP netconns).
*
* @param conn the netconn to disconnect
* @return TODO: return value is not set here...
*/
err_t
netconn_disconnect(struct netconn *conn)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
msg.function = do_disconnect;
msg.msg.conn = conn;
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Set a TCP netconn into listen mode
*
* @param conn the tcp netconn to set to listen mode
* @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1
* @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
* don't return any error (yet?))
*/
err_t
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
{
#if LWIP_TCP
struct api_msg msg;
err_t err;
/* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
LWIP_UNUSED_ARG(backlog);
LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
msg.function = do_listen;
msg.msg.conn = conn;
#if TCP_LISTEN_BACKLOG
msg.msg.msg.lb.backlog = backlog;
#endif /* TCP_LISTEN_BACKLOG */
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
#else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(backlog);
return ERR_ARG;
#endif /* LWIP_TCP */
}
/**
* Accept a new connection on a TCP listening netconn.
*
* @param conn the TCP listen netconn
* @param new_conn pointer where the new connection is stored
* @return ERR_OK if a new connection has been received or an error
* code otherwise
*/
err_t
netconn_accept(struct netconn *conn, struct netconn **new_conn)
{
#if LWIP_TCP
struct netconn *newconn;
err_t err;
#if TCP_LISTEN_BACKLOG
struct api_msg msg;
#endif /* TCP_LISTEN_BACKLOG */
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
*new_conn = NULL;
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;);
err = conn->last_err;
if (ERR_IS_FATAL(err)) {
/* don't recv on fatal errors: this might block the application task
waiting on acceptmbox forever! */
return err;
}
#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
return ERR_TIMEOUT;
}
#else
sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
#endif /* LWIP_SO_RCVTIMEO*/
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
if (newconn == NULL) {
/* connection has been closed */
NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
return ERR_CLSD;
}
#if TCP_LISTEN_BACKLOG
/* Let the stack know that we have accepted the connection. */
msg.function = do_recv;
msg.msg.conn = conn;
/* don't care for the return value of do_recv */
TCPIP_APIMSG(&msg);
#endif /* TCP_LISTEN_BACKLOG */
*new_conn = newconn;
/* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK;
#else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(new_conn);
return ERR_ARG;
#endif /* LWIP_TCP */
}
/**
* Receive data: actual implementation that doesn't care whether pbuf or netbuf
* is received
*
* @param conn the netconn from which to receive data
* @param new_buf pointer where a new pbuf/netbuf is stored when received data
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
*/
static err_t
netconn_recv_data(struct netconn *conn, void **new_buf)
{
void *buf = NULL;
u16_t len;
err_t err;
#if LWIP_TCP
struct api_msg msg;
#endif /* LWIP_TCP */
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
*new_buf = NULL;
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
err = conn->last_err;
if (ERR_IS_FATAL(err)) {
/* don't recv on fatal errors: this might block the application task
waiting on recvmbox forever! */
/* @todo: this does not allow us to fetch data that has been put into recvmbox
before the fatal error occurred - is that a problem? */
return err;
}
#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
return ERR_TIMEOUT;
}
#else
sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
#endif /* LWIP_SO_RCVTIMEO*/
#if LWIP_TCP
if (conn->type == NETCONN_TCP) {
if (!netconn_get_noautorecved(conn) || (buf == NULL)) {
/* Let the stack know that we have taken the data. */
/* TODO: Speedup: Don't block and wait for the answer here
(to prevent multiple thread-switches). */
msg.function = do_recv;
msg.msg.conn = conn;
if (buf != NULL) {
msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len;
} else {
msg.msg.msg.r.len = 1;
}
/* don't care for the return value of do_recv */
TCPIP_APIMSG(&msg);
}
/* If we are closed, we indicate that we no longer wish to use the socket */
if (buf == NULL) {
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
/* Avoid to lose any previous error code */
NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
return ERR_CLSD;
}
len = ((struct pbuf *)buf)->tot_len;
}
#endif /* LWIP_TCP */
#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
else
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
#if (LWIP_UDP || LWIP_RAW)
{
LWIP_ASSERT("buf != NULL", buf != NULL);
len = netbuf_len((struct netbuf *)buf);
}
#endif /* (LWIP_UDP || LWIP_RAW) */
#if LWIP_SO_RCVBUF
SYS_ARCH_DEC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
*new_buf = buf;
/* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK;
}
/**
* Receive data (in form of a pbuf) from a TCP netconn
*
* @param conn the netconn from which to receive data
* @param new_buf pointer where a new pbuf is stored when received data
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
* ERR_ARG if conn is not a TCP netconn
*/
err_t
netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
{
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) &&
netconn_type(conn) == NETCONN_TCP, return ERR_ARG;);
return netconn_recv_data(conn, (void **)new_buf);
}
/**
* Receive data (in form of a netbuf containing a packet buffer) from a netconn
*
* @param conn the netconn from which to receive data
* @param new_buf pointer where a new netbuf is stored when received data
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
*/
err_t
netconn_recv(struct netconn *conn, struct netbuf **new_buf)
{
#if LWIP_TCP
struct netbuf *buf = NULL;
err_t err;
#endif /* LWIP_TCP */
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
*new_buf = NULL;
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
#if LWIP_TCP
if (conn->type == NETCONN_TCP) {
struct pbuf *p = NULL;
/* This is not a listening netconn, since recvmbox is set */
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
if (buf == NULL) {
NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
return ERR_MEM;
}
err = netconn_recv_data(conn, (void **)&p);
if (err != ERR_OK) {
memp_free(MEMP_NETBUF, buf);
return err;
}
LWIP_ASSERT("p != NULL", p != NULL);
buf->p = p;
buf->ptr = p;
buf->port = 0;
ip_addr_set_any(&buf->addr);
*new_buf = buf;
/* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK;
} else
#endif /* LWIP_TCP */
{
#if (LWIP_UDP || LWIP_RAW)
return netconn_recv_data(conn, (void **)new_buf);
#endif /* (LWIP_UDP || LWIP_RAW) */
}
}
/**
* TCP: update the receive window: by calling this, the application
* tells the stack that it has processed data and is able to accept
* new data.
* ATTENTION: use with care, this is mainly used for sockets!
* Can only be used when calling netconn_set_noautorecved(conn, 1) before.
*
* @param conn the netconn for which to update the receive window
* @param length amount of data processed (ATTENTION: this must be accurate!)
*/
void
netconn_recved(struct netconn *conn, u32_t length)
{
#if LWIP_TCP
if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
(netconn_get_noautorecved(conn))) {
struct api_msg msg;
/* Let the stack know that we have taken the data. */
/* TODO: Speedup: Don't block and wait for the answer here
(to prevent multiple thread-switches). */
msg.function = do_recv;
msg.msg.conn = conn;
msg.msg.msg.r.len = length;
/* don't care for the return value of do_recv */
TCPIP_APIMSG(&msg);
}
#else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(length);
#endif /* LWIP_TCP */
}
/**
* Send data (in form of a netbuf) to a specific remote IP address and port.
* Only to be used for UDP and RAW netconns (not TCP).
*
* @param conn the netconn over which to send data
* @param buf a netbuf containing the data to send
* @param addr the remote IP address to which to send the data
* @param port the remote port to which to send the data
* @return ERR_OK if data was sent, any other err_t on error
*/
err_t
netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port)
{
if (buf != NULL) {
ip_addr_set(&buf->addr, addr);
buf->port = port;
return netconn_send(conn, buf);
}
return ERR_VAL;
}
/**
* Send data over a UDP or RAW netconn (that is already connected).
*
* @param conn the UDP or RAW netconn over which to send data
* @param buf a netbuf containing the data to send
* @return ERR_OK if data was sent, any other err_t on error
*/
err_t
netconn_send(struct netconn *conn, struct netbuf *buf)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
msg.function = do_send;
msg.msg.conn = conn;
msg.msg.msg.b = buf;
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Send data over a TCP netconn.
*
* @param conn the TCP netconn over which to send data
* @param dataptr pointer to the application buffer that contains the data to send
* @param size size of the application data to send
* @param apiflags combination of following flags :
* - NETCONN_COPY: data will be copied into memory belonging to the stack
* - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
* - NETCONN_DONTBLOCK: only write the data if all dat can be written at once
* @return ERR_OK if data was sent, any other err_t on error
*/
err_t
netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;);
if (size == 0) {
return ERR_OK;
}
/* @todo: for non-blocking write, check if 'size' would ever fit into
snd_queue or snd_buf */
msg.function = do_write;
msg.msg.conn = conn;
msg.msg.msg.w.dataptr = dataptr;
msg.msg.msg.w.apiflags = apiflags;
msg.msg.msg.w.len = size;
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
but if it is, this is done inside api_msg.c:do_write(), so we can use the
non-blocking version here. */
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Close ot shutdown a TCP netconn (doesn't delete it).
*
* @param conn the TCP netconn to close or shutdown
* @param how fully close or only shutdown one side?
* @return ERR_OK if the netconn was closed, any other err_t on error
*/
static err_t
netconn_close_shutdown(struct netconn *conn, u8_t how)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
msg.function = do_close;
msg.msg.conn = conn;
/* shutting down both ends is the same as closing */
msg.msg.msg.sd.shut = how;
/* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close,
don't use TCPIP_APIMSG here */
err = tcpip_apimsg(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
/**
* Close a TCP netconn (doesn't delete it).
*
* @param conn the TCP netconn to close
* @return ERR_OK if the netconn was closed, any other err_t on error
*/
err_t
netconn_close(struct netconn *conn)
{
/* shutting down both ends is the same as closing */
return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
}
/**
* Shut down one or both sides of a TCP netconn (doesn't delete it).
*
* @param conn the TCP netconn to shut down
* @return ERR_OK if the netconn was closed, any other err_t on error
*/
err_t
netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
{
return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
}
#if LWIP_IGMP
/**
* Join multicast groups for UDP netconns.
*
* @param conn the UDP netconn for which to change multicast addresses
* @param multiaddr IP address of the multicast group to join or leave
* @param netif_addr the IP address of the network interface on which to send
* the igmp message
* @param join_or_leave flag whether to send a join- or leave-message
* @return ERR_OK if the action was taken, any err_t on error
*/
err_t
netconn_join_leave_group(struct netconn *conn,
ip_addr_t *multiaddr,
ip_addr_t *netif_addr,
enum netconn_igmp join_or_leave)
{
struct api_msg msg;
err_t err;
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
msg.function = do_join_leave_group;
msg.msg.conn = conn;
msg.msg.msg.jl.multiaddr = multiaddr;
msg.msg.msg.jl.netif_addr = netif_addr;
msg.msg.msg.jl.join_or_leave = join_or_leave;
err = TCPIP_APIMSG(&msg);
NETCONN_SET_SAFE_ERR(conn, err);
return err;
}
#endif /* LWIP_IGMP */
#if LWIP_DNS
/**
* Execute a DNS query, only one IP address is returned
*
* @param name a string representation of the DNS host name to query
* @param addr a preallocated ip_addr_t where to store the resolved IP address
* @return ERR_OK: resolving succeeded
* ERR_MEM: memory error, try again later
* ERR_ARG: dns client not initialized or invalid hostname
* ERR_VAL: dns server response was invalid
*/
err_t
netconn_gethostbyname(const char *name, ip_addr_t *addr)
{
struct dns_api_msg msg;
err_t err;
sys_sem_t sem;
LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
err = sys_sem_new(&sem, 0);
if (err != ERR_OK) {
return err;
}
msg.name = name;
msg.addr = addr;
msg.err = &err;
msg.sem = &sem;
tcpip_callback(do_gethostbyname, &msg);
sys_sem_wait(&sem);
sys_sem_free(&sem);
return err;
}
#endif /* LWIP_DNS*/
#endif /* LWIP_NETCONN */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
/**
* @file
* Error Management module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/err.h"
#ifdef LWIP_DEBUG
static const char *err_strerr[] = {
"Ok.", /* ERR_OK 0 */
"Out of memory error.", /* ERR_MEM -1 */
"Buffer error.", /* ERR_BUF -2 */
"Timeout.", /* ERR_TIMEOUT -3 */
"Routing problem.", /* ERR_RTE -4 */
"Operation in progress.", /* ERR_INPROGRESS -5 */
"Illegal value.", /* ERR_VAL -6 */
"Operation would block.", /* ERR_WOULDBLOCK -7 */
"Connection aborted.", /* ERR_ABRT -8 */
"Connection reset.", /* ERR_RST -9 */
"Connection closed.", /* ERR_CLSD -10 */
"Not connected.", /* ERR_CONN -11 */
"Illegal argument.", /* ERR_ARG -12 */
"Address in use.", /* ERR_USE -13 */
"Low-level netif error.", /* ERR_IF -14 */
"Already connected.", /* ERR_ISCONN -15 */
};
/**
* Convert an lwip internal error to a string representation.
*
* @param err an lwip internal err_t
* @return a string representation for err
*/
const char *
lwip_strerr(err_t err)
{
return err_strerr[-err];
}
#endif /* LWIP_DEBUG */

View File

@ -0,0 +1,245 @@
/**
* @file
* Network buffer management
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
#include "lwip/netbuf.h"
#include "lwip/memp.h"
#include <string.h>
/**
* Create (allocate) and initialize a new netbuf.
* The netbuf doesn't yet contain a packet buffer!
* netbuf空间
* @return a pointer to a new netbuf
* NULL on lack of memory
*/
struct
netbuf *netbuf_new(void)
{
struct netbuf *buf;
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
if (buf != NULL) {
buf->p = NULL;
buf->ptr = NULL;
ip_addr_set_any(&buf->addr);
buf->port = 0;
#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
#if LWIP_CHECKSUM_ON_COPY
buf->flags = 0;
#endif /* LWIP_CHECKSUM_ON_COPY */
buf->toport_chksum = 0;
#if LWIP_NETBUF_RECVINFO
ip_addr_set_any(&buf->toaddr);
#endif /* LWIP_NETBUF_RECVINFO */
#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */
return buf;
} else {
return NULL;
}
}
/**
* Deallocate a netbuf allocated by netbuf_new().
* netbuf空间
* @param buf pointer to a netbuf allocated by netbuf_new()
*/
void
netbuf_delete(struct netbuf *buf)
{
if (buf != NULL) {
if (buf->p != NULL) {
pbuf_free(buf->p);
buf->p = buf->ptr = NULL;
}
memp_free(MEMP_NETBUF, buf);
}
}
/**
* Allocate memory for a packet buffer for a given netbuf.
*netbuf结构分配size大小的数据空间
* @param buf the netbuf for which to allocate a packet buffer
* @param size the size of the packet buffer to allocate
* @return pointer to the allocated memory
* NULL if no memory could be allocated
*/
void *
netbuf_alloc(struct netbuf *buf, u16_t size)
{
LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
/* Deallocate any previously allocated memory. */
if (buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
if (buf->p == NULL) {
return NULL;
}
LWIP_ASSERT("check that first pbuf can hold size",
(buf->p->len >= size));
buf->ptr = buf->p;
return buf->p->payload;
}
/**
* Free the packet buffer included in a netbuf
*netbuf结构指向的数据pbuf
* @param buf pointer to the netbuf which contains the packet buffer to free
*/
void
netbuf_free(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
if (buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = buf->ptr = NULL;
}
/**
* Let a netbuf reference existing (non-volatile) data.
*
* @param buf netbuf which should reference the data
* @param dataptr pointer to the data to reference
* @param size size of the data
* @return ERR_OK if data is referenced
* ERR_MEM if data couldn't be referenced due to lack of memory
*/
err_t
netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size)
{
LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;);
if (buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
if (buf->p == NULL) {
buf->ptr = NULL;
return ERR_MEM;
}
buf->p->payload = (void*)dataptr;
buf->p->len = buf->p->tot_len = size;
buf->ptr = buf->p;
return ERR_OK;
}
/**
* Chain one netbuf to another (@see pbuf_chain)
*
* @param head the first netbuf
* @param tail netbuf to chain after head, freed by this function, may not be reference after returning
*/
void
netbuf_chain(struct netbuf *head, struct netbuf *tail)
{
LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;);
LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;);
pbuf_cat(head->p, tail->p);
head->ptr = head->p;
memp_free(MEMP_NETBUF, tail);
}
/**
* Get the data pointer and length of the data inside a netbuf.
*
* @param buf netbuf to get the data from
* @param dataptr pointer to a void pointer where to store the data pointer
* @param len pointer to an u16_t where the length of the data is stored
* @return ERR_OK if the information was retreived,
* ERR_BUF on error.
*/
err_t
netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
{
LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;);
LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;);
if (buf->ptr == NULL) {
return ERR_BUF;
}
*dataptr = buf->ptr->payload;
*len = buf->ptr->len;
return ERR_OK;
}
/**
* Move the current data pointer of a packet buffer contained in a netbuf
* to the next part.
* The packet buffer itself is not modified.
*
* @param buf the netbuf to modify
* @return -1 if there is no next part
* 1 if moved to the next part but now there is no next part
* 0 if moved to the next part and there are still more parts
*/
s8_t
netbuf_next(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;);
if (buf->ptr->next == NULL) {
return -1;
}
buf->ptr = buf->ptr->next;
if (buf->ptr->next == NULL) {
return 1;
}
return 0;
}
/**
* Move the current data pointer of a packet buffer contained in a netbuf
* to the beginning of the packet.
* The packet buffer itself is not modified.
*
* @param buf the netbuf to modify
*/
void
netbuf_first(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
buf->ptr = buf->p;
}
#endif /* LWIP_NETCONN */

View File

@ -0,0 +1,352 @@
/**
* @file
* API functions for name resolving
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt
*
*/
#include "lwip/netdb.h"
#if LWIP_DNS && LWIP_SOCKET
#include "lwip/err.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/api.h"
#include "lwip/dns.h"
#include <string.h>
#include <stdlib.h>
/** helper struct for gethostbyname_r to access the char* buffer */
struct gethostbyname_r_helper {
ip_addr_t *addrs;
ip_addr_t addr;
char *aliases;
};
/** h_errno is exported in netdb.h for access by applications. */
#if LWIP_DNS_API_DECLARE_H_ERRNO
int h_errno;
#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
/** define "hostent" variables storage: 0 if we use a static (but unprotected)
* set of variables for lwip_gethostbyname, 1 if we use a local storage */
#ifndef LWIP_DNS_API_HOSTENT_STORAGE
#define LWIP_DNS_API_HOSTENT_STORAGE 0
#endif
/** define "hostent" variables storage */
#if LWIP_DNS_API_HOSTENT_STORAGE
#define HOSTENT_STORAGE
#else
#define HOSTENT_STORAGE static
#endif /* LWIP_DNS_API_STATIC_HOSTENT */
/**
* Returns an entry containing addresses of address family AF_INET
* for the host with name name.
* Due to dns_gethostbyname limitations, only one address is returned.
*
* @param name the hostname to resolve
* @return an entry containing addresses of address family AF_INET
* for the host with name name
*/
struct hostent*
lwip_gethostbyname(const char *name)
{
err_t err;
ip_addr_t addr;
/* buffer variables for lwip_gethostbyname() */
HOSTENT_STORAGE struct hostent s_hostent;
HOSTENT_STORAGE char *s_aliases;
HOSTENT_STORAGE ip_addr_t s_hostent_addr;
HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
/* query host IP address */
err = netconn_gethostbyname(name, &addr);
if (err != ERR_OK) {
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
h_errno = HOST_NOT_FOUND;
return NULL;
}
/* fill hostent */
s_hostent_addr = addr;
s_phostent_addr[0] = &s_hostent_addr;
s_phostent_addr[1] = NULL;
s_hostent.h_name = (char*)name;
s_hostent.h_aliases = &s_aliases;
s_hostent.h_addrtype = AF_INET;
s_hostent.h_length = sizeof(ip_addr_t);
s_hostent.h_addr_list = (char**)&s_phostent_addr;
#if DNS_DEBUG
/* dump hostent */
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases));
if (s_hostent.h_aliases != NULL) {
u8_t idx;
for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx]));
}
}
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list));
if (s_hostent.h_addr_list != NULL) {
u8_t idx;
for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx])));
}
}
#endif /* DNS_DEBUG */
#if LWIP_DNS_API_HOSTENT_STORAGE
/* this function should return the "per-thread" hostent after copy from s_hostent */
return sys_thread_hostent(&s_hostent);
#else
return &s_hostent;
#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
}
/**
* Thread-safe variant of lwip_gethostbyname: instead of using a static
* buffer, this function takes buffer and errno pointers as arguments
* and uses these for the result.
*
* @param name the hostname to resolve
* @param ret pre-allocated struct where to store the result
* @param buf pre-allocated buffer where to store additional data
* @param buflen the size of buf
* @param result pointer to a hostent pointer that is set to ret on success
* and set to zero on error
* @param h_errnop pointer to an int where to store errors (instead of modifying
* the global h_errno)
* @return 0 on success, non-zero on error, additional error information
* is stored in *h_errnop instead of h_errno to be thread-safe
*/
int
lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop)
{
err_t err;
struct gethostbyname_r_helper *h;
char *hostname;
size_t namelen;
int lh_errno;
if (h_errnop == NULL) {
/* ensure h_errnop is never NULL */
h_errnop = &lh_errno;
}
if (result == NULL) {
/* not all arguments given */
*h_errnop = EINVAL;
return -1;
}
/* first thing to do: set *result to nothing */
*result = NULL;
if ((name == NULL) || (ret == NULL) || (buf == 0)) {
/* not all arguments given */
*h_errnop = EINVAL;
return -1;
}
namelen = strlen(name);
if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
/* buf can't hold the data needed + a copy of name */
*h_errnop = ERANGE;
return -1;
}
h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
/* query host IP address */
err = netconn_gethostbyname(name, &(h->addr));
if (err != ERR_OK) {
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
*h_errnop = ENSRNOTFOUND;
return -1;
}
/* copy the hostname into buf */
MEMCPY(hostname, name, namelen);
hostname[namelen] = 0;
/* fill hostent */
h->addrs = &(h->addr);
h->aliases = NULL;
ret->h_name = (char*)hostname;
ret->h_aliases = &(h->aliases);
ret->h_addrtype = AF_INET;
ret->h_length = sizeof(ip_addr_t);
ret->h_addr_list = (char**)&(h->addrs);
/* set result != NULL */
*result = ret;
/* return success */
return 0;
}
/**
* Frees one or more addrinfo structures returned by getaddrinfo(), along with
* any additional storage associated with those structures. If the ai_next field
* of the structure is not null, the entire list of structures is freed.
*
* @param ai struct addrinfo to free
*/
void
lwip_freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
while (ai != NULL) {
next = ai->ai_next;
memp_free(MEMP_NETDB, ai);
ai = next;
}
}
/**
* Translates the name of a service location (for example, a host name) and/or
* a service name and returns a set of socket addresses and associated
* information to be used in creating a socket with which to address the
* specified service.
* Memory for the result is allocated internally and must be freed by calling
* lwip_freeaddrinfo()!
*
* Due to a limitation in dns_gethostbyname, only the first address of a
* host is returned.
* Also, service names are not supported (only port numbers)!
*
* @param nodename descriptive name or address string of the host
* (may be NULL -> local address)
* @param servname port number as string of NULL
* @param hints structure containing input values that set socktype and protocol
* @param res pointer to a pointer where to store the result (set to NULL on failure)
* @return 0 on success, non-zero on failure
*/
int
lwip_getaddrinfo(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
err_t err;
ip_addr_t addr;
struct addrinfo *ai;
struct sockaddr_in *sa = NULL;
int port_nr = 0;
size_t total_size;
size_t namelen = 0;
if (res == NULL) {
return EAI_FAIL;
}
*res = NULL;
if ((nodename == NULL) && (servname == NULL)) {
return EAI_NONAME;
}
if (servname != NULL) {
/* service name specified: convert to port number
* @todo?: currently, only ASCII integers (port numbers) are supported! */
port_nr = atoi(servname);
if ((port_nr <= 0) || (port_nr > 0xffff)) {
return EAI_SERVICE;
}
}
if (nodename != NULL) {
/* service location specified, try to resolve */
err = netconn_gethostbyname(nodename, &addr);
if (err != ERR_OK) {
return EAI_FAIL;
}
} else {
/* service location specified, use loopback address */
ip_addr_set_loopback(&addr);
}
total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
if (nodename != NULL) {
namelen = strlen(nodename);
LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
total_size += namelen + 1;
}
/* If this fails, please report to lwip-devel! :-) */
LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
total_size <= NETDB_ELEM_SIZE);
ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
if (ai == NULL) {
goto memerr;
}
memset(ai, 0, total_size);
sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo));
/* set up sockaddr */
inet_addr_from_ipaddr(&sa->sin_addr, &addr);
sa->sin_family = AF_INET;
sa->sin_len = sizeof(struct sockaddr_in);
sa->sin_port = htons((u16_t)port_nr);
/* set up addrinfo */
ai->ai_family = AF_INET;
if (hints != NULL) {
/* copy socktype & protocol from hints if specified */
ai->ai_socktype = hints->ai_socktype;
ai->ai_protocol = hints->ai_protocol;
}
if (nodename != NULL) {
/* copy nodename to canonname if specified */
ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
MEMCPY(ai->ai_canonname, nodename, namelen);
ai->ai_canonname[namelen] = 0;
}
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr = (struct sockaddr*)sa;
*res = ai;
return 0;
memerr:
if (ai != NULL) {
memp_free(MEMP_NETDB, ai);
}
return EAI_MEMORY;
}
#endif /* LWIP_DNS && LWIP_SOCKET */

View File

@ -0,0 +1,160 @@
/**
* @file
* Network Interface Sequential API module
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/opt.h"
#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
#include "lwip/netifapi.h"
#include "lwip/tcpip.h"
/**
* Call netif_add() inside the tcpip_thread context.
*/
void
do_netifapi_netif_add(struct netifapi_msg_msg *msg)
{
if (!netif_add( msg->netif,
msg->msg.add.ipaddr,
msg->msg.add.netmask,
msg->msg.add.gw,
msg->msg.add.state,
msg->msg.add.init,
msg->msg.add.input)) {
msg->err = ERR_IF;
} else {
msg->err = ERR_OK;
}
TCPIP_NETIFAPI_ACK(msg);
}
/**
* Call netif_set_addr() inside the tcpip_thread context.
*/
void
do_netifapi_netif_set_addr(struct netifapi_msg_msg *msg)
{
netif_set_addr( msg->netif,
msg->msg.add.ipaddr,
msg->msg.add.netmask,
msg->msg.add.gw);
msg->err = ERR_OK;
TCPIP_NETIFAPI_ACK(msg);
}
/**
* Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
* tcpip_thread context.
*/
void
do_netifapi_netif_common(struct netifapi_msg_msg *msg)
{
if (msg->msg.common.errtfunc != NULL) {
msg->err = msg->msg.common.errtfunc(msg->netif);
} else {
msg->err = ERR_OK;
msg->msg.common.voidfunc(msg->netif);
}
TCPIP_NETIFAPI_ACK(msg);
}
/**
* Call netif_add() in a thread-safe way by running that function inside the
* tcpip_thread context.
*
* @note for params @see netif_add()
*/
err_t
netifapi_netif_add(struct netif *netif,
ip_addr_t *ipaddr,
ip_addr_t *netmask,
ip_addr_t *gw,
void *state,
netif_init_fn init,
netif_input_fn input)
{
struct netifapi_msg msg;
msg.function = do_netifapi_netif_add;
msg.msg.netif = netif;
msg.msg.msg.add.ipaddr = ipaddr;
msg.msg.msg.add.netmask = netmask;
msg.msg.msg.add.gw = gw;
msg.msg.msg.add.state = state;
msg.msg.msg.add.init = init;
msg.msg.msg.add.input = input;
TCPIP_NETIFAPI(&msg);
return msg.msg.err;
}
/**
* Call netif_set_addr() in a thread-safe way by running that function inside the
* tcpip_thread context.
*
* @note for params @see netif_set_addr()
*/
err_t
netifapi_netif_set_addr(struct netif *netif,
ip_addr_t *ipaddr,
ip_addr_t *netmask,
ip_addr_t *gw)
{
struct netifapi_msg msg;
msg.function = do_netifapi_netif_set_addr;
msg.msg.netif = netif;
msg.msg.msg.add.ipaddr = ipaddr;
msg.msg.msg.add.netmask = netmask;
msg.msg.msg.add.gw = gw;
TCPIP_NETIFAPI(&msg);
return msg.msg.err;
}
/**
* call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
* way by running that function inside the tcpip_thread context.
*
* @note use only for functions where there is only "netif" parameter.
*/
err_t
netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
netifapi_errt_fn errtfunc)
{
struct netifapi_msg msg;
msg.function = do_netifapi_netif_common;
msg.msg.netif = netif;
msg.msg.msg.common.voidfunc = voidfunc;
msg.msg.msg.common.errtfunc = errtfunc;
TCPIP_NETIFAPI(&msg);
return msg.msg.err;
}
#endif /* LWIP_NETIF_API */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,460 @@
/**
* @file
* Sequential API Main thread module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
#include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/tcpip.h"
#include "lwip/init.h"
#include "netif/etharp.h"
#include "netif/ppp_oe.h"
/* global variables */
static tcpip_init_done_fn tcpip_init_done;
static void *tcpip_init_done_arg;
static sys_mbox_t mbox;
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
sys_mutex_t lock_tcpip_core;
#endif /* LWIP_TCPIP_CORE_LOCKING */
/**
* The main lwIP thread. This thread has exclusive access to lwIP core functions
* (unless access to them is not locked). Other threads communicate with this
* thread using message boxes.
*
* It also starts all the timers to make sure they are running in the right
* thread context.
*
* @param arg unused argument
*/
static void
tcpip_thread(void *arg)
{
struct tcpip_msg *msg;
LWIP_UNUSED_ARG(arg);
if (tcpip_init_done != NULL) {//用户注册了自定义初始化函数
tcpip_init_done(tcpip_init_done_arg);
}
LOCK_TCPIP_CORE();
while (1) { /* MAIN Loop */
UNLOCK_TCPIP_CORE();
LWIP_TCPIP_THREAD_ALIVE();
/* wait for a message, timeouts are processed while waiting */
sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
LOCK_TCPIP_CORE();
switch (msg->type) {
#if LWIP_NETCONN
case TCPIP_MSG_API://API调用
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
break;
#endif /* LWIP_NETCONN */
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
case TCPIP_MSG_INPKT://底层数据包输入
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
#if LWIP_ETHERNET
if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {//支持ARP
ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);//交给ARP处理
} else
#endif /* LWIP_ETHERNET */
{
ip_input(msg->msg.inp.p, msg->msg.inp.netif);//交给IP处理
}
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
break;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
#if LWIP_NETIF_API
case TCPIP_MSG_NETIFAPI:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
break;
#endif /* LWIP_NETIF_API */
case TCPIP_MSG_CALLBACK://上层回调方式执行一个函数
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
msg->msg.cb.function(msg->msg.cb.ctx);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
#if LWIP_TCPIP_TIMEOUT
case TCPIP_MSG_TIMEOUT://上层注册一个定时事件
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
case TCPIP_MSG_UNTIMEOUT://上层删除一个定时事件
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
#endif /* LWIP_TCPIP_TIMEOUT */
default:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
LWIP_ASSERT("tcpip_thread: invalid message", 0);
break;
}
}
}
/**
* Pass a received packet to tcpip_thread for input processing
*
* @param p the received packet, p->payload pointing to the Ethernet header or
* to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
* NETIF_FLAG_ETHERNET flags)
* @param inp the network interface on which the packet was received
*/
err_t
tcpip_input(struct pbuf *p, struct netif *inp)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
err_t ret;
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
LOCK_TCPIP_CORE();
#if LWIP_ETHERNET
if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
ret = ethernet_input(p, inp);
} else
#endif /* LWIP_ETHERNET */
{
ret = ip_input(p, inp);
}
UNLOCK_TCPIP_CORE();
return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
struct tcpip_msg *msg;
if (sys_mbox_valid(&mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_INPKT;
msg->msg.inp.p = p;
msg->msg.inp.netif = inp;
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
return ERR_MEM;
}
return ERR_OK;
}
return ERR_VAL;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}
/**
* Call a specific function in the thread context of
* tcpip_thread for easy access synchronization.
* A function called in that way may access lwIP core code
* without fearing concurrent access.
*
* @param f the function to call
* @param ctx parameter passed to f
* @param block 1 to block until the request is posted, 0 to non-blocking mode
* @return ERR_OK if the function was called, another err_t if not
*/
err_t
tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
{
struct tcpip_msg *msg;
if (sys_mbox_valid(&mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_CALLBACK;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
if (block) {
sys_mbox_post(&mbox, msg);
} else {
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
memp_free(MEMP_TCPIP_MSG_API, msg);
return ERR_MEM;
}
}
return ERR_OK;
}
return ERR_VAL;
}
#if LWIP_TCPIP_TIMEOUT
/**
* call sys_timeout in tcpip_thread
*
* @param msec time in milliseconds for timeout
* @param h function to be called on timeout
* @param arg argument to pass to timeout function h
* @return ERR_MEM on memory error, ERR_OK otherwise
*/
err_t
tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
{
struct tcpip_msg *msg;
if (sys_mbox_valid(&mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_TIMEOUT;
msg->msg.tmo.msecs = msecs;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
sys_mbox_post(&mbox, msg);
return ERR_OK;
}
return ERR_VAL;
}
/**
* call sys_untimeout in tcpip_thread
*
* @param msec time in milliseconds for timeout
* @param h function to be called on timeout
* @param arg argument to pass to timeout function h
* @return ERR_MEM on memory error, ERR_OK otherwise
*/
err_t
tcpip_untimeout(sys_timeout_handler h, void *arg)
{
struct tcpip_msg *msg;
if (sys_mbox_valid(&mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_UNTIMEOUT;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
sys_mbox_post(&mbox, msg);
return ERR_OK;
}
return ERR_VAL;
}
#endif /* LWIP_TCPIP_TIMEOUT */
#if LWIP_NETCONN
/**
* Call the lower part of a netconn_* function
* This function is then running in the thread context
* of tcpip_thread and has exclusive access to lwIP core code.
*
* @param apimsg a struct containing the function to call and its parameters
* @return ERR_OK if the function was called, another err_t if not
*/
err_t
tcpip_apimsg(struct api_msg *apimsg)
{
struct tcpip_msg msg;
#ifdef LWIP_DEBUG
/* catch functions that don't set err */
apimsg->msg.err = ERR_VAL;
#endif
if (sys_mbox_valid(&mbox)) {//内核邮箱有效
msg.type = TCPIP_MSG_API;
msg.msg.apimsg = apimsg;
sys_mbox_post(&mbox, &msg);//投递消息
sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);//等待消息处理完毕
return apimsg->msg.err;
}
return ERR_VAL;
}
#if LWIP_TCPIP_CORE_LOCKING
/**
* Call the lower part of a netconn_* function
* This function has exclusive access to lwIP core code by locking it
* before the function is called.
*
* @param apimsg a struct containing the function to call and its parameters
* @return ERR_OK (only for compatibility fo tcpip_apimsg())
*/
err_t
tcpip_apimsg_lock(struct api_msg *apimsg)
{
#ifdef LWIP_DEBUG
/* catch functions that don't set err */
apimsg->msg.err = ERR_VAL;
#endif
LOCK_TCPIP_CORE();
apimsg->function(&(apimsg->msg));
UNLOCK_TCPIP_CORE();
return apimsg->msg.err;
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
#endif /* LWIP_NETCONN */
#if LWIP_NETIF_API
#if !LWIP_TCPIP_CORE_LOCKING
/**
* Much like tcpip_apimsg, but calls the lower part of a netifapi_*
* function.
*
* @param netifapimsg a struct containing the function to call and its parameters
* @return error code given back by the function that was called
*/
err_t
tcpip_netifapi(struct netifapi_msg* netifapimsg)
{
struct tcpip_msg msg;
if (sys_mbox_valid(&mbox)) {
err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
if (err != ERR_OK) {
netifapimsg->msg.err = err;
return err;
}
msg.type = TCPIP_MSG_NETIFAPI;
msg.msg.netifapimsg = netifapimsg;
sys_mbox_post(&mbox, &msg);
sys_sem_wait(&netifapimsg->msg.sem);
sys_sem_free(&netifapimsg->msg.sem);
return netifapimsg->msg.err;
}
return ERR_VAL;
}
#else /* !LWIP_TCPIP_CORE_LOCKING */
/**
* Call the lower part of a netifapi_* function
* This function has exclusive access to lwIP core code by locking it
* before the function is called.
*
* @param netifapimsg a struct containing the function to call and its parameters
* @return ERR_OK (only for compatibility fo tcpip_netifapi())
*/
err_t
tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
{
LOCK_TCPIP_CORE();
netifapimsg->function(&(netifapimsg->msg));
UNLOCK_TCPIP_CORE();
return netifapimsg->msg.err;
}
#endif /* !LWIP_TCPIP_CORE_LOCKING */
#endif /* LWIP_NETIF_API */
/**
* Initialize this module:
* - initialize all sub modules
* - start the tcpip_thread
*
* @param initfunc a function to call when tcpip_thread is running and finished initializing
* @param arg argument to pass to initfunc
*/
void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
lwip_init();//初始化内核
tcpip_init_done = initfunc;//注册用户自定义函数
tcpip_init_done_arg = arg;//函数参数
if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {//创建内核邮箱
LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
}
#if LWIP_TCPIP_CORE_LOCKING
if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);//创建内核进程
}
/**
* Simple callback function used with tcpip_callback to free a pbuf
* (pbuf_free has a wrong signature for tcpip_callback)
*
* @param p The pbuf (chain) to be dereferenced.
*/
static void
pbuf_free_int(void *p)
{
struct pbuf *q = (struct pbuf *)p;
pbuf_free(q);
}
/**
* A simple wrapper function that allows you to free a pbuf from interrupt context.
*
* @param p The pbuf (chain) to be dereferenced.
* @return ERR_OK if callback could be enqueued, an err_t if not
*/
err_t
pbuf_free_callback(struct pbuf *p)
{
return tcpip_callback_with_block(pbuf_free_int, p, 0);
}
/**
* A simple wrapper function that allows you to free heap memory from
* interrupt context.
*
* @param m the heap memory to free
* @return ERR_OK if callback could be enqueued, an err_t if not
*/
err_t
mem_free_callback(void *m)
{
return tcpip_callback_with_block(mem_free, m, 0);
}
#endif /* !NO_SYS */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More