1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Merge branch 'master' into httpUpdate

This commit is contained in:
Markus Sattler 2015-12-09 15:41:55 +01:00
commit ce4edcb423
23 changed files with 588 additions and 91 deletions

View File

@ -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_end=0x3FB000
d1_mini.menu.FlashSize.4M1M.build.spiffs_blocksize=8192 d1_mini.menu.FlashSize.4M1M.build.spiffs_blocksize=8192
d1_mini.menu.FlashSize.4M1M.build.spiffs_pagesize=256 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

View File

@ -219,14 +219,12 @@ void loop(void);
void yield(void); void yield(void);
void optimistic_yield(uint32_t interval_us); 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 digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin)) #define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0) #define digitalPinToTimer(pin) (0)
#define portOutputRegister(port) ((volatile uint32_t*) GPO) #define portOutputRegister(port) ((volatile uint32_t*) &GPO)
#define portInputRegister(port) ((volatile uint32_t*) GPI) #define portInputRegister(port) ((volatile uint32_t*) &GPI)
#define portModeRegister(port) ((volatile uint32_t*) GPE) #define portModeRegister(port) ((volatile uint32_t*) &GPE)
#define NOT_A_PIN -1 #define NOT_A_PIN -1
#define NOT_A_PORT -1 #define NOT_A_PORT -1

View File

@ -617,18 +617,15 @@ size_t HardwareSerial::write(uint8_t c) {
size_t room = uart_get_tx_fifo_room(_uart); size_t room = uart_get_tx_fifo_room(_uart);
if(room > 0 && _tx_buffer->empty()) { if(room > 0 && _tx_buffer->empty()) {
uart_transmit_char(_uart, c); uart_transmit_char(_uart, c);
if(room < 10) {
uart_arm_tx_interrupt(_uart);
}
return 1; return 1;
} }
while(_tx_buffer->room() == 0) { while(_tx_buffer->room() == 0) {
yield(); yield();
uart_arm_tx_interrupt(_uart);
} }
_tx_buffer->write(c); _tx_buffer->write(c);
uart_arm_tx_interrupt(_uart);
return 1; return 1;
} }

View File

@ -68,6 +68,10 @@ void __throw_length_error(char const*) {
void __throw_bad_alloc() { void __throw_bad_alloc() {
panic(); panic();
} }
void __throw_logic_error(const char* str) {
panic();
}
} }
// TODO: rebuild windows toolchain to make this unnecessary: // TODO: rebuild windows toolchain to make this unnecessary:

63
cores/esp8266/base64.cpp Normal file
View File

@ -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());
}

36
cores/esp8266/base64.h Normal file
View File

@ -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_ */

View File

@ -42,9 +42,6 @@ class cbuf {
if(_end >= _begin) { if(_end >= _begin) {
return _size - (_end - _begin) - 1; return _size - (_end - _begin) - 1;
} }
if(_begin == _end) {
return _size;
}
return _begin - _end - 1; return _begin - _end - 1;
} }
@ -62,7 +59,7 @@ class cbuf {
if(getSize() == 0) return -1; if(getSize() == 0) return -1;
char result = *_begin; char result = *_begin;
if(++_begin == _bufend) _begin = _buf; _begin = wrap_if_bufend(_begin + 1);
return static_cast<int>(result); return static_cast<int>(result);
} }
@ -78,8 +75,7 @@ class cbuf {
dst += top_size; dst += top_size;
} }
memcpy(dst, _begin, size_to_read); memcpy(dst, _begin, size_to_read);
_begin += size_to_read; _begin = wrap_if_bufend(_begin + size_to_read);
if(_begin == _bufend) _begin = _buf;
return size_read; return size_read;
} }
@ -87,7 +83,7 @@ class cbuf {
if(room() == 0) return 0; if(room() == 0) return 0;
*_end = c; *_end = c;
if(++_end == _bufend) _end = _buf; _end = wrap_if_bufend(_end + 1);
return 1; return 1;
} }
@ -103,8 +99,7 @@ class cbuf {
src += top_size; src += top_size;
} }
memcpy(_end, src, size_to_write); memcpy(_end, src, size_to_write);
_end += size_to_write; _end = wrap_if_bufend(_end + size_to_write);
if(_end == _bufend) _end = _buf;
return size_written; return size_written;
} }
@ -114,6 +109,10 @@ class cbuf {
} }
private: private:
inline char* wrap_if_bufend(char* ptr) {
return (ptr == _bufend) ? _buf : ptr;
}
size_t _size; size_t _size;
char* _buf; char* _buf;
char* _bufend; char* _bufend;

