diff --git a/boards.txt b/boards.txt index 8ed16f539..248622f74 100644 --- a/boards.txt +++ b/boards.txt @@ -691,3 +691,83 @@ d1_mini.menu.FlashSize.4M1M.build.spiffs_start=0x300000 d1_mini.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000 d1_mini.menu.FlashSize.4M1M.build.spiffs_blocksize=8192 d1_mini.menu.FlashSize.4M1M.build.spiffs_pagesize=256 + + +############################################################## +espino.name=ESPino + +espino.upload.tool=esptool +espino.upload.speed=115200 +espino.upload.resetmethod=ck +espino.upload.maximum_size=1044464 +espino.upload.maximum_data_size=81920 +espino.upload.wait_for_upload_port=true +espino.serial.disableDTR=true +espino.serial.disableRTS=true + +espino.build.mcu=esp8266 +espino.build.f_cpu=80000000L +espino.build.board=ESP8266_ESP12 +espino.build.core=esp8266 +espino.build.variant=espino +espino.build.flash_mode=qio +espino.build.flash_size=4M +espino.build.flash_freq=40 +espino.build.spiffs_pagesize=256 + +espino.menu.UploadTool.esptool=Serial +espino.menu.UploadTool.esptool.upload.tool=esptool +espino.menu.UploadTool.esptool.upload.verbose=-vv +espino.menu.UploadTool.espota=OTA +espino.menu.UploadTool.espota.upload.tool=espota + +espino.menu.CpuFrequency.80=80 MHz +espino.menu.CpuFrequency.80.build.f_cpu=80000000L +espino.menu.CpuFrequency.160=160 MHz +espino.menu.CpuFrequency.160.build.f_cpu=160000000L + +espino.menu.FlashMode.dio=DIO +espino.menu.FlashMode.dio.build.flash_mode=dio +espino.menu.FlashMode.qio=QIO +espino.menu.FlashMode.qio.build.flash_mode=qio + +espino.menu.UploadSpeed.115200=115200 +espino.menu.UploadSpeed.115200.upload.speed=115200 +espino.menu.UploadSpeed.9600=9600 +espino.menu.UploadSpeed.9600.upload.speed=9600 +espino.menu.UploadSpeed.57600=57600 +espino.menu.UploadSpeed.57600.upload.speed=57600 +espino.menu.UploadSpeed.256000.windows=256000 +espino.menu.UploadSpeed.256000.upload.speed=256000 +espino.menu.UploadSpeed.230400.linux=230400 +espino.menu.UploadSpeed.230400.macosx=230400 +espino.menu.UploadSpeed.230400.upload.speed=230400 +espino.menu.UploadSpeed.460800.linux=460800 +espino.menu.UploadSpeed.460800.macosx=460800 +espino.menu.UploadSpeed.460800.upload.speed=460800 +espino.menu.UploadSpeed.512000.windows=512000 +espino.menu.UploadSpeed.512000.upload.speed=512000 +espino.menu.UploadSpeed.921600=921600 +espino.menu.UploadSpeed.921600.upload.speed=921600 + +espino.menu.FlashSize.4M1M=4M (1M SPIFFS) +espino.menu.FlashSize.4M1M.build.flash_size=4M +espino.menu.FlashSize.4M1M.build.flash_ld=eagle.flash.4m1m.ld +espino.menu.FlashSize.4M1M.build.spiffs_start=0x300000 +espino.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000 +espino.menu.FlashSize.4M1M.build.spiffs_blocksize=8192 +espino.menu.FlashSize.4M1M.build.spiffs_pagesize=256 +espino.menu.FlashSize.4M1M.upload.maximum_size=1044464 + +espino.menu.FlashSize.4M3M=4M (3M SPIFFS) +espino.menu.FlashSize.4M3M.build.flash_size=4M +espino.menu.FlashSize.4M3M.build.flash_ld=eagle.flash.4m.ld +espino.menu.FlashSize.4M3M.build.spiffs_start=0x100000 +espino.menu.FlashSize.4M3M.build.spiffs_end=0x3FB000 +espino.menu.FlashSize.4M3M.build.spiffs_blocksize=8192 +espino.menu.FlashSize.4M3M.upload.maximum_size=1044464 + +espino.menu.ResetMethod.ck=ck +espino.menu.ResetMethod.ck.upload.resetmethod=ck +espino.menu.ResetMethod.nodemcu=nodemcu +espino.menu.ResetMethod.nodemcu.upload.resetmethod=nodemcu diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 7e06e0058..10c6ebd44 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -219,14 +219,12 @@ void loop(void); void yield(void); void optimistic_yield(uint32_t interval_us); -// Get the bit location within the hardware port of the given virtual pin. -// This comes from the pins_*.c file for the active board configuration. #define digitalPinToPort(pin) (0) #define digitalPinToBitMask(pin) (1UL << (pin)) #define digitalPinToTimer(pin) (0) -#define portOutputRegister(port) ((volatile uint32_t*) GPO) -#define portInputRegister(port) ((volatile uint32_t*) GPI) -#define portModeRegister(port) ((volatile uint32_t*) GPE) +#define portOutputRegister(port) ((volatile uint32_t*) &GPO) +#define portInputRegister(port) ((volatile uint32_t*) &GPI) +#define portModeRegister(port) ((volatile uint32_t*) &GPE) #define NOT_A_PIN -1 #define NOT_A_PORT -1 diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index 2e93f8aee..78108bee7 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -617,18 +617,15 @@ size_t HardwareSerial::write(uint8_t c) { size_t room = uart_get_tx_fifo_room(_uart); if(room > 0 && _tx_buffer->empty()) { uart_transmit_char(_uart, c); - if(room < 10) { - uart_arm_tx_interrupt(_uart); - } return 1; } while(_tx_buffer->room() == 0) { yield(); - uart_arm_tx_interrupt(_uart); } _tx_buffer->write(c); + uart_arm_tx_interrupt(_uart); return 1; } diff --git a/cores/esp8266/abi.cpp b/cores/esp8266/abi.cpp index b38f16453..ff865d9ca 100644 --- a/cores/esp8266/abi.cpp +++ b/cores/esp8266/abi.cpp @@ -68,6 +68,10 @@ void __throw_length_error(char const*) { void __throw_bad_alloc() { panic(); } + +void __throw_logic_error(const char* str) { + panic(); +} } // TODO: rebuild windows toolchain to make this unnecessary: diff --git a/cores/esp8266/base64.cpp b/cores/esp8266/base64.cpp new file mode 100644 index 000000000..11deb0af0 --- /dev/null +++ b/cores/esp8266/base64.cpp @@ -0,0 +1,63 @@ +/** + * base64.cpp + * + * Created on: 09.12.2015 + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the ESP8266 core for Arduino. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "Arduino.h" +extern "C" { +#include "libb64/cdecode.h" +#include "libb64/cencode.h" +} +#include "base64.h" + +/** + * convert input data to base64 + * @param data uint8_t * + * @param length size_t + * @return String + */ +String base64::encode(uint8_t * data, size_t length) { + // base64 needs more size then the source data + size_t size = ((length * 1.6f) + 1); + char * buffer = (char *) malloc(size); + if(buffer) { + base64_encodestate _state; + base64_init_encodestate(&_state); + int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state); + len = base64_encode_blockend((buffer + len), &_state); + + String base64 = String(buffer); + free(buffer); + return base64; + } + return String("-FAIL-"); +} + +/** + * convert input data to base64 + * @param text String + * @return String + */ +String base64::encode(String text) { + return base64::encode((uint8_t *) text.c_str(), text.length()); +} + diff --git a/cores/esp8266/base64.h b/cores/esp8266/base64.h new file mode 100644 index 000000000..39be2d397 --- /dev/null +++ b/cores/esp8266/base64.h @@ -0,0 +1,36 @@ +/** + * base64.h + * + * Created on: 09.12.2015 + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the ESP8266 core for Arduino. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef CORE_BASE64_H_ +#define CORE_BASE64_H_ + +class base64 { + public: + static String encode(uint8_t * data, size_t length); + static String encode(String text); + private: +}; + + +#endif /* CORE_BASE64_H_ */ diff --git a/cores/esp8266/cbuf.h b/cores/esp8266/cbuf.h index fee98a94b..087e7200b 100644 --- a/cores/esp8266/cbuf.h +++ b/cores/esp8266/cbuf.h @@ -42,9 +42,6 @@ class cbuf { if(_end >= _begin) { return _size - (_end - _begin) - 1; } - if(_begin == _end) { - return _size; - } return _begin - _end - 1; } @@ -62,7 +59,7 @@ class cbuf { if(getSize() == 0) return -1; char result = *_begin; - if(++_begin == _bufend) _begin = _buf; + _begin = wrap_if_bufend(_begin + 1); return static_cast(result); } @@ -78,8 +75,7 @@ class cbuf { dst += top_size; } memcpy(dst, _begin, size_to_read); - _begin += size_to_read; - if(_begin == _bufend) _begin = _buf; + _begin = wrap_if_bufend(_begin + size_to_read); return size_read; } @@ -87,7 +83,7 @@ class cbuf { if(room() == 0) return 0; *_end = c; - if(++_end == _bufend) _end = _buf; + _end = wrap_if_bufend(_end + 1); return 1; } @@ -103,8 +99,7 @@ class cbuf { src += top_size; } memcpy(_end, src, size_to_write); - _end += size_to_write; - if(_end == _bufend) _end = _buf; + _end = wrap_if_bufend(_end + size_to_write); return size_written; } @@ -114,6 +109,10 @@ class cbuf { } private: + inline char* wrap_if_bufend(char* ptr) { + return (ptr == _bufend) ? _buf : ptr; + } + size_t _size; char* _buf; char* _bufend; diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index bafcd3aee..ae5d58539 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -26,6 +26,7 @@ #define CORE_HAS_LIBB64 +#define CORE_HAS_BASE64_CLASS #endif diff --git a/cores/esp8266/esp8266_peri.h b/cores/esp8266/esp8266_peri.h index 4fd057009..e7aab1f03 100644 --- a/cores/esp8266/esp8266_peri.h +++ b/cores/esp8266/esp8266_peri.h @@ -834,4 +834,10 @@ extern uint8_t esp8266_gpioToFn[16]; #define I2STXCMM (0x7) //I2S_TX_CHAN_MOD #define I2STXCM (0) //I2S_TX_CHAN_MOD_S +/** + Random Number Generator 32bit + http://esp8266-re.foogod.com/wiki/Random_Number_Generator +**/ +#define RANDOM_REG32 ESP8266_DREG(0x20E44) + #endif diff --git a/cores/esp8266/pgmspace.h b/cores/esp8266/pgmspace.h index 4ee599557..c9e83fa05 100644 --- a/cores/esp8266/pgmspace.h +++ b/cores/esp8266/pgmspace.h @@ -78,7 +78,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut (__extension__({ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \ - const uint32_t* __addr32 = reinterpret_cast(reinterpret_cast(__local)-__offset); \ + const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local)-__offset); \ uint8_t __result = ((*__addr32) >> (__offset * 8)); \ __result; \ })) @@ -87,7 +87,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut (__extension__({ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \ - const uint32_t* __addr32 = reinterpret_cast(reinterpret_cast(__local) - __offset); \ + const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local) - __offset); \ uint16_t __result = ((*__addr32) >> (__offset * 8)); \ __result; \ })) diff --git a/doc/boards.md b/doc/boards.md index e92c4c591..578ea319d 100644 --- a/doc/boards.md +++ b/doc/boards.md @@ -11,6 +11,7 @@ title: Supported Hardware * [Olimex MOD\-WIFI\-ESP8266](#olimex-mod-wifi-esp8266) * [SparkFun ESP8266 Thing](#sparkfun-esp8266-thing) * [SweetPea ESP\-210](#sweetpea-esp-210) + * [ESPino](#espino) * [Generic ESP8266 modules](#generic-esp8266-modules) * [Serial Adapter](#serial-adapter) * [Minimal Hardware Setup for Bootloading and Usage](#minimal-hardware-setup-for-bootloading-and-usage) @@ -91,6 +92,14 @@ Product page: https://www.sparkfun.com/products/13231 *TODO: add notes* +## ESPino + +ESPino integrates the ESP-12 module with a 3.3v regulator, CP2104 USB-Serial bridge and a micro USB connector for easy programming. It is designed for fitting in a breadboard and has an RGB Led and two buttons for easy prototyping. + +For more information about the hardware, pinout diagram and programming procedures, please see the [datasheet](https://github.com/makerlabmx/ESPino-tools/raw/master/Docs/ESPino-Datasheet-EN.pdf). + +Product page: http://www.espino.io/en + ## Generic ESP8266 modules These modules come in different form factors and pinouts. See the page at ESP8266 community wiki for more info: diff --git a/doc/libraries.md b/doc/libraries.md index 314b1aa51..c9c714e2f 100644 --- a/doc/libraries.md +++ b/doc/libraries.md @@ -140,15 +140,17 @@ While many RC servo motors will accept the 3.3V IO data pin from a ESP8266, most Libraries that don't rely on low-level access to AVR registers should work well. Here are a few libraries that were verified to work: +- [Adafruit_ILI9341](https://github.com/Links2004/Adafruit_ILI9341) - Port of the Adafruit ILI9341 for the ESP8266 - [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets) - WebSocket Server and Client compatible with ESP8266 (RFC6455) -- [aREST](https://github.com/marcoschwartz/aREST) REST API handler library. +- [aREST](https://github.com/marcoschwartz/aREST) - REST API handler library. - [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)). - [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library.git) - [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library) - Arduino library for the DHT11/DHT22 temperature and humidity sensors. Download latest v1.1.1 library and no changes are necessary. Older versions should initialize DHT as follows: `DHT dht(DHTPIN, DHTTYPE, 15)` - [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 "NeoPixelAnimator" branch for ESP8266 to get HSL color support and more. -- [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy. +- [PubSubClient](https://github.com/Imroy/pubsubclient) - MQTT library by @Imroy. - [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with ESP8266. - [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB. - [ST7735](https://github.com/nzmichaelh/Adafruit-ST7735-Library) - Adafruit's ST7735 library modified to be compatible with ESP8266. Just make sure to modify the pins in the examples as they are still AVR specific. - [UTFT-ESP8266](https://github.com/gnulabis/UTFT-ESP8266) - UTFT display library with support for ESP8266. Only serial interface (SPI) displays are supported for now (no 8-bit parallel mode, etc). Also includes support for the hardware SPI controller of the ESP8266. +- [WiFiManager](https://github.com/tzapu/WiFiManager) - WiFi Connection manager with web captive portal. If it can't connect, it starts AP mode and a configuration portal so you can choose and enter WiFi credentials. diff --git a/libraries/ESP8266HTTPClient/examples/Authorization/Authorization.ino b/libraries/ESP8266HTTPClient/examples/Authorization/Authorization.ino new file mode 100644 index 000000000..79a4c3fdf --- /dev/null +++ b/libraries/ESP8266HTTPClient/examples/Authorization/Authorization.ino @@ -0,0 +1,84 @@ +/** + * Authorization.ino + * + * Created on: 09.12.2015 + * + */ + +#include + +#include +#include + +#include + +#define USE_SERIAL Serial + +ESP8266WiFiMulti WiFiMulti; + +void setup() { + + USE_SERIAL.begin(115200); + // USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "PASSWORD"); + +} + +void loop() { + // wait for WiFi connection + if((WiFiMulti.run() == WL_CONNECTED)) { + + HTTPClient http; + + USE_SERIAL.print("[HTTP] begin...\n"); + // configure traged server and url + + + http.begin("http://user:password@192.168.1.12/test.html"); + + /* + // or + http.begin("http://192.168.1.12/test.html"); + http.setAuthorization("user", "password"); + + // or + http.begin("http://192.168.1.12/test.html"); + http.setAuthorization("dXNlcjpwYXN3b3Jk"); + */ + + + USE_SERIAL.print("[HTTP] GET...\n"); + // start connection and send HTTP header + int httpCode = http.GET(); + + // httpCode will be negative on error + if(httpCode) { + // HTTP header has been send and Server response header has been handled + USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); + + // file found at server + if(httpCode == HTTP_CODE_OK) { + String payload = http.getString(); + USE_SERIAL.println(payload); + } + } else { + USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); + } + + http.end(); + } + + delay(10000); +} + diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino index 3c722556b..d3a5fbc7d 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino @@ -43,24 +43,28 @@ void loop() { USE_SERIAL.print("[HTTP] begin...\n"); // configure traged server and url - //http.begin("192.168.1.12", 443, "/test.html", true, "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS - http.begin("192.168.1.12", 80, "/test.html"); //HTTP + //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS + http.begin("http://192.168.1.12/test.html"); //HTTP USE_SERIAL.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); + + // httpCode will be negative on error if(httpCode) { // HTTP header has been send and Server response header has been handled USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server - if(httpCode == 200) { + if(httpCode == HTTP_CODE_OK) { String payload = http.getString(); USE_SERIAL.println(payload); } } else { - USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n"); + USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } + + http.end(); } delay(10000); diff --git a/libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino b/libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino index e725a1f76..35babdc33 100644 --- a/libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino +++ b/libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino @@ -36,26 +36,31 @@ void setup() { WiFiMulti.addAP("SSID", "PASSWORD"); - + // allow reuse (if server supports it) + http.setReuse(true); } void loop() { // wait for WiFi connection if((WiFiMulti.run() == WL_CONNECTED)) { - http.begin("192.168.1.12", 80, "/test.html"); + http.begin("http://192.168.1.12/test.html"); + //http.begin("192.168.1.12", 80, "/test.html"); int httpCode = http.GET(); if(httpCode) { USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server - if(httpCode == 200) { + if(httpCode == HTTP_CODE_OK) { http.writeToStream(&USE_SERIAL); } } else { - USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n"); + USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } + + http.end(); + } delay(1000); diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino index 442fa6547..2e7f4487d 100644 --- a/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino @@ -42,19 +42,20 @@ void loop() { HTTPClient http; USE_SERIAL.print("[HTTP] begin...\n"); - // configure traged server and url - http.begin("192.168.1.12", 80, "/test.html"); + + // configure server and url + http.begin("http://192.168.1.12/test.html"); + //http.begin("192.168.1.12", 80, "/test.html"); USE_SERIAL.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); if(httpCode) { // HTTP header has been send and Server response header has been handled - USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server - if(httpCode == 200) { + if(httpCode == HTTP_CODE_OK) { // get lenght of document (is -1 when Server sends no Content-Length header) int len = http.getSize(); @@ -89,8 +90,10 @@ void loop() { } } else { - USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n"); + USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } + + http.end(); } delay(10000); diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 37b71dbc1..6a8d010e1 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -26,9 +26,11 @@ #include #include #include +#include #include "ESP8266HTTPClient.h" + /** * constractor */ @@ -100,27 +102,34 @@ void HTTPClient::begin(String url, String httpsFingerprint) { String protocol; // check for : (http: or https: int index = url.indexOf(':'); - int index2; + //int index2; bool hasPort = false; if(index) { protocol = url.substring(0, index); url.remove(0, (index + 3)); // remove http:// or https:// - index = url.indexOf(':'); - index2 = url.indexOf('/'); + index = url.indexOf('/'); + String host = url.substring(0, index); + url.remove(0, index); // remove host part - if(index >= 0 && ((index2 >= 0 && index < index2) || index2 == 0)) { // do we have a port? - _host = url.substring(0, index); // hostname - url.remove(0, (index + 1)); // remove hostname + : + // get Authorization + index = host.indexOf('@'); + if(index >= 0) { + // auth info + String auth = host.substring(0, index); + host.remove(0, index +1); // remove auth part including @ + _base64Authorization = base64::encode(auth); + } - index = url.indexOf('/'); - _port = url.substring(0, index).toInt(); // get port - url.remove(0, index); // remove port + // get port + index = host.indexOf(':'); + if(index >= 0) { + _host = host.substring(0, index); // hostname + host.remove(0, (index + 1)); // remove hostname + : + _port = host.toInt(); // get port hasPort = true; } else { - index = index2; - _host = url.substring(0, index); - url.remove(0, index); // remove hostname + _host = host; } _url = url; @@ -139,6 +148,7 @@ void HTTPClient::begin(String url, String httpsFingerprint) { DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str()); return; } + } 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()); @@ -219,6 +229,30 @@ void HTTPClient::setUserAgent(const char * userAgent) { _userAgent = userAgent; } +/** + * set the Authorizatio for the http request + * @param user const char * + * @param password const char * + */ +void HTTPClient::setAuthorization(const char * user, const char * password) { + if(user && password) { + String auth = user; + auth += ":"; + auth += password; + _base64Authorization = base64::encode(auth); + } +} + +/** + * set the Authorizatio for the http request + * @param auth const char * base64 + */ +void HTTPClient::setAuthorization(const char * auth) { + if(auth) { + _base64Authorization = auth; + } +} + /** * send a GET request * @return http code @@ -454,6 +488,33 @@ String HTTPClient::getString(void) { return sstring; } +/** + * converts error code to String + * @param error int + * @return String + */ +String HTTPClient::errorToString(int error) { + switch(error) { + case HTTPC_ERROR_CONNECTION_REFUSED: + return String("connection refused"); + case HTTPC_ERROR_SEND_HEADER_FAILED: + return String("send header failed"); + case HTTPC_ERROR_SEND_PAYLOAD_FAILED: + return String("send payload failed"); + case HTTPC_ERROR_NOT_CONNECTED: + return String("not connected"); + case HTTPC_ERROR_CONNECTION_LOST: + return String("connection lost"); + case HTTPC_ERROR_NO_STREAM: + return String("no stream"); + case HTTPC_ERROR_NO_HTTP_SERVER: + return String("no HTTP server"); + default: + return String(); + } +} + + /** * adds Header to the request * @param name @@ -463,7 +524,7 @@ String HTTPClient::getString(void) { 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")) { + if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host") && !(_base64Authorization.length() && name.equalsIgnoreCase("Authorization"))) { String headerLine = name; headerLine += ": "; headerLine += value; @@ -595,7 +656,13 @@ bool HTTPClient::sendHeader(const char * type) { } else { header += "close"; } - header += "\r\n" + _Headers + "\r\n"; + header += "\r\n"; + + if(_base64Authorization.length()) { + header += "Authorization: Basic " + _base64Authorization + "\r\n"; + } + + header += _Headers + "\r\n"; return (_tcp->write(header.c_str(), header.length()) == header.length()); } diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h index 2d1312a29..2bf6d0565 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h @@ -42,6 +42,67 @@ #define HTTPC_ERROR_NO_STREAM (-6) #define HTTPC_ERROR_NO_HTTP_SERVER (-7) +/// HTTP codes see RFC7231 +typedef enum { + HTTP_CODE_CONTINUE = 100, + HTTP_CODE_SWITCHING_PROTOCOLS = 101, + HTTP_CODE_PROCESSING = 102, + HTTP_CODE_OK = 200, + HTTP_CODE_CREATED = 201, + HTTP_CODE_ACCEPTED = 202, + HTTP_CODE_NON_AUTHORITATIVE_INFORMATION = 203, + HTTP_CODE_NO_CONTENT = 204, + HTTP_CODE_RESET_CONTENT = 205, + HTTP_CODE_PARTIAL_CONTENT = 206, + HTTP_CODE_MULTI_STATUS = 207, + HTTP_CODE_ALREADY_REPORTED = 208, + HTTP_CODE_IM_USED = 226, + HTTP_CODE_MULTIPLE_CHOICES = 300, + HTTP_CODE_MOVED_PERMANENTLY = 301, + HTTP_CODE_FOUND = 302, + HTTP_CODE_SEE_OTHER = 303, + HTTP_CODE_NOT_MODIFIED = 304, + HTTP_CODE_USE_PROXY = 305, + HTTP_CODE_TEMPORARY_REDIRECT = 307, + HTTP_CODE_PERMANENT_REDIRECT = 308, + HTTP_CODE_BAD_REQUEST = 400, + HTTP_CODE_UNAUTHORIZED = 401, + HTTP_CODE_PAYMENT_REQUIRED = 402, + HTTP_CODE_FORBIDDEN = 403, + HTTP_CODE_NOT_FOUND = 404, + HTTP_CODE_METHOD_NOT_ALLOWED = 405, + HTTP_CODE_NOT_ACCEPTABLE = 406, + HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED = 407, + HTTP_CODE_REQUEST_TIMEOUT = 408, + HTTP_CODE_CONFLICT = 409, + HTTP_CODE_GONE = 410, + HTTP_CODE_LENGTH_REQUIRED = 411, + HTTP_CODE_PRECONDITION_FAILED = 412, + HTTP_CODE_PAYLOAD_TOO_LARGE = 413, + HTTP_CODE_URI_TOO_LONG = 414, + HTTP_CODE_UNSUPPORTED_MEDIA_TYPE = 415, + HTTP_CODE_RANGE_NOT_SATISFIABLE = 416, + HTTP_CODE_EXPECTATION_FAILED = 417, + HTTP_CODE_MISDIRECTED_REQUEST = 421, + HTTP_CODE_UNPROCESSABLE_ENTITY = 422, + HTTP_CODE_LOCKED = 423, + HTTP_CODE_FAILED_DEPENDENCY = 424, + HTTP_CODE_UPGRADE_REQUIRED = 426, + HTTP_CODE_PRECONDITION_REQUIRED = 428, + HTTP_CODE_TOO_MANY_REQUESTS = 429, + HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, + HTTP_CODE_INTERNAL_SERVER_ERROR = 500, + HTTP_CODE_NOT_IMPLEMENTED = 501, + HTTP_CODE_BAD_GATEWAY = 502, + HTTP_CODE_SERVICE_UNAVAILABLE = 503, + HTTP_CODE_GATEWAY_TIMEOUT = 504, + HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED = 505, + HTTP_CODE_VARIANT_ALSO_NEGOTIATES = 506, + HTTP_CODE_INSUFFICIENT_STORAGE = 507, + HTTP_CODE_LOOP_DETECTED = 508, + HTTP_CODE_NOT_EXTENDED = 510, + HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED = 511 +} t_http_codes; class HTTPClient { public: @@ -60,6 +121,8 @@ class HTTPClient { void setReuse(bool reuse); /// keep-alive void setUserAgent(const char * userAgent); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); /// request handling int GET(); @@ -86,6 +149,8 @@ class HTTPClient { int writeToStream(Stream * stream); String getString(void); + String errorToString(int error); + protected: struct RequestArgument { @@ -109,6 +174,7 @@ class HTTPClient { String _Headers; String _userAgent; + String _base64Authorization; /// Response handling RequestArgument* _currentHeaders; diff --git a/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino b/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino index 7ffc78acd..eb7c02eff 100644 --- a/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino +++ b/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino @@ -71,7 +71,14 @@ void loop() { client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); - delay(10); + int timeout = millis() + 5000; + while (client.available() == 0) { + if (timeout - millis() < 0) { + Serial.println(">>> Client Timeout !"); + client.stop(); + return; + } + } // Read all the lines of the reply from server and print them to Serial while(client.available()){ diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 247701acd..997fe5ccb 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -53,7 +53,7 @@ extern "C" uint8_t* default_private_key = 0; uint32_t default_private_key_len = 0; static bool default_private_key_dynamic = false; -// +static int s_pk_refcnt = 0; uint8_t* default_certificate = 0; uint32_t default_certificate_len = 0; static bool default_certificate_dynamic = false; @@ -81,9 +81,6 @@ public: if (_ssl_ctx_refcnt == 0) { ssl_ctx_free(_ssl_ctx); } - - clear_private_key(); - clear_certificate(); } void ref() { @@ -186,12 +183,17 @@ int SSLContext::_ssl_ctx_refcnt = 0; WiFiClientSecure::WiFiClientSecure() { + ++s_pk_refcnt; } WiFiClientSecure::~WiFiClientSecure() { if (_ssl) { _ssl->unref(); } + if (--s_pk_refcnt == 0) { + clear_private_key(); + clear_certificate(); + } } WiFiClientSecure::WiFiClientSecure(const WiFiClientSecure& other) diff --git a/libraries/ESP8266WiFi/src/include/UdpContext.h b/libraries/ESP8266WiFi/src/include/UdpContext.h index d9347fd34..708007036 100644 --- a/libraries/ESP8266WiFi/src/include/UdpContext.h +++ b/libraries/ESP8266WiFi/src/include/UdpContext.h @@ -1,9 +1,9 @@ -/* +/* UdpContext.h - UDP connection handling on top of lwIP Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. This file is part of the esp8266 core for Arduino environment. - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -206,10 +206,10 @@ public: size_t max_size = _rx_buf->len - _rx_buf_offset; size = (size < max_size) ? size : max_size; DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset); - - os_memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, size); + + memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, size); _consume(size); - + return size; } @@ -236,7 +236,7 @@ public: { _reserve(_tx_buf_offset + size); } - + size_t left_to_copy = size; while(left_to_copy) { @@ -249,7 +249,7 @@ public: continue; } size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur; - os_memcpy(reinterpret_cast(_tx_buf_cur->payload) + used_cur, data, will_copy); + memcpy(reinterpret_cast(_tx_buf_cur->payload) + used_cur, data, will_copy); _tx_buf_offset += will_copy; left_to_copy -= will_copy; data += will_copy; @@ -259,18 +259,20 @@ public: void send(ip_addr_t* addr = 0, uint16_t port = 0) { - size_t orig_size = _tx_buf_head->tot_len; - size_t data_size = _tx_buf_offset; - size_t size_adjustment = orig_size - data_size; - for (pbuf* p = _tx_buf_head; p; p = p->next) - { - p->tot_len -= size_adjustment; - if (!p->next) - { - p->len = p->tot_len; - } + pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM); + uint8_t* dst = reinterpret_cast(tx_copy->payload); + for (pbuf* p = _tx_buf_head; p; p = p->next) { + size_t will_copy = (data_size < p->len) ? data_size : p->len; + memcpy(dst, p->payload, will_copy); + dst += will_copy; + data_size -= will_copy; } + pbuf_free(_tx_buf_head); + _tx_buf_head = 0; + _tx_buf_cur = 0; + _tx_buf_offset = 0; + if (!addr) { addr = &_dest_addr; @@ -282,30 +284,16 @@ public: _pcb->ttl = _multicast_ttl; } - udp_sendto(_pcb, _tx_buf_head, addr, port); - + udp_sendto(_pcb, tx_copy, addr, port); _pcb->ttl = old_ttl; - - for (pbuf* p = _tx_buf_head; p; p = p->next) - { - p->tot_len += size_adjustment; - if (!p->next) - { - p->len = p->tot_len; - } - } - - pbuf_free(_tx_buf_head); - _tx_buf_head = 0; - _tx_buf_cur = 0; - _tx_buf_offset = 0; + pbuf_free(tx_copy); } private: void _reserve(size_t size) { - const size_t pbuf_unit_size = 512; + const size_t pbuf_unit_size = 128; if (!_tx_buf_head) { _tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); @@ -357,7 +345,7 @@ private: } - static void _s_recv(void *arg, + static void _s_recv(void *arg, udp_pcb *upcb, pbuf *p, ip_addr_t *addr, u16_t port) { diff --git a/package/package_esp8266com_index.template.json b/package/package_esp8266com_index.template.json index ee1042450..d070d4809 100644 --- a/package/package_esp8266com_index.template.json +++ b/package/package_esp8266com_index.template.json @@ -43,11 +43,14 @@ { "name": "SweetPea ESP-210" }, - { + { "name": "WeMos D1" }, - { + { "name": "WeMos D1 mini" + }, + { + "name": "ESPino" } ], "toolsDependencies": [ diff --git a/variants/espino/pins_arduino.h b/variants/espino/pins_arduino.h new file mode 100644 index 000000000..2efad2db3 --- /dev/null +++ b/variants/espino/pins_arduino.h @@ -0,0 +1,73 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + Modified for ESP8266 platform by Ivan Grokhotkov, 2014-2015. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#define EXTERNAL_NUM_INTERRUPTS 16 +#define NUM_DIGITAL_PINS 17 +#define NUM_ANALOG_INPUTS 1 + +#define analogInputToDigitalPin(p) ((p > 0)?NOT_A_PIN:0) +#define digitalPinToInterrupt(p) (((p) < EXTERNAL_NUM_INTERRUPTS)?p:NOT_A_PIN) +#define digitalPinHasPWM(p) (((p) < NUM_DIGITAL_PINS)?p:NOT_A_PIN) + +static const uint8_t SDA = 4; +static const uint8_t SCL = 5; + +static const uint8_t SS = 15; +static const uint8_t MOSI = 13; +static const uint8_t MISO = 12; +static const uint8_t SCK = 14; + +static const uint8_t BUILTIN_LED = 2; +static const uint8_t BUILTIN_LEDR = 2; +static const uint8_t BUILTIN_LEDG = 4; +static const uint8_t BUILTIN_LEDB = 5; +static const uint8_t BUILTIN_BUTTON = 0; + +static const uint8_t A0 = 17; + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_HARDWARE Serial +#define SERIAL_PORT_HARDWARE_OPEN Serial + +#endif /* Pins_Arduino_h */