View File

@ -26,6 +26,7 @@
#define CORE_HAS_LIBB64 #define CORE_HAS_LIBB64
#define CORE_HAS_BASE64_CLASS
#endif #endif

View File

@ -834,4 +834,10 @@ extern uint8_t esp8266_gpioToFn[16];
#define I2STXCMM (0x7) //I2S_TX_CHAN_MOD #define I2STXCMM (0x7) //I2S_TX_CHAN_MOD
#define I2STXCM (0) //I2S_TX_CHAN_MOD_S #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 #endif

View File

@ -78,7 +78,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut
(__extension__({ \ (__extension__({ \
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \ ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \
const uint32_t* __addr32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(__local)-__offset); \ const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local)-__offset); \
uint8_t __result = ((*__addr32) >> (__offset * 8)); \ uint8_t __result = ((*__addr32) >> (__offset * 8)); \
__result; \ __result; \
})) }))
@ -87,7 +87,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut
(__extension__({ \ (__extension__({ \
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \ ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \
const uint32_t* __addr32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(__local) - __offset); \ const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local) - __offset); \
uint16_t __result = ((*__addr32) >> (__offset * 8)); \ uint16_t __result = ((*__addr32) >> (__offset * 8)); \
__result; \ __result; \
})) }))

View File

@ -11,6 +11,7 @@ title: Supported Hardware
* [Olimex MOD\-WIFI\-ESP8266](#olimex-mod-wifi-esp8266) * [Olimex MOD\-WIFI\-ESP8266](#olimex-mod-wifi-esp8266)
* [SparkFun ESP8266 Thing](#sparkfun-esp8266-thing) * [SparkFun ESP8266 Thing](#sparkfun-esp8266-thing)
* [SweetPea ESP\-210](#sweetpea-esp-210) * [SweetPea ESP\-210](#sweetpea-esp-210)
* [ESPino](#espino)
* [Generic ESP8266 modules](#generic-esp8266-modules) * [Generic ESP8266 modules](#generic-esp8266-modules)
* [Serial Adapter](#serial-adapter) * [Serial Adapter](#serial-adapter)
* [Minimal Hardware Setup for Bootloading and Usage](#minimal-hardware-setup-for-bootloading-and-usage) * [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* *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 ## Generic ESP8266 modules
These modules come in different form factors and pinouts. See the page at ESP8266 community wiki for more info: These modules come in different form factors and pinouts. See the page at ESP8266 community wiki for more info:

View File

@ -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: 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) - [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)). - [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) - [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)` - [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). - [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. - [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. - [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. - [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. - [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. - [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.

View File

@ -0,0 +1,84 @@
/**
* Authorization.ino
*
* Created on: 09.12.2015
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#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);
}

View File

@ -43,24 +43,28 @@ void loop() {
USE_SERIAL.print("[HTTP] begin...\n"); USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url // 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("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("192.168.1.12", 80, "/test.html"); //HTTP http.begin("http://192.168.1.12/test.html"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n"); USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header // start connection and send HTTP header
int httpCode = http.GET(); int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode) { if(httpCode) {
// HTTP header has been send and Server response header has been handled // HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server // file found at server
if(httpCode == 200) { if(httpCode == HTTP_CODE_OK) {
String payload = http.getString(); String payload = http.getString();
USE_SERIAL.println(payload); USE_SERIAL.println(payload);
} }
} else { } 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); delay(10000);

View File

@ -36,26 +36,31 @@ void setup() {
WiFiMulti.addAP("SSID", "PASSWORD"); WiFiMulti.addAP("SSID", "PASSWORD");
// allow reuse (if server supports it)
http.setReuse(true);
} }
void loop() { void loop() {
// wait for WiFi connection // wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) { 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(); int httpCode = http.GET();
if(httpCode) { if(httpCode) {
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server // file found at server
if(httpCode == 200) { if(httpCode == HTTP_CODE_OK) {
http.writeToStream(&USE_SERIAL); http.writeToStream(&USE_SERIAL);
} }
} else { } 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); delay(1000);

View File

@ -42,19 +42,20 @@ void loop() {
HTTPClient http; HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n"); 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"); USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header // start connection and send HTTP header
int httpCode = http.GET(); int httpCode = http.GET();
if(httpCode) { if(httpCode) {
// HTTP header has been send and Server response header has been handled // HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server // 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) // get lenght of document (is -1 when Server sends no Content-Length header)
int len = http.getSize(); int len = http.getSize();
@ -89,8 +90,10 @@ void loop() {
} }
} else { } 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); delay(10000);

View File

@ -26,9 +26,11 @@
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>
#include <StreamString.h> #include <StreamString.h>
#include <base64.h>
#include "ESP8266HTTPClient.h" #include "ESP8266HTTPClient.h"
/** /**
* constractor * constractor
*/ */
@ -100,27 +102,34 @@ void HTTPClient::begin(String url, String httpsFingerprint) {
String protocol; String protocol;
// check for : (http: or https: // check for : (http: or https:
int index = url.indexOf(':'); int index = url.indexOf(':');
int index2; //int index2;
bool hasPort = false; bool hasPort = false;
if(index) { if(index) {
protocol = url.substring(0, index); protocol = url.substring(0, index);
url.remove(0, (index + 3)); // remove http:// or https:// url.remove(0, (index + 3)); // remove http:// or https://
index = url.indexOf(':'); index = url.indexOf('/');
index2 = 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? // get Authorization
_host = url.substring(0, index); // hostname index = host.indexOf('@');
url.remove(0, (index + 1)); // remove hostname + : 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('/'); // get port
_port = url.substring(0, index).toInt(); // get port index = host.indexOf(':');
url.remove(0, index); // remove port if(index >= 0) {
_host = host.substring(0, index); // hostname
host.remove(0, (index + 1)); // remove hostname + :
_port = host.toInt(); // get port
hasPort = true; hasPort = true;
} else { } else {
index = index2; _host = host;
_host = url.substring(0, index);
url.remove(0, index); // remove hostname
} }
_url = url; _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()); DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
return; 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()); 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; _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 * send a GET request
* @return http code * @return http code
@ -454,6 +488,33 @@ String HTTPClient::getString(void) {
return sstring; 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 * adds Header to the request
* @param name * @param name
@ -463,7 +524,7 @@ String HTTPClient::getString(void) {
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 // 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; String headerLine = name;
headerLine += ": "; headerLine += ": ";
headerLine += value; headerLine += value;
@ -595,7 +656,13 @@ bool HTTPClient::sendHeader(const char * type) {
} else { } else {
header += "close"; 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()); return (_tcp->write(header.c_str(), header.length()) == header.length());
} }

View File

@ -42,6 +42,67 @@
#define HTTPC_ERROR_NO_STREAM (-6) #define HTTPC_ERROR_NO_STREAM (-6)
#define HTTPC_ERROR_NO_HTTP_SERVER (-7) #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 { class HTTPClient {
public: public:
@ -60,6 +121,8 @@ class HTTPClient {
void setReuse(bool reuse); /// keep-alive void setReuse(bool reuse); /// keep-alive
void setUserAgent(const char * userAgent); void setUserAgent(const char * userAgent);
void setAuthorization(const char * user, const char * password);
void setAuthorization(const char * auth);
/// request handling /// request handling
int GET(); int GET();
@ -86,6 +149,8 @@ class HTTPClient {
int writeToStream(Stream * stream); int writeToStream(Stream * stream);
String getString(void); String getString(void);
String errorToString(int error);
protected: protected:
struct RequestArgument { struct RequestArgument {
@ -109,6 +174,7 @@ class HTTPClient {
String _Headers; String _Headers;
String _userAgent; String _userAgent;
String _base64Authorization;
/// Response handling /// Response handling
RequestArgument* _currentHeaders; RequestArgument* _currentHeaders;

View File

@ -71,7 +71,14 @@ void loop() {
client.print(String("GET ") + url + " HTTP/1.1\r\n" + client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" + "Host: " + host + "\r\n" +
"Connection: close\r\n\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 // Read all the lines of the reply from server and print them to Serial
while(client.available()){ while(client.available()){

View File

@ -53,7 +53,7 @@ extern "C"
uint8_t* default_private_key = 0; uint8_t* default_private_key = 0;
uint32_t default_private_key_len = 0; uint32_t default_private_key_len = 0;
static bool default_private_key_dynamic = false; static bool default_private_key_dynamic = false;
// static int s_pk_refcnt = 0;
uint8_t* default_certificate = 0; uint8_t* default_certificate = 0;
uint32_t default_certificate_len = 0; uint32_t default_certificate_len = 0;
static bool default_certificate_dynamic = false; static bool default_certificate_dynamic = false;
@ -81,9 +81,6 @@ public:
if (_ssl_ctx_refcnt == 0) { if (_ssl_ctx_refcnt == 0) {
ssl_ctx_free(_ssl_ctx); ssl_ctx_free(_ssl_ctx);
} }
clear_private_key();
clear_certificate();
} }
void ref() { void ref() {
@ -186,12 +183,17 @@ int SSLContext::_ssl_ctx_refcnt = 0;
WiFiClientSecure::WiFiClientSecure() { WiFiClientSecure::WiFiClientSecure() {
++s_pk_refcnt;
} }
WiFiClientSecure::~WiFiClientSecure() { WiFiClientSecure::~WiFiClientSecure() {
if (_ssl) { if (_ssl) {
_ssl->unref(); _ssl->unref();
} }
if (--s_pk_refcnt == 0) {
clear_private_key();
clear_certificate();
}
} }
WiFiClientSecure::WiFiClientSecure(const WiFiClientSecure& other) WiFiClientSecure::WiFiClientSecure(const WiFiClientSecure& other)

View File

@ -207,7 +207,7 @@ public:
size = (size < max_size) ? size : max_size; size = (size < max_size) ? size : max_size;
DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset); DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset);
os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size); memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size);
_consume(size); _consume(size);
return size; return size;
@ -249,7 +249,7 @@ public:
continue; continue;
} }
size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur; size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur;
os_memcpy(reinterpret_cast<char*>(_tx_buf_cur->payload) + used_cur, data, will_copy); memcpy(reinterpret_cast<char*>(_tx_buf_cur->payload) + used_cur, data, will_copy);
_tx_buf_offset += will_copy; _tx_buf_offset += will_copy;
left_to_copy -= will_copy; left_to_copy -= will_copy;
data += will_copy; data += will_copy;
@ -259,18 +259,20 @@ public:
void send(ip_addr_t* addr = 0, uint16_t port = 0) 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 data_size = _tx_buf_offset;
size_t size_adjustment = orig_size - data_size; pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM);
for (pbuf* p = _tx_buf_head; p; p = p->next) uint8_t* dst = reinterpret_cast<uint8_t*>(tx_copy->payload);
{ for (pbuf* p = _tx_buf_head; p; p = p->next) {
p->tot_len -= size_adjustment; size_t will_copy = (data_size < p->len) ? data_size : p->len;
if (!p->next) memcpy(dst, p->payload, will_copy);
{ dst += will_copy;
p->len = p->tot_len; data_size -= will_copy;
}
} }
pbuf_free(_tx_buf_head);
_tx_buf_head = 0;
_tx_buf_cur = 0;
_tx_buf_offset = 0;
if (!addr) { if (!addr) {
addr = &_dest_addr; addr = &_dest_addr;
@ -282,30 +284,16 @@ public:
_pcb->ttl = _multicast_ttl; _pcb->ttl = _multicast_ttl;
} }
udp_sendto(_pcb, _tx_buf_head, addr, port); udp_sendto(_pcb, tx_copy, addr, port);
_pcb->ttl = old_ttl; _pcb->ttl = old_ttl;
pbuf_free(tx_copy);
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;
} }
private: private:
void _reserve(size_t size) void _reserve(size_t size)
{ {
const size_t pbuf_unit_size = 512; const size_t pbuf_unit_size = 128;
if (!_tx_buf_head) if (!_tx_buf_head)
{ {
_tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); _tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM);

View File

@ -43,11 +43,14 @@
{ {
"name": "SweetPea ESP-210" "name": "SweetPea ESP-210"
}, },
{ {
"name": "WeMos D1" "name": "WeMos D1"
}, },
{ {
"name": "WeMos D1 mini" "name": "WeMos D1 mini"
},
{
"name": "ESPino"
} }
], ],
"toolsDependencies": [ "toolsDependencies": [

View File

@ -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 */