1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-15 00:02:49 +03:00

Revert "Allman now (#6080)" (#6090)

This reverts commit 98125f8860.
This commit is contained in:
Allman-astyler
2019-05-14 00:09:54 +02:00
committed by david gauchard
parent 98125f8860
commit eea9999dc5
255 changed files with 42650 additions and 50904 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,23 @@
/*
WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries
- Mostly compatible with Arduino WiFi shield library and standard
WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries
- Mostly compatible with Arduino WiFi shield library and standard
WiFiClient/ServerSecure (except for certificate handling).
Copyright (c) 2018 Earle F. Philhower, III
Copyright (c) 2018 Earle F. Philhower, III
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 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.
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
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 _BEARSSLHELPERS_H
@ -28,21 +28,18 @@
// Internal opaque structures, not needed by user applications
namespace brssl
{
class public_key;
class private_key;
namespace brssl {
class public_key;
class private_key;
};
namespace BearSSL
{
namespace BearSSL {
// Holds either a single public RSA or EC key for use when BearSSL wants a pubkey.
// Copies all associated data so no need to keep input PEM/DER keys.
// All inputs can be either in RAM or PROGMEM.
class PublicKey
{
public:
class PublicKey {
public:
PublicKey();
PublicKey(const char *pemKey);
PublicKey(const uint8_t *derKey, size_t derLen);
@ -60,16 +57,15 @@ public:
// Disable the copy constructor, we're pointer based
PublicKey(const PublicKey& that) = delete;
private:
private:
brssl::public_key *_key;
};
// Holds either a single private RSA or EC key for use when BearSSL wants a secretkey.
// Copies all associated data so no need to keep input PEM/DER keys.
// All inputs can be either in RAM or PROGMEM.
class PrivateKey
{
public:
class PrivateKey {
public:
PrivateKey();
PrivateKey(const char *pemKey);
PrivateKey(const uint8_t *derKey, size_t derLen);
@ -87,7 +83,7 @@ public:
// Disable the copy constructor, we're pointer based
PrivateKey(const PrivateKey& that) = delete;
private:
private:
brssl::private_key *_key;
};
@ -97,9 +93,8 @@ private:
// for a more memory efficient way).
// Copies all associated data so no need to keep input PEM/DER certs.
// All inputs can be either in RAM or PROGMEM.
class X509List
{
public:
class X509List {
public:
X509List();
X509List(const char *pemCert);
X509List(const uint8_t *derCert, size_t derLen);
@ -109,23 +104,20 @@ public:
bool append(const uint8_t *derCert, size_t derLen);
// Accessors
size_t getCount() const
{
return _count;
size_t getCount() const {
return _count;
}
const br_x509_certificate *getX509Certs() const
{
return _cert;
const br_x509_certificate *getX509Certs() const {
return _cert;
}
const br_x509_trust_anchor *getTrustAnchors() const
{
return _ta;
const br_x509_trust_anchor *getTrustAnchors() const {
return _ta;
}
// Disable the copy constructor, we're pointer based
X509List(const X509List& that) = delete;
private:
private:
size_t _count;
br_x509_certificate *_cert;
br_x509_trust_anchor *_ta;
@ -135,64 +127,52 @@ private:
// significantly faster. Completely optional.
class WiFiClientSecure;
class Session
{
friend class WiFiClientSecure;
class Session {
friend class WiFiClientSecure;
public:
Session()
{
memset(&_session, 0, sizeof(_session));
}
private:
br_ssl_session_parameters *getSession()
{
return &_session;
}
public:
Session() { memset(&_session, 0, sizeof(_session)); }
private:
br_ssl_session_parameters *getSession() { return &_session; }
// The actual BearSSL ession information
br_ssl_session_parameters _session;
};
// Updater SHA256 hash and signature verification
class HashSHA256 : public UpdaterHashClass
{
public:
class HashSHA256 : public UpdaterHashClass {
public:
virtual void begin() override;
virtual void add(const void *data, uint32_t len) override;
virtual void end() override;
virtual int len() override;
virtual const void *hash() override;
private:
private:
br_sha256_context _cc;
unsigned char _sha256[32];
};
class SigningVerifier : public UpdaterVerifyClass
{
public:
class SigningVerifier : public UpdaterVerifyClass {
public:
virtual uint32_t length() override;
virtual bool verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) override;
public:
SigningVerifier(PublicKey *pubKey)
{
_pubKey = pubKey;
}
public:
SigningVerifier(PublicKey *pubKey) { _pubKey = pubKey; }
private:
private:
PublicKey *_pubKey;
};
// Stack thunked versions of calls
extern "C" {
extern unsigned char *thunk_br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len);
extern unsigned char *thunk_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len);
extern void thunk_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len);
};
};

View File

@ -1,20 +1,20 @@
/*
CertStoreBearSSL.cpp - Library for Arduino ESP8266
Copyright (c) 2018 Earle F. Philhower, III
CertStoreBearSSL.cpp - Library for Arduino ESP8266
Copyright (c) 2018 Earle F. Philhower, III
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 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.
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
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 "CertStoreBearSSL.h"
@ -27,213 +27,184 @@
#define DEBUG_BSSL(...)
#endif
namespace BearSSL
{
namespace BearSSL {
extern "C" {
// Callback for the x509 decoder
static void dn_append(void *ctx, const void *buf, size_t len)
{
br_sha256_context *sha1 = (br_sha256_context*)ctx;
br_sha256_update(sha1, buf, len);
}
// Callback for the x509 decoder
static void dn_append(void *ctx, const void *buf, size_t len) {
br_sha256_context *sha1 = (br_sha256_context*)ctx;
br_sha256_update(sha1, buf, len);
}
}
CertStore::CertInfo CertStore::_preprocessCert(uint32_t length, uint32_t offset, const void *raw)
{
CertStore::CertInfo ci;
CertStore::CertInfo CertStore::_preprocessCert(uint32_t length, uint32_t offset, const void *raw) {
CertStore::CertInfo ci;
// Clear the CertInfo
memset(&ci, 0, sizeof(ci));
// Clear the CertInfo
memset(&ci, 0, sizeof(ci));
// Process it using SHA256, same as the hashed_dn
br_x509_decoder_context *ctx = new br_x509_decoder_context;
br_sha256_context *sha256 = new br_sha256_context;
if (!ctx || !sha256)
{
DEBUG_BSSL("CertStore::_preprocessCert: OOM\n");
return ci;
}
br_sha256_init(sha256);
br_x509_decoder_init(ctx, dn_append, sha256, nullptr, nullptr);
br_x509_decoder_push(ctx, (const void*)raw, length);
// Copy result to structure
br_sha256_out(sha256, &ci.sha256);
ci.length = length;
ci.offset = offset;
// Clean up allocated memory
delete sha256;
delete ctx;
// Return result
// Process it using SHA256, same as the hashed_dn
br_x509_decoder_context *ctx = new br_x509_decoder_context;
br_sha256_context *sha256 = new br_sha256_context;
if (!ctx || !sha256) {
DEBUG_BSSL("CertStore::_preprocessCert: OOM\n");
return ci;
}
br_sha256_init(sha256);
br_x509_decoder_init(ctx, dn_append, sha256, nullptr, nullptr);
br_x509_decoder_push(ctx, (const void*)raw, length);
// Copy result to structure
br_sha256_out(sha256, &ci.sha256);
ci.length = length;
ci.offset = offset;
// Clean up allocated memory
delete sha256;
delete ctx;
// Return result
return ci;
}
// The certs.ar file is a UNIX ar format file, concatenating all the
// The certs.ar file is a UNIX ar format file, concatenating all the
// individual certificates into a single blob in a space-efficient way.
int CertStore::initCertStore(CertStoreFile *index, CertStoreFile *data)
{
int count = 0;
uint32_t offset = 0;
int CertStore::initCertStore(CertStoreFile *index, CertStoreFile *data) {
int count = 0;
uint32_t offset = 0;
_index = index;
_data = data;
_index = index;
_data = data;
if (!_index || !data)
{
return 0;
}
if (!_index || !data) {
return 0;
}
if (!_index->open(true))
{
return 0;
}
if (!_index->open(true)) {
return 0;
}
if (!_data->open(false))
{
_index->close();
return 0;
}
if (!_data->open(false)) {
_index->close();
return 0;
}
char magic[8];
if (_data->read(magic, sizeof(magic)) != sizeof(magic) ||
memcmp(magic, "!<arch>\n", sizeof(magic)))
{
_data->close();
_index->close();
return 0;
}
offset += sizeof(magic);
while (true)
{
char fileHeader[60];
// 0..15 = filename in ASCII
// 48...57 = length in decimal ASCII
uint32_t length;
if (data->read(fileHeader, sizeof(fileHeader)) != sizeof(fileHeader))
{
break;
}
offset += sizeof(fileHeader);
fileHeader[58] = 0;
if (1 != sscanf(fileHeader + 48, "%d", &length) || !length)
{
break;
}
void *raw = malloc(length);
if (!raw)
{
break;
}
if (_data->read(raw, length) != (ssize_t)length)
{
free(raw);
break;
}
// If the filename starts with "//" then this is a rename file, skip it
if (fileHeader[0] != '/' || fileHeader[1] != '/')
{
CertStore::CertInfo ci = _preprocessCert(length, offset, raw);
if (_index->write(&ci, sizeof(ci)) != (ssize_t)sizeof(ci))
{
free(raw);
break;
}
count++;
}
offset += length;
free(raw);
if (offset & 1)
{
char x;
_data->read(&x, 1);
offset++;
}
}
char magic[8];
if (_data->read(magic, sizeof(magic)) != sizeof(magic) ||
memcmp(magic, "!<arch>\n", sizeof(magic)) ) {
_data->close();
_index->close();
return count;
return 0;
}
offset += sizeof(magic);
while (true) {
char fileHeader[60];
// 0..15 = filename in ASCII
// 48...57 = length in decimal ASCII
uint32_t length;
if (data->read(fileHeader, sizeof(fileHeader)) != sizeof(fileHeader)) {
break;
}
offset += sizeof(fileHeader);
fileHeader[58] = 0;
if (1 != sscanf(fileHeader + 48, "%d", &length) || !length) {
break;
}
void *raw = malloc(length);
if (!raw) {
break;
}
if (_data->read(raw, length) != (ssize_t)length) {
free(raw);
break;
}
// If the filename starts with "//" then this is a rename file, skip it
if (fileHeader[0] != '/' || fileHeader[1] != '/') {
CertStore::CertInfo ci = _preprocessCert(length, offset, raw);
if (_index->write(&ci, sizeof(ci)) != (ssize_t)sizeof(ci)) {
free(raw);
break;
}
count++;
}
offset += length;
free(raw);
if (offset & 1) {
char x;
_data->read(&x, 1);
offset++;
}
}
_data->close();
_index->close();
return count;
}
void CertStore::installCertStore(br_x509_minimal_context *ctx)
{
br_x509_minimal_set_dynamic(ctx, (void*)this, findHashedTA, freeHashedTA);
void CertStore::installCertStore(br_x509_minimal_context *ctx) {
br_x509_minimal_set_dynamic(ctx, (void*)this, findHashedTA, freeHashedTA);
}
const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn, size_t len)
{
CertStore *cs = static_cast<CertStore*>(ctx);
CertStore::CertInfo ci;
const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn, size_t len) {
CertStore *cs = static_cast<CertStore*>(ctx);
CertStore::CertInfo ci;
if (!cs || len != sizeof(ci.sha256) || !cs->_index || !cs->_data)
{
return nullptr;
}
if (!cs->_index->open(false))
{
return nullptr;
}
while (cs->_index->read(&ci, sizeof(ci)) == sizeof(ci))
{
if (!memcmp(ci.sha256, hashed_dn, sizeof(ci.sha256)))
{
cs->_index->close();
uint8_t *der = (uint8_t*)malloc(ci.length);
if (!der)
{
return nullptr;
}
if (!cs->_data->open(false))
{
free(der);
return nullptr;
}
if (!cs->_data->seek(ci.offset))
{
cs->_data->close();
free(der);
return nullptr;
}
if (cs->_data->read(der, ci.length) != (ssize_t)ci.length)
{
free(der);
return nullptr;
}
cs->_data->close();
cs->_x509 = new X509List(der, ci.length);
free(der);
if (!cs->_x509)
{
DEBUG_BSSL("CertStore::findHashedTA: OOM\n");
return nullptr;
}
br_x509_trust_anchor *ta = (br_x509_trust_anchor*)cs->_x509->getTrustAnchors();
memcpy(ta->dn.data, ci.sha256, sizeof(ci.sha256));
ta->dn.len = sizeof(ci.sha256);
return ta;
}
}
cs->_index->close();
if (!cs || len != sizeof(ci.sha256) || !cs->_index || !cs->_data) {
return nullptr;
}
if (!cs->_index->open(false)) {
return nullptr;
}
while (cs->_index->read(&ci, sizeof(ci)) == sizeof(ci)) {
if (!memcmp(ci.sha256, hashed_dn, sizeof(ci.sha256))) {
cs->_index->close();
uint8_t *der = (uint8_t*)malloc(ci.length);
if (!der) {
return nullptr;
}
if (!cs->_data->open(false)) {
free(der);
return nullptr;
}
if (!cs->_data->seek(ci.offset)) {
cs->_data->close();
free(der);
return nullptr;
}
if (cs->_data->read(der, ci.length) != (ssize_t)ci.length) {
free(der);
return nullptr;
}
cs->_data->close();
cs->_x509 = new X509List(der, ci.length);
free(der);
if (!cs->_x509) {
DEBUG_BSSL("CertStore::findHashedTA: OOM\n");
return nullptr;
}
br_x509_trust_anchor *ta = (br_x509_trust_anchor*)cs->_x509->getTrustAnchors();
memcpy(ta->dn.data, ci.sha256, sizeof(ci.sha256));
ta->dn.len = sizeof(ci.sha256);
return ta;
}
}
cs->_index->close();
return nullptr;
}
void CertStore::freeHashedTA(void *ctx, const br_x509_trust_anchor *ta)
{
CertStore *cs = static_cast<CertStore*>(ctx);
(void) ta; // Unused
delete cs->_x509;
cs->_x509 = nullptr;
void CertStore::freeHashedTA(void *ctx, const br_x509_trust_anchor *ta) {
CertStore *cs = static_cast<CertStore*>(ctx);
(void) ta; // Unused
delete cs->_x509;
cs->_x509 = nullptr;
}
}

View File

@ -1,20 +1,20 @@
/*
CertStoreBearSSL.h - Library for Arduino ESP8266
Copyright (c) 2018 Earle F. Philhower, III
CertStoreBearSSL.h - Library for Arduino ESP8266
Copyright (c) 2018 Earle F. Philhower, III
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 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.
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
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 _CERTSTORE_BEARSSL_H
@ -28,8 +28,7 @@
// of a large set of certificates stored on SPIFFS of SD card to
// be dynamically used when validating a X509 certificate
namespace BearSSL
{
namespace BearSSL {
// Subclass this and provide virtual functions appropriate for your storage.
// Required because there are conflicting definitions for a "File" in the
@ -40,14 +39,13 @@ namespace BearSSL
// NOTE: This virtual class may migrate to a templated model in a future
// release. Expect some changes to the interface, no matter what, as the
// SD and SPIFFS filesystem get unified.
class CertStoreFile
{
public:
class CertStoreFile {
public:
CertStoreFile() {};
virtual ~CertStoreFile() {};
// The main API
virtual bool open(bool write = false) = 0;
virtual bool open(bool write=false) = 0;
virtual bool seek(size_t absolute_pos) = 0;
virtual ssize_t read(void *dest, size_t bytes) = 0;
virtual ssize_t write(void *dest, size_t bytes) = 0;
@ -55,9 +53,8 @@ public:
};
class CertStore
{
public:
class CertStore {
public:
CertStore() { };
~CertStore() { };
@ -67,7 +64,7 @@ public:
// Installs the cert store into the X509 decoder (normally via static function callbacks)
void installCertStore(br_x509_minimal_context *ctx);
protected:
protected:
CertStoreFile *_index = nullptr;
CertStoreFile *_data = nullptr;
X509List *_x509 = nullptr;
@ -77,12 +74,11 @@ protected:
static void freeHashedTA(void *ctx, const br_x509_trust_anchor *ta);
// The binary format of the index file
class CertInfo
{
class CertInfo {
public:
uint8_t sha256[32];
uint32_t offset;
uint32_t length;
uint8_t sha256[32];
uint32_t offset;
uint32_t length;
};
static CertInfo _preprocessCert(uint32_t length, uint32_t offset, const void *raw);

View File

@ -1,26 +1,26 @@
/*
ESP8266WiFi.cpp - WiFi library for esp8266
ESP8266WiFi.cpp - WiFi library for esp8266
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
Reworked on 28 Dec 2015 by Markus Sattler
Reworked on 28 Dec 2015 by Markus Sattler
*/
*/
#include "ESP8266WiFi.h"
@ -45,11 +45,10 @@ extern "C" {
/**
Output WiFi settings to an object derived from Print interface (like Serial).
@param p Print interface
*/
void ESP8266WiFiClass::printDiag(Print& p)
{
* Output WiFi settings to an object derived from Print interface (like Serial).
* @param p Print interface
*/
void ESP8266WiFiClass::printDiag(Print& p) {
const char* modes[] = { "NULL", "STA", "AP", "STA+AP" };
p.print("Mode: ");
p.println(modes[wifi_get_opmode()]);
@ -76,7 +75,7 @@ void ESP8266WiFiClass::printDiag(Print& p)
char ssid[33]; //ssid can be up to 32chars, => plus null term
memcpy(ssid, conf.ssid, sizeof(conf.ssid));
ssid[32] = 0; //nullterm in case of 32 char ssid
p.print("SSID (");
p.print(strlen(ssid));
p.print("): ");

View File

@ -1,23 +1,23 @@
/*
ESP8266WiFi.h - esp8266 Wifi support.
Based on WiFi.h from Arduino WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
ESP8266WiFi.h - esp8266 Wifi support.
Based on WiFi.h from Arduino WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
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 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.
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
*/
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 WiFi_h
#define WiFi_h
@ -54,36 +54,35 @@ extern "C" {
#endif
class ESP8266WiFiClass : public ESP8266WiFiGenericClass, public ESP8266WiFiSTAClass, public ESP8266WiFiScanClass, public ESP8266WiFiAPClass
{
public:
class ESP8266WiFiClass : public ESP8266WiFiGenericClass, public ESP8266WiFiSTAClass, public ESP8266WiFiScanClass, public ESP8266WiFiAPClass {
public:
// workaround same function name with different signature
using ESP8266WiFiGenericClass::channel;
// workaround same function name with different signature
using ESP8266WiFiGenericClass::channel;
using ESP8266WiFiSTAClass::SSID;
using ESP8266WiFiSTAClass::RSSI;
using ESP8266WiFiSTAClass::BSSID;
using ESP8266WiFiSTAClass::BSSIDstr;
using ESP8266WiFiSTAClass::SSID;
using ESP8266WiFiSTAClass::RSSI;
using ESP8266WiFiSTAClass::BSSID;
using ESP8266WiFiSTAClass::BSSIDstr;
using ESP8266WiFiScanClass::SSID;
using ESP8266WiFiScanClass::encryptionType;
using ESP8266WiFiScanClass::RSSI;
using ESP8266WiFiScanClass::BSSID;
using ESP8266WiFiScanClass::BSSIDstr;
using ESP8266WiFiScanClass::channel;
using ESP8266WiFiScanClass::isHidden;
using ESP8266WiFiScanClass::SSID;
using ESP8266WiFiScanClass::encryptionType;
using ESP8266WiFiScanClass::RSSI;
using ESP8266WiFiScanClass::BSSID;
using ESP8266WiFiScanClass::BSSIDstr;
using ESP8266WiFiScanClass::channel;
using ESP8266WiFiScanClass::isHidden;
// ----------------------------------------------------------------------------------------------
// ------------------------------------------- Debug --------------------------------------------
// ----------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------
// ------------------------------------------- Debug --------------------------------------------
// ----------------------------------------------------------------------------------------------
public:
public:
void printDiag(Print& dest);
void printDiag(Print& dest);
friend class WiFiClient;
friend class WiFiServer;
friend class WiFiClient;
friend class WiFiServer;
};

View File

@ -1,442 +1,383 @@
/*
ESP8266WiFiSTA.cpp - WiFi library for esp8266
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
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
Reworked on 28 Dec 2015 by Markus Sattler
*/
#include "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiAP.h"
extern "C" {
#include "c_types.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
}
#include "debug.h"
// -----------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------- Private functions ------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs);
/**
compare two AP configurations
@param lhs softap_config
@param rhs softap_config
@return equal
*/
static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs)
{
if (strcmp(reinterpret_cast<const char*>(lhs.ssid), reinterpret_cast<const char*>(rhs.ssid)) != 0)
{
return false;
}
if (strcmp(reinterpret_cast<const char*>(lhs.password), reinterpret_cast<const char*>(rhs.password)) != 0)
{
return false;
}
if (lhs.channel != rhs.channel)
{
return false;
}
if (lhs.ssid_hidden != rhs.ssid_hidden)
{
return false;
}
if (lhs.max_connection != rhs.max_connection)
{
return false;
}
if (lhs.beacon_interval != rhs.beacon_interval)
{
return false;
}
if (lhs.authmode != rhs.authmode)
{
return false;
}
return true;
}
// -----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- AP function -----------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
/**
Set up an access point
@param ssid Pointer to the SSID (max 31 char).
@param passphrase For WPA2 min 8 char, for open use NULL (max 63 char).
@param channel WiFi channel number, 1 - 13.
@param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID)
@param max_connection Max simultaneous connected clients, 0 - 8. https://bbs.espressif.com/viewtopic.php?f=46&t=481&p=1832&hilit=max_connection#p1832
*/
bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection)
{
if (!WiFi.enableAP(true))
{
// enable AP failed
DEBUG_WIFI("[AP] enableAP failed!\n");
return false;
}
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) > 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;
}
bool ret = true;
struct softap_config conf;
strcpy(reinterpret_cast<char*>(conf.ssid), ssid);
conf.channel = channel;
conf.ssid_len = strlen(ssid);
conf.ssid_hidden = ssid_hidden;
conf.max_connection = max_connection;
conf.beacon_interval = 100;
if (!passphrase || strlen(passphrase) == 0)
{
conf.authmode = AUTH_OPEN;
*conf.password = 0;
}
else
{
conf.authmode = AUTH_WPA2_PSK;
strcpy(reinterpret_cast<char*>(conf.password), passphrase);
}
struct softap_config conf_compare;
if (WiFi._persistent)
{
wifi_softap_get_config_default(&conf_compare);
}
else
{
wifi_softap_get_config(&conf_compare);
}
if (!softap_config_equal(conf, conf_compare))
{
ETS_UART_INTR_DISABLE();
if (WiFi._persistent)
{
ret = wifi_softap_set_config(&conf);
}
else
{
ret = wifi_softap_set_config_current(&conf);
}
ETS_UART_INTR_ENABLE();
if (!ret)
{
DEBUG_WIFI("[AP] set_config failed!\n");
return false;
}
}
else
{
DEBUG_WIFI("[AP] softap config unchanged\n");
}
if (wifi_softap_dhcps_status() != DHCP_STARTED)
{
DEBUG_WIFI("[AP] DHCP not started, starting...\n");
if (!wifi_softap_dhcps_start())
{
DEBUG_WIFI("[AP] wifi_softap_dhcps_start failed!\n");
ret = false;
}
}
// check IP config
struct ip_info ip;
if (wifi_get_ip_info(SOFTAP_IF, &ip))
{
if (ip.ip.addr == 0x00000000)
{
// Invalid config
DEBUG_WIFI("[AP] IP config Invalid resetting...\n");
//192.168.244.1 , 192.168.244.1 , 255.255.255.0
ret = softAPConfig(0x01F4A8C0, 0x01F4A8C0, 0x00FFFFFF);
if (!ret)
{
DEBUG_WIFI("[AP] softAPConfig failed!\n");
ret = false;
}
}
}
else
{
DEBUG_WIFI("[AP] wifi_get_ip_info failed!\n");
ret = false;
}
return ret;
}
bool ESP8266WiFiAPClass::softAP(const String& ssid, const String& passphrase, int channel, int ssid_hidden, int max_connection)
{
return softAP(ssid.c_str(), passphrase.c_str(), channel, ssid_hidden, max_connection);
}
/**
Configure access point
@param local_ip access point IP
@param gateway gateway IP (0.0.0.0 to disable)
@param subnet subnet mask
*/
bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
{
DEBUG_WIFI("[APConfig] local_ip: %s gateway: %s subnet: %s\n", local_ip.toString().c_str(), gateway.toString().c_str(), subnet.toString().c_str());
if (!WiFi.enableAP(true))
{
// enable AP failed
DEBUG_WIFI("[APConfig] enableAP failed!\n");
return false;
}
bool ret = true;
if (!local_ip.isV4()
|| !subnet.isV4()
#if LWIP_IPV6
// uninitialized gateway is valid
|| gateway.isV6()
#endif
)
{
return false;
}
struct ip_info info;
info.ip.addr = local_ip.v4();
info.gw.addr = gateway.v4();
info.netmask.addr = subnet.v4();
if (!wifi_softap_dhcps_stop())
{
DEBUG_WIFI("[APConfig] wifi_softap_dhcps_stop failed!\n");
}
if (!wifi_set_ip_info(SOFTAP_IF, &info))
{
DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n");
ret = false;
}
struct dhcps_lease dhcp_lease;
IPAddress ip = local_ip;
ip[3] += 99;
dhcp_lease.start_ip.addr = ip.v4();
DEBUG_WIFI("[APConfig] DHCP IP start: %s\n", ip.toString().c_str());
ip[3] += 100;
dhcp_lease.end_ip.addr = ip.v4();
DEBUG_WIFI("[APConfig] DHCP IP end: %s\n", ip.toString().c_str());
if (!wifi_softap_set_dhcps_lease(&dhcp_lease))
{
DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n");
ret = false;
}
// set lease time to 720min --> 12h
if (!wifi_softap_set_dhcps_lease_time(720))
{
DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_lease_time failed!\n");
ret = false;
}
uint8 mode = info.gw.addr ? 1 : 0;
if (!wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode))
{
DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_offer_option failed!\n");
ret = false;
}
if (!wifi_softap_dhcps_start())
{
DEBUG_WIFI("[APConfig] wifi_softap_dhcps_start failed!\n");
ret = false;
}
// check config
if (wifi_get_ip_info(SOFTAP_IF, &info))
{
if (info.ip.addr == 0x00000000)
{
DEBUG_WIFI("[APConfig] IP config Invalid?!\n");
ret = false;
}
else if (local_ip.v4() != info.ip.addr)
{
ip = info.ip.addr;
DEBUG_WIFI("[APConfig] IP config not set correct?! new IP: %s\n", ip.toString().c_str());
ret = false;
}
}
else
{
DEBUG_WIFI("[APConfig] wifi_get_ip_info failed!\n");
ret = false;
}
return ret;
}
/**
Disconnect from the network (close AP)
@param wifioff disable mode?
@return one value of wl_status_t enum
*/
bool ESP8266WiFiAPClass::softAPdisconnect(bool wifioff)
{
bool ret;
struct softap_config conf;
*conf.ssid = 0;
*conf.password = 0;
conf.authmode = AUTH_OPEN;
ETS_UART_INTR_DISABLE();
if (WiFi._persistent)
{
ret = wifi_softap_set_config(&conf);
}
else
{
ret = wifi_softap_set_config_current(&conf);
}
ETS_UART_INTR_ENABLE();
if (!ret)
{
DEBUG_WIFI("[APdisconnect] set_config failed!\n");
}
if (ret && wifioff)
{
ret = WiFi.enableAP(false);
}
return ret;
}
/**
Get the count of the Station / client that are connected to the softAP interface
@return Stations count
*/
uint8_t ESP8266WiFiAPClass::softAPgetStationNum()
{
return wifi_softap_get_station_num();
}
/**
Get the softAP interface IP address.
@return IPAddress softAP IP
*/
IPAddress ESP8266WiFiAPClass::softAPIP()
{
struct ip_info ip;
wifi_get_ip_info(SOFTAP_IF, &ip);
return IPAddress(ip.ip.addr);
}
/**
Get the softAP interface MAC address.
@param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
@return pointer to uint8_t
*/
uint8_t* ESP8266WiFiAPClass::softAPmacAddress(uint8_t* mac)
{
wifi_get_macaddr(SOFTAP_IF, mac);
return mac;
}
/**
Get the softAP interface MAC address.
@return String mac
*/
String ESP8266WiFiAPClass::softAPmacAddress(void)
{
uint8_t mac[6];
char macStr[18] = { 0 };
wifi_get_macaddr(SOFTAP_IF, mac);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(macStr);
}
/**
Get the configured(Not-In-Flash) softAP SSID name.
@return String SSID.
*/
String ESP8266WiFiAPClass::softAPSSID() const
{
struct softap_config config;
wifi_softap_get_config(&config);
char* name = reinterpret_cast<char*>(config.ssid);
char ssid[sizeof(config.ssid) + 1];
memcpy(ssid, name, sizeof(config.ssid));
ssid[sizeof(config.ssid)] = '\0';
return String(ssid);
}
/**
Get the configured(Not-In-Flash) softAP PSK or PASSWORD.
@return String psk.
*/
String ESP8266WiFiAPClass::softAPPSK() const
{
struct softap_config config;
wifi_softap_get_config(&config);
char* pass = reinterpret_cast<char*>(config.password);
char psk[sizeof(config.password) + 1];
memcpy(psk, pass, sizeof(config.password));
psk[sizeof(config.password)] = '\0';
return String(psk);
}
/*
ESP8266WiFiSTA.cpp - WiFi library for esp8266
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
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
Reworked on 28 Dec 2015 by Markus Sattler
*/
#include "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiAP.h"
extern "C" {
#include "c_types.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
}
#include "debug.h"
// -----------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------- Private functions ------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs);
/**
* compare two AP configurations
* @param lhs softap_config
* @param rhs softap_config
* @return equal
*/
static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs) {
if(strcmp(reinterpret_cast<const char*>(lhs.ssid), reinterpret_cast<const char*>(rhs.ssid)) != 0) {
return false;
}
if(strcmp(reinterpret_cast<const char*>(lhs.password), reinterpret_cast<const char*>(rhs.password)) != 0) {
return false;
}
if(lhs.channel != rhs.channel) {
return false;
}
if(lhs.ssid_hidden != rhs.ssid_hidden) {
return false;
}
if(lhs.max_connection != rhs.max_connection) {
return false;
}
if(lhs.beacon_interval != rhs.beacon_interval) {
return false;
}
if(lhs.authmode != rhs.authmode) {
return false;
}
return true;
}
// -----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- AP function -----------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
/**
* Set up an access point
* @param ssid Pointer to the SSID (max 31 char).
* @param passphrase For WPA2 min 8 char, for open use NULL (max 63 char).
* @param channel WiFi channel number, 1 - 13.
* @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID)
* @param max_connection Max simultaneous connected clients, 0 - 8. https://bbs.espressif.com/viewtopic.php?f=46&t=481&p=1832&hilit=max_connection#p1832
*/
bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection) {
if(!WiFi.enableAP(true)) {
// enable AP failed
DEBUG_WIFI("[AP] enableAP failed!\n");
return false;
}
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) > 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;
}
bool ret = true;
struct softap_config conf;
strcpy(reinterpret_cast<char*>(conf.ssid), ssid);
conf.channel = channel;
conf.ssid_len = strlen(ssid);
conf.ssid_hidden = ssid_hidden;
conf.max_connection = max_connection;
conf.beacon_interval = 100;
if(!passphrase || strlen(passphrase) == 0) {
conf.authmode = AUTH_OPEN;
*conf.password = 0;
} else {
conf.authmode = AUTH_WPA2_PSK;
strcpy(reinterpret_cast<char*>(conf.password), passphrase);
}
struct softap_config conf_compare;
if(WiFi._persistent){
wifi_softap_get_config_default(&conf_compare);
}
else {
wifi_softap_get_config(&conf_compare);
}
if(!softap_config_equal(conf, conf_compare)) {
ETS_UART_INTR_DISABLE();
if(WiFi._persistent) {
ret = wifi_softap_set_config(&conf);
} else {
ret = wifi_softap_set_config_current(&conf);
}
ETS_UART_INTR_ENABLE();
if(!ret) {
DEBUG_WIFI("[AP] set_config failed!\n");
return false;
}
} else {
DEBUG_WIFI("[AP] softap config unchanged\n");
}
if(wifi_softap_dhcps_status() != DHCP_STARTED) {
DEBUG_WIFI("[AP] DHCP not started, starting...\n");
if(!wifi_softap_dhcps_start()) {
DEBUG_WIFI("[AP] wifi_softap_dhcps_start failed!\n");
ret = false;
}
}
// check IP config
struct ip_info ip;
if(wifi_get_ip_info(SOFTAP_IF, &ip)) {
if(ip.ip.addr == 0x00000000) {
// Invalid config
DEBUG_WIFI("[AP] IP config Invalid resetting...\n");
//192.168.244.1 , 192.168.244.1 , 255.255.255.0
ret = softAPConfig(0x01F4A8C0, 0x01F4A8C0, 0x00FFFFFF);
if(!ret) {
DEBUG_WIFI("[AP] softAPConfig failed!\n");
ret = false;
}
}
} else {
DEBUG_WIFI("[AP] wifi_get_ip_info failed!\n");
ret = false;
}
return ret;
}
bool ESP8266WiFiAPClass::softAP(const String& ssid, const String& passphrase, int channel, int ssid_hidden, int max_connection) {
return softAP(ssid.c_str(), passphrase.c_str(), channel, ssid_hidden, max_connection);
}
/**
* Configure access point
* @param local_ip access point IP
* @param gateway gateway IP (0.0.0.0 to disable)
* @param subnet subnet mask
*/
bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) {
DEBUG_WIFI("[APConfig] local_ip: %s gateway: %s subnet: %s\n", local_ip.toString().c_str(), gateway.toString().c_str(), subnet.toString().c_str());
if(!WiFi.enableAP(true)) {
// enable AP failed
DEBUG_WIFI("[APConfig] enableAP failed!\n");
return false;
}
bool ret = true;
if ( !local_ip.isV4()
|| !subnet.isV4()
#if LWIP_IPV6
// uninitialized gateway is valid
|| gateway.isV6()
#endif
) {
return false;
}
struct ip_info info;
info.ip.addr = local_ip.v4();
info.gw.addr = gateway.v4();
info.netmask.addr = subnet.v4();
if(!wifi_softap_dhcps_stop()) {
DEBUG_WIFI("[APConfig] wifi_softap_dhcps_stop failed!\n");
}
if(!wifi_set_ip_info(SOFTAP_IF, &info)) {
DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n");
ret = false;
}
struct dhcps_lease dhcp_lease;
IPAddress ip = local_ip;
ip[3] += 99;
dhcp_lease.start_ip.addr = ip.v4();
DEBUG_WIFI("[APConfig] DHCP IP start: %s\n", ip.toString().c_str());
ip[3] += 100;
dhcp_lease.end_ip.addr = ip.v4();
DEBUG_WIFI("[APConfig] DHCP IP end: %s\n", ip.toString().c_str());
if(!wifi_softap_set_dhcps_lease(&dhcp_lease)) {
DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n");
ret = false;
}
// set lease time to 720min --> 12h
if(!wifi_softap_set_dhcps_lease_time(720)) {
DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_lease_time failed!\n");
ret = false;
}
uint8 mode = info.gw.addr ? 1 : 0;
if(!wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode)) {
DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_offer_option failed!\n");
ret = false;
}
if(!wifi_softap_dhcps_start()) {
DEBUG_WIFI("[APConfig] wifi_softap_dhcps_start failed!\n");
ret = false;
}
// check config
if(wifi_get_ip_info(SOFTAP_IF, &info)) {
if(info.ip.addr == 0x00000000) {
DEBUG_WIFI("[APConfig] IP config Invalid?!\n");
ret = false;
} else if(local_ip.v4() != info.ip.addr) {
ip = info.ip.addr;
DEBUG_WIFI("[APConfig] IP config not set correct?! new IP: %s\n", ip.toString().c_str());
ret = false;
}
} else {
DEBUG_WIFI("[APConfig] wifi_get_ip_info failed!\n");
ret = false;
}
return ret;
}
/**
* Disconnect from the network (close AP)
* @param wifioff disable mode?
* @return one value of wl_status_t enum
*/
bool ESP8266WiFiAPClass::softAPdisconnect(bool wifioff) {
bool ret;
struct softap_config conf;
*conf.ssid = 0;
*conf.password = 0;
conf.authmode = AUTH_OPEN;
ETS_UART_INTR_DISABLE();
if(WiFi._persistent) {
ret = wifi_softap_set_config(&conf);
} else {
ret = wifi_softap_set_config_current(&conf);
}
ETS_UART_INTR_ENABLE();
if(!ret) {
DEBUG_WIFI("[APdisconnect] set_config failed!\n");
}
if(ret && wifioff) {
ret = WiFi.enableAP(false);
}
return ret;
}
/**
* Get the count of the Station / client that are connected to the softAP interface
* @return Stations count
*/
uint8_t ESP8266WiFiAPClass::softAPgetStationNum() {
return wifi_softap_get_station_num();
}
/**
* Get the softAP interface IP address.
* @return IPAddress softAP IP
*/
IPAddress ESP8266WiFiAPClass::softAPIP() {
struct ip_info ip;
wifi_get_ip_info(SOFTAP_IF, &ip);
return IPAddress(ip.ip.addr);
}
/**
* Get the softAP interface MAC address.
* @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
* @return pointer to uint8_t*
*/
uint8_t* ESP8266WiFiAPClass::softAPmacAddress(uint8_t* mac) {
wifi_get_macaddr(SOFTAP_IF, mac);
return mac;
}
/**
* Get the softAP interface MAC address.
* @return String mac
*/
String ESP8266WiFiAPClass::softAPmacAddress(void) {
uint8_t mac[6];
char macStr[18] = { 0 };
wifi_get_macaddr(SOFTAP_IF, mac);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(macStr);
}
/**
* Get the configured(Not-In-Flash) softAP SSID name.
* @return String SSID.
*/
String ESP8266WiFiAPClass::softAPSSID() const {
struct softap_config config;
wifi_softap_get_config(&config);
char* name = reinterpret_cast<char*>(config.ssid);
char ssid[sizeof(config.ssid) + 1];
memcpy(ssid, name, sizeof(config.ssid));
ssid[sizeof(config.ssid)] = '\0';
return String(ssid);
}
/**
* Get the configured(Not-In-Flash) softAP PSK or PASSWORD.
* @return String psk.
*/
String ESP8266WiFiAPClass::softAPPSK() const {
struct softap_config config;
wifi_softap_get_config(&config);
char* pass = reinterpret_cast<char*>(config.password);
char psk[sizeof(config.password) + 1];
memcpy(psk, pass, sizeof(config.password));
psk[sizeof(config.password)] = '\0';
return String(psk);
}

View File

@ -1,59 +1,58 @@
/*
ESP8266WiFiAP.h - esp8266 Wifi support.
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
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 ESP8266WIFIAP_H_
#define ESP8266WIFIAP_H_
#include "ESP8266WiFiType.h"
#include "ESP8266WiFiGeneric.h"
class ESP8266WiFiAPClass
{
// ----------------------------------------------------------------------------------------------
// ----------------------------------------- AP function ----------------------------------------
// ----------------------------------------------------------------------------------------------
public:
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4);
bool softAP(const String& ssid, const String& passphrase = emptyString, int channel = 1, int ssid_hidden = 0, int max_connection = 4);
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
bool softAPdisconnect(bool wifioff = false);
uint8_t softAPgetStationNum();
IPAddress softAPIP();
uint8_t* softAPmacAddress(uint8_t* mac);
String softAPmacAddress(void);
String softAPSSID() const;
String softAPPSK() const;
protected:
};
#endif /* ESP8266WIFIAP_H_*/
/*
ESP8266WiFiAP.h - esp8266 Wifi support.
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
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 ESP8266WIFIAP_H_
#define ESP8266WIFIAP_H_
#include "ESP8266WiFiType.h"
#include "ESP8266WiFiGeneric.h"
class ESP8266WiFiAPClass {
// ----------------------------------------------------------------------------------------------
// ----------------------------------------- AP function ----------------------------------------
// ----------------------------------------------------------------------------------------------
public:
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4);
bool softAP(const String& ssid,const String& passphrase = emptyString,int channel = 1,int ssid_hidden = 0,int max_connection = 4);
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
bool softAPdisconnect(bool wifioff = false);
uint8_t softAPgetStationNum();
IPAddress softAPIP();
uint8_t* softAPmacAddress(uint8_t* mac);
String softAPmacAddress(void);
String softAPSSID() const;
String softAPPSK() const;
protected:
};
#endif /* ESP8266WIFIAP_H_*/

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +1,115 @@
/*
ESP8266WiFiGeneric.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFIGENERIC_H_
#define ESP8266WIFIGENERIC_H_
#include "ESP8266WiFiType.h"
#include <functional>
#include <memory>
#ifdef DEBUG_ESP_WIFI
#ifdef DEBUG_ESP_PORT
#define DEBUG_WIFI_GENERIC(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ )
#endif
#endif
#ifndef DEBUG_WIFI_GENERIC
#define DEBUG_WIFI_GENERIC(...) do { (void)0; } while (0)
#endif
struct WiFiEventHandlerOpaque;
typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
typedef void (*WiFiEventCb)(WiFiEvent_t);
class ESP8266WiFiGenericClass
{
// ----------------------------------------------------------------------------------------------
// -------------------------------------- Generic WiFi function ---------------------------------
// ----------------------------------------------------------------------------------------------
public:
ESP8266WiFiGenericClass();
// Note: this function is deprecated. Use one of the functions below instead.
void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated));
// Subscribe to specific event and get event information as an argument to the callback
WiFiEventHandler onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)>);
WiFiEventHandler onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)>);
WiFiEventHandler onStationModeAuthModeChanged(std::function<void(const WiFiEventStationModeAuthModeChanged&)>);
WiFiEventHandler onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)>);
WiFiEventHandler onStationModeDHCPTimeout(std::function<void(void)>);
WiFiEventHandler onSoftAPModeStationConnected(std::function<void(const WiFiEventSoftAPModeStationConnected&)>);
WiFiEventHandler onSoftAPModeStationDisconnected(std::function<void(const WiFiEventSoftAPModeStationDisconnected&)>);
WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function<void(const WiFiEventSoftAPModeProbeRequestReceived&)>);
// WiFiEventHandler onWiFiModeChange(std::function<void(const WiFiEventModeChange&)>);
int32_t channel(void);
bool setSleepMode(WiFiSleepType_t type, uint8_t listenInterval = 0);
WiFiSleepType_t getSleepMode();
uint8_t getListenInterval();
bool isSleepLevelMax();
bool setPhyMode(WiFiPhyMode_t mode);
WiFiPhyMode_t getPhyMode();
void setOutputPower(float dBm);
void persistent(bool persistent);
bool mode(WiFiMode_t);
WiFiMode_t getMode();
bool enableSTA(bool enable);
bool enableAP(bool enable);
bool forceSleepBegin(uint32 sleepUs = 0);
bool forceSleepWake();
static void preinitWiFiOff(); //meant to be called in user-defined preinit()
protected:
static bool _persistent;
static WiFiMode_t _forceSleepLastMode;
static void _eventCallback(void *event);
// ----------------------------------------------------------------------------------------------
// ------------------------------------ Generic Network function --------------------------------
// ----------------------------------------------------------------------------------------------
public:
int hostByName(const char* aHostname, IPAddress& aResult);
int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms);
bool getPersistent();
protected:
friend class ESP8266WiFiSTAClass;
friend class ESP8266WiFiScanClass;
friend class ESP8266WiFiAPClass;
};
#endif /* ESP8266WIFIGENERIC_H_ */
/*
ESP8266WiFiGeneric.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFIGENERIC_H_
#define ESP8266WIFIGENERIC_H_
#include "ESP8266WiFiType.h"
#include <functional>
#include <memory>
#ifdef DEBUG_ESP_WIFI
#ifdef DEBUG_ESP_PORT
#define DEBUG_WIFI_GENERIC(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ )
#endif
#endif
#ifndef DEBUG_WIFI_GENERIC
#define DEBUG_WIFI_GENERIC(...) do { (void)0; } while (0)
#endif
struct WiFiEventHandlerOpaque;
typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
typedef void (*WiFiEventCb)(WiFiEvent_t);
class ESP8266WiFiGenericClass {
// ----------------------------------------------------------------------------------------------
// -------------------------------------- Generic WiFi function ---------------------------------
// ----------------------------------------------------------------------------------------------
public:
ESP8266WiFiGenericClass();
// Note: this function is deprecated. Use one of the functions below instead.
void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated));
// Subscribe to specific event and get event information as an argument to the callback
WiFiEventHandler onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)>);
WiFiEventHandler onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)>);
WiFiEventHandler onStationModeAuthModeChanged(std::function<void(const WiFiEventStationModeAuthModeChanged&)>);
WiFiEventHandler onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)>);
WiFiEventHandler onStationModeDHCPTimeout(std::function<void(void)>);
WiFiEventHandler onSoftAPModeStationConnected(std::function<void(const WiFiEventSoftAPModeStationConnected&)>);
WiFiEventHandler onSoftAPModeStationDisconnected(std::function<void(const WiFiEventSoftAPModeStationDisconnected&)>);
WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function<void(const WiFiEventSoftAPModeProbeRequestReceived&)>);
// WiFiEventHandler onWiFiModeChange(std::function<void(const WiFiEventModeChange&)>);
int32_t channel(void);
bool setSleepMode(WiFiSleepType_t type, uint8_t listenInterval = 0);
WiFiSleepType_t getSleepMode();
uint8_t getListenInterval ();
bool isSleepLevelMax ();
bool setPhyMode(WiFiPhyMode_t mode);
WiFiPhyMode_t getPhyMode();
void setOutputPower(float dBm);
void persistent(bool persistent);
bool mode(WiFiMode_t);
WiFiMode_t getMode();
bool enableSTA(bool enable);
bool enableAP(bool enable);
bool forceSleepBegin(uint32 sleepUs = 0);
bool forceSleepWake();
static void preinitWiFiOff (); //meant to be called in user-defined preinit()
protected:
static bool _persistent;
static WiFiMode_t _forceSleepLastMode;
static void _eventCallback(void *event);
// ----------------------------------------------------------------------------------------------
// ------------------------------------ Generic Network function --------------------------------
// ----------------------------------------------------------------------------------------------
public:
int hostByName(const char* aHostname, IPAddress& aResult);
int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms);
bool getPersistent();
protected:
friend class ESP8266WiFiSTAClass;
friend class ESP8266WiFiScanClass;
friend class ESP8266WiFiAPClass;
};
#endif /* ESP8266WIFIGENERIC_H_ */

View File

@ -1,309 +1,265 @@
/**
@file ESP8266WiFiMulti.cpp
@date 16.05.2015
@author Markus Sattler
Copyright (c) 2015 Markus Sattler. 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
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 "ESP8266WiFiMulti.h"
#include <limits.h>
#include <string.h>
ESP8266WiFiMulti::ESP8266WiFiMulti()
{
}
ESP8266WiFiMulti::~ESP8266WiFiMulti()
{
APlistClean();
}
bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase)
{
return APlistAdd(ssid, passphrase);
}
bool ESP8266WiFiMulti::existsAP(const char* ssid, const char *passphrase)
{
return APlistExists(ssid, passphrase);
}
wl_status_t ESP8266WiFiMulti::run(void)
{
wl_status_t status = WiFi.status();
if (status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED)
{
int8_t scanResult = WiFi.scanComplete();
if (scanResult == WIFI_SCAN_RUNNING)
{
// scan is running, do nothing yet
status = WL_NO_SSID_AVAIL;
return status;
}
if (scanResult == 0)
{
// scan done, no ssids found. Start another scan.
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
WiFi.scanDelete();
DEBUG_WIFI_MULTI("\n\n");
delay(0);
WiFi.disconnect();
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
// scan wifi async mode
WiFi.scanNetworks(true);
return status;
}
if (scanResult > 0)
{
// scan done, analyze
WifiAPEntry bestNetwork { NULL, NULL };
int bestNetworkDb = INT_MIN;
uint8 bestBSSID[6];
int32_t bestChannel;
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
delay(0);
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
for (int8_t i = 0; i < scanResult; ++i)
{
String ssid_scan;
int32_t rssi_scan;
uint8_t sec_scan;
uint8_t* BSSID_scan;
int32_t chan_scan;
bool hidden_scan;
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
bool known = false;
for (auto entry : APlist)
{
if (ssid_scan == entry.ssid) // SSID match
{
known = true;
if (rssi_scan > bestNetworkDb) // best network
{
if (sec_scan == ENC_TYPE_NONE || entry.passphrase) // check for passphrase if not open wlan
{
bestNetworkDb = rssi_scan;
bestChannel = chan_scan;
bestNetwork = entry;
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
}
}
break;
}
}
if (known)
{
DEBUG_WIFI_MULTI(" ---> ");
}
else
{
DEBUG_WIFI_MULTI(" ");
}
DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*');
delay(0);
}
// clean up ram
WiFi.scanDelete();
DEBUG_WIFI_MULTI("\n\n");
delay(0);
if (bestNetwork.ssid)
{
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
status = WiFi.status();
static const uint32_t connectTimeout = 5000; //5s timeout
auto startTime = millis();
// wait for connection, fail, or timeout
while (status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout)
{
delay(10);
status = WiFi.status();
}
#ifdef DEBUG_ESP_WIFI
IPAddress ip;
uint8_t * mac;
switch (status)
{
case WL_CONNECTED:
ip = WiFi.localIP();
mac = WiFi.BSSID();
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID().c_str());
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
break;
case WL_NO_SSID_AVAIL:
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n");
break;
case WL_CONNECT_FAILED:
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n");
break;
default:
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status);
break;
}
#endif
}
else
{
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
}
return status;
}
// scan failed, or some other condition not handled above. Start another scan.
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
WiFi.disconnect();
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
// scan wifi async mode
WiFi.scanNetworks(true);
}
return status;
}
// ##################################################################################
bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase)
{
WifiAPEntry newAP;
if (!ssid || *ssid == 0x00 || strlen(ssid) > 32)
{
// fail SSID too long or missing!
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid too long\n");
return false;
}
//for passphrase, max is 63 ascii + null. For psk, 64hex + null.
if (passphrase && strlen(passphrase) > 64)
{
// fail passphrase too long!
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase too long\n");
return false;
}
if (APlistExists(ssid, passphrase))
{
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s already exists\n", ssid);
return true;
}
newAP.ssid = strdup(ssid);
if (!newAP.ssid)
{
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n");
return false;
}
if (passphrase)
{
newAP.passphrase = strdup(passphrase);
}
else
{
newAP.passphrase = strdup("");
}
if (!newAP.passphrase)
{
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n");
free(newAP.ssid);
return false;
}
APlist.push_back(newAP);
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid);
return true;
}
bool ESP8266WiFiMulti::APlistExists(const char* ssid, const char *passphrase)
{
if (!ssid || *ssid == 0x00 || strlen(ssid) > 32)
{
// fail SSID too long or missing!
DEBUG_WIFI_MULTI("[WIFI][APlistExists] no ssid or ssid too long\n");
return false;
}
for (auto entry : APlist)
{
if (!strcmp(entry.ssid, ssid))
{
if (!passphrase)
{
if (!strcmp(entry.passphrase, ""))
{
return true;
}
}
else
{
if (!strcmp(entry.passphrase, passphrase))
{
return true;
}
}
}
}
return false;
}
void ESP8266WiFiMulti::APlistClean(void)
{
for (auto entry : APlist)
{
if (entry.ssid)
{
free(entry.ssid);
}
if (entry.passphrase)
{
free(entry.passphrase);
}
}
APlist.clear();
}
/**
*
* @file ESP8266WiFiMulti.cpp
* @date 16.05.2015
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. 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
* 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 "ESP8266WiFiMulti.h"
#include <limits.h>
#include <string.h>
ESP8266WiFiMulti::ESP8266WiFiMulti() {
}
ESP8266WiFiMulti::~ESP8266WiFiMulti() {
APlistClean();
}
bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) {
return APlistAdd(ssid, passphrase);
}
bool ESP8266WiFiMulti::existsAP(const char* ssid, const char *passphrase) {
return APlistExists(ssid, passphrase);
}
wl_status_t ESP8266WiFiMulti::run(void) {
wl_status_t status = WiFi.status();
if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) {
int8_t scanResult = WiFi.scanComplete();
if(scanResult == WIFI_SCAN_RUNNING) {
// scan is running, do nothing yet
status = WL_NO_SSID_AVAIL;
return status;
}
if(scanResult == 0) {
// scan done, no ssids found. Start another scan.
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
WiFi.scanDelete();
DEBUG_WIFI_MULTI("\n\n");
delay(0);
WiFi.disconnect();
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
// scan wifi async mode
WiFi.scanNetworks(true);
return status;
}
if(scanResult > 0) {
// scan done, analyze
WifiAPEntry bestNetwork { NULL, NULL };
int bestNetworkDb = INT_MIN;
uint8 bestBSSID[6];
int32_t bestChannel;
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
delay(0);
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
for(int8_t i = 0; i < scanResult; ++i) {
String ssid_scan;
int32_t rssi_scan;
uint8_t sec_scan;
uint8_t* BSSID_scan;
int32_t chan_scan;
bool hidden_scan;
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
bool known = false;
for(auto entry : APlist) {
if(ssid_scan == entry.ssid) { // SSID match
known = true;
if(rssi_scan > bestNetworkDb) { // best network
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
bestNetworkDb = rssi_scan;
bestChannel = chan_scan;
bestNetwork = entry;
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
}
}
break;
}
}
if(known) {
DEBUG_WIFI_MULTI(" ---> ");
} else {
DEBUG_WIFI_MULTI(" ");
}
DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*');
delay(0);
}
// clean up ram
WiFi.scanDelete();
DEBUG_WIFI_MULTI("\n\n");
delay(0);
if(bestNetwork.ssid) {
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
status = WiFi.status();
static const uint32_t connectTimeout = 5000; //5s timeout
auto startTime = millis();
// wait for connection, fail, or timeout
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) {
delay(10);
status = WiFi.status();
}
#ifdef DEBUG_ESP_WIFI
IPAddress ip;
uint8_t * mac;
switch(status) {
case WL_CONNECTED:
ip = WiFi.localIP();
mac = WiFi.BSSID();
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID().c_str());
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
break;
case WL_NO_SSID_AVAIL:
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n");
break;
case WL_CONNECT_FAILED:
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n");
break;
default:
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status);
break;
}
#endif
} else {
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
}
return status;
}
// scan failed, or some other condition not handled above. Start another scan.
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
WiFi.disconnect();
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
// scan wifi async mode
WiFi.scanNetworks(true);
}
return status;
}
// ##################################################################################
bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) {
WifiAPEntry newAP;
if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
// fail SSID too long or missing!
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid too long\n");
return false;
}
//for passphrase, max is 63 ascii + null. For psk, 64hex + null.
if(passphrase && strlen(passphrase) > 64) {
// fail passphrase too long!
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase too long\n");
return false;
}
if(APlistExists(ssid, passphrase)) {
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s already exists\n", ssid);
return true;
}
newAP.ssid = strdup(ssid);
if(!newAP.ssid) {
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n");
return false;
}
if(passphrase) {
newAP.passphrase = strdup(passphrase);
} else {
newAP.passphrase = strdup("");
}
if(!newAP.passphrase) {
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n");
free(newAP.ssid);
return false;
}
APlist.push_back(newAP);
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid);
return true;
}
bool ESP8266WiFiMulti::APlistExists(const char* ssid, const char *passphrase) {
if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
// fail SSID too long or missing!
DEBUG_WIFI_MULTI("[WIFI][APlistExists] no ssid or ssid too long\n");
return false;
}
for(auto entry : APlist) {
if(!strcmp(entry.ssid, ssid)) {
if(!passphrase) {
if(!strcmp(entry.passphrase, "")) {
return true;
}
} else {
if(!strcmp(entry.passphrase, passphrase)) {
return true;
}
}
}
}
return false;
}
void ESP8266WiFiMulti::APlistClean(void) {
for(auto entry : APlist) {
if(entry.ssid) {
free(entry.ssid);
}
if(entry.passphrase) {
free(entry.passphrase);
}
}
APlist.clear();
}

View File

@ -1,70 +1,68 @@
/**
@file ESP8266WiFiMulti.h
@date 16.05.2015
@author Markus Sattler
Copyright (c) 2015 Markus Sattler. 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
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 WIFICLIENTMULTI_H_
#define WIFICLIENTMULTI_H_
#include "ESP8266WiFi.h"
#include <vector>
#ifdef DEBUG_ESP_WIFI
#ifdef DEBUG_ESP_PORT
#define DEBUG_WIFI_MULTI(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ )
#endif
#endif
#ifndef DEBUG_WIFI_MULTI
#define DEBUG_WIFI_MULTI(...) do { (void)0; } while (0)
#endif
struct WifiAPEntry
{
char * ssid;
char * passphrase;
};
typedef std::vector<WifiAPEntry> WifiAPlist;
class ESP8266WiFiMulti
{
public:
ESP8266WiFiMulti();
~ESP8266WiFiMulti();
bool addAP(const char* ssid, const char *passphrase = NULL);
bool existsAP(const char* ssid, const char *passphrase = NULL);
wl_status_t run(void);
private:
WifiAPlist APlist;
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
bool APlistExists(const char* ssid, const char *passphrase = NULL);
void APlistClean(void);
};
#endif /* WIFICLIENTMULTI_H_ */
/**
*
* @file ESP8266WiFiMulti.h
* @date 16.05.2015
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. 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
* 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 WIFICLIENTMULTI_H_
#define WIFICLIENTMULTI_H_
#include "ESP8266WiFi.h"
#include <vector>
#ifdef DEBUG_ESP_WIFI
#ifdef DEBUG_ESP_PORT
#define DEBUG_WIFI_MULTI(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ )
#endif
#endif
#ifndef DEBUG_WIFI_MULTI
#define DEBUG_WIFI_MULTI(...) do { (void)0; } while (0)
#endif
struct WifiAPEntry {
char * ssid;
char * passphrase;
};
typedef std::vector<WifiAPEntry> WifiAPlist;
class ESP8266WiFiMulti {
public:
ESP8266WiFiMulti();
~ESP8266WiFiMulti();
bool addAP(const char* ssid, const char *passphrase = NULL);
bool existsAP(const char* ssid, const char *passphrase = NULL);
wl_status_t run(void);
private:
WifiAPlist APlist;
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
bool APlistExists(const char* ssid, const char *passphrase = NULL);
void APlistClean(void);
};
#endif /* WIFICLIENTMULTI_H_ */

View File

@ -1,121 +1,111 @@
/*
ESP8266WiFiSTA-WPS.cpp - WiFi library for esp8266
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
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
Reworked on 28 Dec 2015 by Markus Sattler
*/
#include "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiSTA.h"
#include "coredecls.h" // disable_extra4k_at_link_time()
static void wifi_wps_status_cb(wps_cb_status status);
/**
WPS config
so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
@return ok
*/
bool ESP8266WiFiSTAClass::beginWPSConfig(void)
{
// SYS ram is used by WPS, let's configure user stack inside user's HEAP
disable_extra4k_at_link_time();
if (!WiFi.enableSTA(true))
{
// enable STA failed
return false;
}
disconnect();
DEBUGV("wps begin\n");
if (!wifi_wps_disable())
{
DEBUGV("wps disable failed\n");
return false;
}
// so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
if (!wifi_wps_enable(WPS_TYPE_PBC))
{
DEBUGV("wps enable failed\n");
return false;
}
if (!wifi_set_wps_cb((wps_st_cb_t) &wifi_wps_status_cb))
{
DEBUGV("wps cb failed\n");
return false;
}
if (!wifi_wps_start())
{
DEBUGV("wps start failed\n");
return false;
}
esp_yield();
// will return here when wifi_wps_status_cb fires
return true;
}
/**
WPS callback
@param status wps_cb_status
*/
void wifi_wps_status_cb(wps_cb_status status)
{
DEBUGV("wps cb status: %d\r\n", status);
switch (status)
{
case WPS_CB_ST_SUCCESS:
if (!wifi_wps_disable())
{
DEBUGV("wps disable failed\n");
}
wifi_station_connect();
break;
case WPS_CB_ST_FAILED:
DEBUGV("wps FAILED\n");
break;
case WPS_CB_ST_TIMEOUT:
DEBUGV("wps TIMEOUT\n");
break;
case WPS_CB_ST_WEP:
DEBUGV("wps WEP\n");
break;
case WPS_CB_ST_UNK:
DEBUGV("wps UNKNOWN\n");
if (!wifi_wps_disable())
{
DEBUGV("wps disable failed\n");
}
break;
}
// TODO user function to get status
esp_schedule(); // resume the beginWPSConfig function
}
/*
ESP8266WiFiSTA-WPS.cpp - WiFi library for esp8266
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
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
Reworked on 28 Dec 2015 by Markus Sattler
*/
#include "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiSTA.h"
#include "coredecls.h" // disable_extra4k_at_link_time()
static void wifi_wps_status_cb(wps_cb_status status);
/**
* WPS config
* so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
* @return ok
*/
bool ESP8266WiFiSTAClass::beginWPSConfig(void) {
// SYS ram is used by WPS, let's configure user stack inside user's HEAP
disable_extra4k_at_link_time();
if(!WiFi.enableSTA(true)) {
// enable STA failed
return false;
}
disconnect();
DEBUGV("wps begin\n");
if(!wifi_wps_disable()) {
DEBUGV("wps disable failed\n");
return false;
}
// so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
if(!wifi_wps_enable(WPS_TYPE_PBC)) {
DEBUGV("wps enable failed\n");
return false;
}
if(!wifi_set_wps_cb((wps_st_cb_t) &wifi_wps_status_cb)) {
DEBUGV("wps cb failed\n");
return false;
}
if(!wifi_wps_start()) {
DEBUGV("wps start failed\n");
return false;
}
esp_yield();
// will return here when wifi_wps_status_cb fires
return true;
}
/**
* WPS callback
* @param status wps_cb_status
*/
void wifi_wps_status_cb(wps_cb_status status) {
DEBUGV("wps cb status: %d\r\n", status);
switch(status) {
case WPS_CB_ST_SUCCESS:
if(!wifi_wps_disable()) {
DEBUGV("wps disable failed\n");
}
wifi_station_connect();
break;
case WPS_CB_ST_FAILED:
DEBUGV("wps FAILED\n");
break;
case WPS_CB_ST_TIMEOUT:
DEBUGV("wps TIMEOUT\n");
break;
case WPS_CB_ST_WEP:
DEBUGV("wps WEP\n");
break;
case WPS_CB_ST_UNK:
DEBUGV("wps UNKNOWN\n");
if(!wifi_wps_disable()) {
DEBUGV("wps disable failed\n");
}
break;
}
// TODO user function to get status
esp_schedule(); // resume the beginWPSConfig function
}

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +1,114 @@
/*
ESP8266WiFiSTA.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFISTA_H_
#define ESP8266WIFISTA_H_
#include "ESP8266WiFiType.h"
#include "ESP8266WiFiGeneric.h"
#include "user_interface.h"
class ESP8266WiFiSTAClass
{
// ----------------------------------------------------------------------------------------------
// ---------------------------------------- STA function ----------------------------------------
// ----------------------------------------------------------------------------------------------
public:
wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
wl_status_t begin(const String& ssid, const String& passphrase = emptyString, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
wl_status_t begin();
//The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood
//to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't
//work here (see Arduino docs for gway/subnet defaults). In other words: at least 3 args must always be given.
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
bool reconnect();
bool disconnect(bool wifioff = false);
bool isConnected();
bool setAutoConnect(bool autoConnect);
bool getAutoConnect();
bool setAutoReconnect(bool autoReconnect);
bool getAutoReconnect();
uint8_t waitForConnectResult();
// STA network info
IPAddress localIP();
uint8_t * macAddress(uint8_t* mac);
String macAddress();
IPAddress subnetMask();
IPAddress gatewayIP();
IPAddress dnsIP(uint8_t dns_no = 0);
String hostname();
bool hostname(const String& aHostname)
{
return hostname(aHostname.c_str());
}
bool hostname(const char* aHostname);
// STA WiFi info
wl_status_t status();
String SSID() const;
String psk() const;
uint8_t * BSSID();
String BSSIDstr();
int32_t RSSI();
static void enableInsecureWEP(bool enable = true)
{
_useInsecureWEP = enable;
}
protected:
static bool _useStaticIp;
static bool _useInsecureWEP;
// ----------------------------------------------------------------------------------------------
// ------------------------------------ STA remote configure -----------------------------------
// ----------------------------------------------------------------------------------------------
public:
bool beginWPSConfig(void);
bool beginSmartConfig();
bool stopSmartConfig();
bool smartConfigDone();
protected:
static bool _smartConfigStarted;
static bool _smartConfigDone;
static void _smartConfigCallback(uint32_t status, void* result);
};
#endif /* ESP8266WIFISTA_H_ */
/*
ESP8266WiFiSTA.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFISTA_H_
#define ESP8266WIFISTA_H_
#include "ESP8266WiFiType.h"
#include "ESP8266WiFiGeneric.h"
#include "user_interface.h"
class ESP8266WiFiSTAClass {
// ----------------------------------------------------------------------------------------------
// ---------------------------------------- STA function ----------------------------------------
// ----------------------------------------------------------------------------------------------
public:
wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
wl_status_t begin(const String& ssid, const String& passphrase = emptyString, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
wl_status_t begin();
//The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood
//to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't
//work here (see Arduino docs for gway/subnet defaults). In other words: at least 3 args must always be given.
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
bool reconnect();
bool disconnect(bool wifioff = false);
bool isConnected();
bool setAutoConnect(bool autoConnect);
bool getAutoConnect();
bool setAutoReconnect(bool autoReconnect);
bool getAutoReconnect();
uint8_t waitForConnectResult();
// STA network info
IPAddress localIP();
uint8_t * macAddress(uint8_t* mac);
String macAddress();
IPAddress subnetMask();
IPAddress gatewayIP();
IPAddress dnsIP(uint8_t dns_no = 0);
String hostname();
bool hostname(const String& aHostname) { return hostname(aHostname.c_str()); }
bool hostname(const char* aHostname);
// STA WiFi info
wl_status_t status();
String SSID() const;
String psk() const;
uint8_t * BSSID();
String BSSIDstr();
int32_t RSSI();
static void enableInsecureWEP (bool enable = true) { _useInsecureWEP = enable; }
protected:
static bool _useStaticIp;
static bool _useInsecureWEP;
// ----------------------------------------------------------------------------------------------
// ------------------------------------ STA remote configure -----------------------------------
// ----------------------------------------------------------------------------------------------
public:
bool beginWPSConfig(void);
bool beginSmartConfig();
bool stopSmartConfig();
bool smartConfigDone();
protected:
static bool _smartConfigStarted;
static bool _smartConfigDone;
static void _smartConfigCallback(uint32_t status, void* result);
};
#endif /* ESP8266WIFISTA_H_ */

View File

@ -1,386 +1,343 @@
/*
ESP8266WiFiScan.cpp - WiFi library for esp8266
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
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
Reworked on 28 Dec 2015 by Markus Sattler
*/
#include "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiScan.h"
extern "C" {
#include "c_types.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
}
#include "debug.h"
extern "C" void esp_schedule();
extern "C" void esp_yield();
// -----------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------- Private functions ------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- scan function ---------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
bool ESP8266WiFiScanClass::_scanAsync = false;
bool ESP8266WiFiScanClass::_scanStarted = false;
bool ESP8266WiFiScanClass::_scanComplete = false;
size_t ESP8266WiFiScanClass::_scanCount = 0;
void* ESP8266WiFiScanClass::_scanResult = 0;
std::function<void(int)> ESP8266WiFiScanClass::_onComplete;
/**
Start scan WiFi networks available
@param async run in async mode
@param show_hidden show hidden networks
@param channel scan only this channel (0 for all channels)
@param ssid* scan for only this ssid (NULL for all ssid's)
@return Number of discovered networks
*/
int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 channel, uint8* ssid)
{
if (ESP8266WiFiScanClass::_scanStarted)
{
return WIFI_SCAN_RUNNING;
}
ESP8266WiFiScanClass::_scanAsync = async;
WiFi.enableSTA(true);
int status = wifi_station_get_connect_status();
if (status != STATION_GOT_IP && status != STATION_IDLE)
{
wifi_station_disconnect();
}
scanDelete();
struct scan_config config;
memset(&config, 0, sizeof(config));
config.ssid = ssid;
config.channel = channel;
config.show_hidden = show_hidden;
if (wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiScanClass::_scanDone)))
{
ESP8266WiFiScanClass::_scanComplete = false;
ESP8266WiFiScanClass::_scanStarted = true;
if (ESP8266WiFiScanClass::_scanAsync)
{
delay(0); // time for the OS to trigger the scan
return WIFI_SCAN_RUNNING;
}
esp_yield();
return ESP8266WiFiScanClass::_scanCount;
}
else
{
return WIFI_SCAN_FAILED;
}
}
/**
Starts scanning WiFi networks available in async mode
@param onComplete the event handler executed when the scan is done
@param show_hidden show hidden networks
*/
void ESP8266WiFiScanClass::scanNetworksAsync(std::function<void(int)> onComplete, bool show_hidden)
{
_onComplete = onComplete;
scanNetworks(true, show_hidden);
}
/**
called to get the scan state in Async mode
@return scan result or status
-1 if scan not fin
-2 if scan not triggered
*/
int8_t ESP8266WiFiScanClass::scanComplete()
{
if (_scanStarted)
{
return WIFI_SCAN_RUNNING;
}
if (_scanComplete)
{
return ESP8266WiFiScanClass::_scanCount;
}
return WIFI_SCAN_FAILED;
}
/**
delete last scan result from RAM
*/
void ESP8266WiFiScanClass::scanDelete()
{
if (ESP8266WiFiScanClass::_scanResult)
{
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiScanClass::_scanResult);
ESP8266WiFiScanClass::_scanResult = 0;
ESP8266WiFiScanClass::_scanCount = 0;
}
_scanComplete = false;
}
/**
loads all infos from a scanned wifi in to the ptr parameters
@param networkItem uint8_t
@param ssid const char*
@param encryptionType uint8_t
@param RSSI int32_t
@param BSSID uint8_t *
@param channel int32_t
@param isHidden bool
@return (true if ok)
*/
bool ESP8266WiFiScanClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &isHidden)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return false;
}
char ssid_copy[33]; // Ensure space for maximum len SSID (32) plus trailing 0
memcpy(ssid_copy, it->ssid, sizeof(it->ssid));
ssid_copy[32] = 0; // Potentially add 0-termination if none present earlier
ssid = (const char*) ssid_copy;
encType = encryptionType(i);
rssi = it->rssi;
bssid = it->bssid; // move ptr
channel = it->channel;
isHidden = (it->is_hidden != 0);
return true;
}
/**
Return the SSID discovered during the network scan.
@param i specify from which network item want to get the information
@return ssid string of the specified item on the networks scanned list
*/
String ESP8266WiFiScanClass::SSID(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return "";
}
char tmp[33]; //ssid can be up to 32chars, => plus null term
memcpy(tmp, it->ssid, sizeof(it->ssid));
tmp[32] = 0; //nullterm in case of 32 char ssid
return String(reinterpret_cast<const char*>(tmp));
}
/**
Return the encryption type of the networks discovered during the scanNetworks
@param i specify from which network item want to get the information
@return encryption type (enum wl_enc_type) of the specified item on the networks scanned list
*/
uint8_t ESP8266WiFiScanClass::encryptionType(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return -1;
}
switch (it->authmode)
{
case AUTH_OPEN:
return ENC_TYPE_NONE;
case AUTH_WEP:
return ENC_TYPE_WEP;
case AUTH_WPA_PSK:
return ENC_TYPE_TKIP;
case AUTH_WPA2_PSK:
return ENC_TYPE_CCMP;
case AUTH_WPA_WPA2_PSK:
return ENC_TYPE_AUTO;
default:
return -1;
}
}
/**
Return the RSSI of the networks discovered during the scanNetworks
@param i specify from which network item want to get the information
@return signed value of RSSI of the specified item on the networks scanned list
*/
int32_t ESP8266WiFiScanClass::RSSI(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return 0;
}
return it->rssi;
}
/**
return MAC / BSSID of scanned wifi
@param i specify from which network item want to get the information
@return uint8_t * MAC / BSSID of scanned wifi
*/
uint8_t * ESP8266WiFiScanClass::BSSID(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return 0;
}
return it->bssid;
}
/**
return MAC / BSSID of scanned wifi
@param i specify from which network item want to get the information
@return String MAC / BSSID of scanned wifi
*/
String ESP8266WiFiScanClass::BSSIDstr(uint8_t i)
{
char mac[18] = { 0 };
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return String("");
}
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]);
return String(mac);
}
int32_t ESP8266WiFiScanClass::channel(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return 0;
}
return it->channel;
}
/**
return if the scanned wifi is Hidden (no SSID)
@param networkItem specify from which network item want to get the information
@return bool (true == hidden)
*/
bool ESP8266WiFiScanClass::isHidden(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
{
return false;
}
return (it->is_hidden != 0);
}
/**
private
scan callback
@param result void *arg
@param status STATUS
*/
void ESP8266WiFiScanClass::_scanDone(void* result, int status)
{
if (status != OK)
{
ESP8266WiFiScanClass::_scanCount = 0;
ESP8266WiFiScanClass::_scanResult = 0;
}
else
{
int i = 0;
bss_info* head = reinterpret_cast<bss_info*>(result);
for (bss_info* it = head; it; it = STAILQ_NEXT(it, next), ++i)
;
ESP8266WiFiScanClass::_scanCount = i;
if (i == 0)
{
ESP8266WiFiScanClass::_scanResult = 0;
}
else
{
bss_info* copied_info = new bss_info[i];
i = 0;
for (bss_info* it = head; it; it = STAILQ_NEXT(it, next), ++i)
{
memcpy(copied_info + i, it, sizeof(bss_info));
}
ESP8266WiFiScanClass::_scanResult = copied_info;
}
}
ESP8266WiFiScanClass::_scanStarted = false;
ESP8266WiFiScanClass::_scanComplete = true;
if (!ESP8266WiFiScanClass::_scanAsync)
{
esp_schedule();
}
else if (ESP8266WiFiScanClass::_onComplete)
{
ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount);
ESP8266WiFiScanClass::_onComplete = nullptr;
}
}
/**
@param i specify from which network item want to get the information
@return bss_info
*/
void * ESP8266WiFiScanClass::_getScanInfoByIndex(int i)
{
if (!ESP8266WiFiScanClass::_scanResult || (size_t) i > ESP8266WiFiScanClass::_scanCount)
{
return 0;
}
return reinterpret_cast<bss_info*>(ESP8266WiFiScanClass::_scanResult) + i;
}
/*
ESP8266WiFiScan.cpp - WiFi library for esp8266
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
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
Reworked on 28 Dec 2015 by Markus Sattler
*/
#include "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiScan.h"
extern "C" {
#include "c_types.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
}
#include "debug.h"
extern "C" void esp_schedule();
extern "C" void esp_yield();
// -----------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------- Private functions ------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- scan function ---------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------
bool ESP8266WiFiScanClass::_scanAsync = false;
bool ESP8266WiFiScanClass::_scanStarted = false;
bool ESP8266WiFiScanClass::_scanComplete = false;
size_t ESP8266WiFiScanClass::_scanCount = 0;
void* ESP8266WiFiScanClass::_scanResult = 0;
std::function<void(int)> ESP8266WiFiScanClass::_onComplete;
/**
* Start scan WiFi networks available
* @param async run in async mode
* @param show_hidden show hidden networks
* @param channel scan only this channel (0 for all channels)
* @param ssid* scan for only this ssid (NULL for all ssid's)
* @return Number of discovered networks
*/
int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 channel, uint8* ssid) {
if(ESP8266WiFiScanClass::_scanStarted) {
return WIFI_SCAN_RUNNING;
}
ESP8266WiFiScanClass::_scanAsync = async;
WiFi.enableSTA(true);
int status = wifi_station_get_connect_status();
if(status != STATION_GOT_IP && status != STATION_IDLE) {
wifi_station_disconnect();
}
scanDelete();
struct scan_config config;
memset(&config, 0, sizeof(config));
config.ssid = ssid;
config.channel = channel;
config.show_hidden = show_hidden;
if(wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiScanClass::_scanDone))) {
ESP8266WiFiScanClass::_scanComplete = false;
ESP8266WiFiScanClass::_scanStarted = true;
if(ESP8266WiFiScanClass::_scanAsync) {
delay(0); // time for the OS to trigger the scan
return WIFI_SCAN_RUNNING;
}
esp_yield();
return ESP8266WiFiScanClass::_scanCount;
} else {
return WIFI_SCAN_FAILED;
}
}
/**
* Starts scanning WiFi networks available in async mode
* @param onComplete the event handler executed when the scan is done
* @param show_hidden show hidden networks
*/
void ESP8266WiFiScanClass::scanNetworksAsync(std::function<void(int)> onComplete, bool show_hidden) {
_onComplete = onComplete;
scanNetworks(true, show_hidden);
}
/**
* called to get the scan state in Async mode
* @return scan result or status
* -1 if scan not fin
* -2 if scan not triggered
*/
int8_t ESP8266WiFiScanClass::scanComplete() {
if(_scanStarted) {
return WIFI_SCAN_RUNNING;
}
if(_scanComplete) {
return ESP8266WiFiScanClass::_scanCount;
}
return WIFI_SCAN_FAILED;
}
/**
* delete last scan result from RAM
*/
void ESP8266WiFiScanClass::scanDelete() {
if(ESP8266WiFiScanClass::_scanResult) {
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiScanClass::_scanResult);
ESP8266WiFiScanClass::_scanResult = 0;
ESP8266WiFiScanClass::_scanCount = 0;
}
_scanComplete = false;
}
/**
* loads all infos from a scanned wifi in to the ptr parameters
* @param networkItem uint8_t
* @param ssid const char**
* @param encryptionType uint8_t *
* @param RSSI int32_t *
* @param BSSID uint8_t **
* @param channel int32_t *
* @param isHidden bool *
* @return (true if ok)
*/
bool ESP8266WiFiScanClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &isHidden) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return false;
}
char ssid_copy[33]; // Ensure space for maximum len SSID (32) plus trailing 0
memcpy(ssid_copy, it->ssid, sizeof(it->ssid));
ssid_copy[32] = 0; // Potentially add 0-termination if none present earlier
ssid = (const char*) ssid_copy;
encType = encryptionType(i);
rssi = it->rssi;
bssid = it->bssid; // move ptr
channel = it->channel;
isHidden = (it->is_hidden != 0);
return true;
}
/**
* Return the SSID discovered during the network scan.
* @param i specify from which network item want to get the information
* @return ssid string of the specified item on the networks scanned list
*/
String ESP8266WiFiScanClass::SSID(uint8_t i) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return "";
}
char tmp[33]; //ssid can be up to 32chars, => plus null term
memcpy(tmp, it->ssid, sizeof(it->ssid));
tmp[32] = 0; //nullterm in case of 32 char ssid
return String(reinterpret_cast<const char*>(tmp));
}
/**
* Return the encryption type of the networks discovered during the scanNetworks
* @param i specify from which network item want to get the information
* @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list
*/
uint8_t ESP8266WiFiScanClass::encryptionType(uint8_t i) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return -1;
}
switch(it->authmode) {
case AUTH_OPEN:
return ENC_TYPE_NONE;
case AUTH_WEP:
return ENC_TYPE_WEP;
case AUTH_WPA_PSK:
return ENC_TYPE_TKIP;
case AUTH_WPA2_PSK:
return ENC_TYPE_CCMP;
case AUTH_WPA_WPA2_PSK:
return ENC_TYPE_AUTO;
default:
return -1;
}
}
/**
* Return the RSSI of the networks discovered during the scanNetworks
* @param i specify from which network item want to get the information
* @return signed value of RSSI of the specified item on the networks scanned list
*/
int32_t ESP8266WiFiScanClass::RSSI(uint8_t i) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return 0;
}
return it->rssi;
}
/**
* return MAC / BSSID of scanned wifi
* @param i specify from which network item want to get the information
* @return uint8_t * MAC / BSSID of scanned wifi
*/
uint8_t * ESP8266WiFiScanClass::BSSID(uint8_t i) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return 0;
}
return it->bssid;
}
/**
* return MAC / BSSID of scanned wifi
* @param i specify from which network item want to get the information
* @return String MAC / BSSID of scanned wifi
*/
String ESP8266WiFiScanClass::BSSIDstr(uint8_t i) {
char mac[18] = { 0 };
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return String("");
}
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]);
return String(mac);
}
int32_t ESP8266WiFiScanClass::channel(uint8_t i) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return 0;
}
return it->channel;
}
/**
* return if the scanned wifi is Hidden (no SSID)
* @param networkItem specify from which network item want to get the information
* @return bool (true == hidden)
*/
bool ESP8266WiFiScanClass::isHidden(uint8_t i) {
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if(!it) {
return false;
}
return (it->is_hidden != 0);
}
/**
* private
* scan callback
* @param result void *arg
* @param status STATUS
*/
void ESP8266WiFiScanClass::_scanDone(void* result, int status) {
if(status != OK) {
ESP8266WiFiScanClass::_scanCount = 0;
ESP8266WiFiScanClass::_scanResult = 0;
} else {
int i = 0;
bss_info* head = reinterpret_cast<bss_info*>(result);
for(bss_info* it = head; it; it = STAILQ_NEXT(it, next), ++i)
;
ESP8266WiFiScanClass::_scanCount = i;
if(i == 0) {
ESP8266WiFiScanClass::_scanResult = 0;
} else {
bss_info* copied_info = new bss_info[i];
i = 0;
for(bss_info* it = head; it; it = STAILQ_NEXT(it, next), ++i) {
memcpy(copied_info + i, it, sizeof(bss_info));
}
ESP8266WiFiScanClass::_scanResult = copied_info;
}
}
ESP8266WiFiScanClass::_scanStarted = false;
ESP8266WiFiScanClass::_scanComplete = true;
if(!ESP8266WiFiScanClass::_scanAsync) {
esp_schedule();
} else if (ESP8266WiFiScanClass::_onComplete) {
ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount);
ESP8266WiFiScanClass::_onComplete = nullptr;
}
}
/**
*
* @param i specify from which network item want to get the information
* @return bss_info *
*/
void * ESP8266WiFiScanClass::_getScanInfoByIndex(int i) {
if(!ESP8266WiFiScanClass::_scanResult || (size_t) i > ESP8266WiFiScanClass::_scanCount) {
return 0;
}
return reinterpret_cast<bss_info*>(ESP8266WiFiScanClass::_scanResult) + i;
}

View File

@ -1,72 +1,71 @@
/*
ESP8266WiFiScan.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFISCAN_H_
#define ESP8266WIFISCAN_H_
#include "ESP8266WiFiType.h"
#include "ESP8266WiFiGeneric.h"
class ESP8266WiFiScanClass
{
// ----------------------------------------------------------------------------------------------
// ----------------------------------------- scan function --------------------------------------
// ----------------------------------------------------------------------------------------------
public:
int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL);
void scanNetworksAsync(std::function<void(int)> onComplete, bool show_hidden = false);
int8_t scanComplete();
void scanDelete();
// scan result
bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden);
String SSID(uint8_t networkItem);
uint8_t encryptionType(uint8_t networkItem);
int32_t RSSI(uint8_t networkItem);
uint8_t * BSSID(uint8_t networkItem);
String BSSIDstr(uint8_t networkItem);
int32_t channel(uint8_t networkItem);
bool isHidden(uint8_t networkItem);
protected:
static bool _scanAsync;
static bool _scanStarted;
static bool _scanComplete;
static size_t _scanCount;
static void* _scanResult;
static std::function<void(int)> _onComplete;
static void _scanDone(void* result, int status);
static void * _getScanInfoByIndex(int i);
};
#endif /* ESP8266WIFISCAN_H_ */
/*
ESP8266WiFiScan.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFISCAN_H_
#define ESP8266WIFISCAN_H_
#include "ESP8266WiFiType.h"
#include "ESP8266WiFiGeneric.h"
class ESP8266WiFiScanClass {
// ----------------------------------------------------------------------------------------------
// ----------------------------------------- scan function --------------------------------------
// ----------------------------------------------------------------------------------------------
public:
int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL);
void scanNetworksAsync(std::function<void(int)> onComplete, bool show_hidden = false);
int8_t scanComplete();
void scanDelete();
// scan result
bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden);
String SSID(uint8_t networkItem);
uint8_t encryptionType(uint8_t networkItem);
int32_t RSSI(uint8_t networkItem);
uint8_t * BSSID(uint8_t networkItem);
String BSSIDstr(uint8_t networkItem);
int32_t channel(uint8_t networkItem);
bool isHidden(uint8_t networkItem);
protected:
static bool _scanAsync;
static bool _scanStarted;
static bool _scanComplete;
static size_t _scanCount;
static void* _scanResult;
static std::function<void(int)> _onComplete;
static void _scanDone(void* result, int status);
static void * _getScanInfoByIndex(int i);
};
#endif /* ESP8266WIFISCAN_H_ */

View File

@ -1,151 +1,151 @@
/*
ESP8266WiFiType.h - esp8266 Wifi support.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFITYPE_H_
#define ESP8266WIFITYPE_H_
#include <queue.h>
#define WIFI_SCAN_RUNNING (-1)
#define WIFI_SCAN_FAILED (-2)
// Note: these enums need to be in sync with the SDK!
// TODO: replace/deprecate/remove enum typedefs ending with _t below
typedef enum WiFiMode
{
WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3
} WiFiMode_t;
typedef enum WiFiPhyMode
{
WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3
} WiFiPhyMode_t;
typedef enum WiFiSleepType
{
WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 1, WIFI_MODEM_SLEEP = 2
} WiFiSleepType_t;
typedef enum WiFiEvent
{
WIFI_EVENT_STAMODE_CONNECTED = 0,
WIFI_EVENT_STAMODE_DISCONNECTED,
WIFI_EVENT_STAMODE_AUTHMODE_CHANGE,
WIFI_EVENT_STAMODE_GOT_IP,
WIFI_EVENT_STAMODE_DHCP_TIMEOUT,
WIFI_EVENT_SOFTAPMODE_STACONNECTED,
WIFI_EVENT_SOFTAPMODE_STADISCONNECTED,
WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED,
WIFI_EVENT_MAX,
WIFI_EVENT_ANY = WIFI_EVENT_MAX,
WIFI_EVENT_MODE_CHANGE
} WiFiEvent_t;
enum WiFiDisconnectReason
{
WIFI_DISCONNECT_REASON_UNSPECIFIED = 1,
WIFI_DISCONNECT_REASON_AUTH_EXPIRE = 2,
WIFI_DISCONNECT_REASON_AUTH_LEAVE = 3,
WIFI_DISCONNECT_REASON_ASSOC_EXPIRE = 4,
WIFI_DISCONNECT_REASON_ASSOC_TOOMANY = 5,
WIFI_DISCONNECT_REASON_NOT_AUTHED = 6,
WIFI_DISCONNECT_REASON_NOT_ASSOCED = 7,
WIFI_DISCONNECT_REASON_ASSOC_LEAVE = 8,
WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED = 9,
WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD = 10, /* 11h */
WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD = 11, /* 11h */
WIFI_DISCONNECT_REASON_IE_INVALID = 13, /* 11i */
WIFI_DISCONNECT_REASON_MIC_FAILURE = 14, /* 11i */
WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, /* 11i */
WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS = 17, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID = 18, /* 11i */
WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID = 19, /* 11i */
WIFI_DISCONNECT_REASON_AKMP_INVALID = 20, /* 11i */
WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION = 21, /* 11i */
WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP = 22, /* 11i */
WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED = 23, /* 11i */
WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED = 24, /* 11i */
WIFI_DISCONNECT_REASON_BEACON_TIMEOUT = 200,
WIFI_DISCONNECT_REASON_NO_AP_FOUND = 201,
WIFI_DISCONNECT_REASON_AUTH_FAIL = 202,
WIFI_DISCONNECT_REASON_ASSOC_FAIL = 203,
WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT = 204,
};
struct WiFiEventModeChange
{
WiFiMode oldMode;
WiFiMode newMode;
};
struct WiFiEventStationModeConnected
{
String ssid;
uint8 bssid[6];
uint8 channel;
};
struct WiFiEventStationModeDisconnected
{
String ssid;
uint8 bssid[6];
WiFiDisconnectReason reason;
};
struct WiFiEventStationModeAuthModeChanged
{
uint8 oldMode;
uint8 newMode;
};
struct WiFiEventStationModeGotIP
{
IPAddress ip;
IPAddress mask;
IPAddress gw;
};
struct WiFiEventSoftAPModeStationConnected
{
uint8 mac[6];
uint8 aid;
};
struct WiFiEventSoftAPModeStationDisconnected
{
uint8 mac[6];
uint8 aid;
};
struct WiFiEventSoftAPModeProbeRequestReceived
{
int rssi;
uint8 mac[6];
};
#endif /* ESP8266WIFITYPE_H_ */
/*
ESP8266WiFiType.h - esp8266 Wifi support.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
Reworked by Markus Sattler, December 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266WIFITYPE_H_
#define ESP8266WIFITYPE_H_
#include <queue.h>
#define WIFI_SCAN_RUNNING (-1)
#define WIFI_SCAN_FAILED (-2)
// Note: these enums need to be in sync with the SDK!
// TODO: replace/deprecate/remove enum typedefs ending with _t below
typedef enum WiFiMode
{
WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3
} WiFiMode_t;
typedef enum WiFiPhyMode
{
WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3
} WiFiPhyMode_t;
typedef enum WiFiSleepType
{
WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 1, WIFI_MODEM_SLEEP = 2
} WiFiSleepType_t;
typedef enum WiFiEvent
{
WIFI_EVENT_STAMODE_CONNECTED = 0,
WIFI_EVENT_STAMODE_DISCONNECTED,
WIFI_EVENT_STAMODE_AUTHMODE_CHANGE,
WIFI_EVENT_STAMODE_GOT_IP,
WIFI_EVENT_STAMODE_DHCP_TIMEOUT,
WIFI_EVENT_SOFTAPMODE_STACONNECTED,
WIFI_EVENT_SOFTAPMODE_STADISCONNECTED,
WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED,
WIFI_EVENT_MAX,
WIFI_EVENT_ANY = WIFI_EVENT_MAX,
WIFI_EVENT_MODE_CHANGE
} WiFiEvent_t;
enum WiFiDisconnectReason
{
WIFI_DISCONNECT_REASON_UNSPECIFIED = 1,
WIFI_DISCONNECT_REASON_AUTH_EXPIRE = 2,
WIFI_DISCONNECT_REASON_AUTH_LEAVE = 3,
WIFI_DISCONNECT_REASON_ASSOC_EXPIRE = 4,
WIFI_DISCONNECT_REASON_ASSOC_TOOMANY = 5,
WIFI_DISCONNECT_REASON_NOT_AUTHED = 6,
WIFI_DISCONNECT_REASON_NOT_ASSOCED = 7,
WIFI_DISCONNECT_REASON_ASSOC_LEAVE = 8,
WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED = 9,
WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD = 10, /* 11h */
WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD = 11, /* 11h */
WIFI_DISCONNECT_REASON_IE_INVALID = 13, /* 11i */
WIFI_DISCONNECT_REASON_MIC_FAILURE = 14, /* 11i */
WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, /* 11i */
WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS = 17, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID = 18, /* 11i */
WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID = 19, /* 11i */
WIFI_DISCONNECT_REASON_AKMP_INVALID = 20, /* 11i */
WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION = 21, /* 11i */
WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP = 22, /* 11i */
WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED = 23, /* 11i */
WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED = 24, /* 11i */
WIFI_DISCONNECT_REASON_BEACON_TIMEOUT = 200,
WIFI_DISCONNECT_REASON_NO_AP_FOUND = 201,
WIFI_DISCONNECT_REASON_AUTH_FAIL = 202,
WIFI_DISCONNECT_REASON_ASSOC_FAIL = 203,
WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT = 204,
};
struct WiFiEventModeChange
{
WiFiMode oldMode;
WiFiMode newMode;
};
struct WiFiEventStationModeConnected
{
String ssid;
uint8 bssid[6];
uint8 channel;
};
struct WiFiEventStationModeDisconnected
{
String ssid;
uint8 bssid[6];
WiFiDisconnectReason reason;
};
struct WiFiEventStationModeAuthModeChanged
{
uint8 oldMode;
uint8 newMode;
};
struct WiFiEventStationModeGotIP
{
IPAddress ip;
IPAddress mask;
IPAddress gw;
};
struct WiFiEventSoftAPModeStationConnected
{
uint8 mac[6];
uint8 aid;
};
struct WiFiEventSoftAPModeStationDisconnected
{
uint8 mac[6];
uint8 aid;
};
struct WiFiEventSoftAPModeProbeRequestReceived
{
int rssi;
uint8 mac[6];
};
#endif /* ESP8266WIFITYPE_H_ */

View File

@ -1,32 +1,32 @@
/*
WiFiClient.cpp - TCP/IP client for esp8266, mostly compatible
WiFiClient.cpp - TCP/IP client for esp8266, mostly compatible
with Arduino WiFi shield library
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
#define LWIP_INTERNAL
extern "C"
{
#include "include/wl_definitions.h"
#include "osapi.h"
#include "ets_sys.h"
#include "include/wl_definitions.h"
#include "osapi.h"
#include "ets_sys.h"
}
#include "debug.h"
@ -46,27 +46,27 @@ uint16_t WiFiClient::_localPort = 0;
static bool defaultNoDelay = false; // false == Nagle enabled by default
static bool defaultSync = false;
bool getDefaultPrivateGlobalSyncValue()
bool getDefaultPrivateGlobalSyncValue ()
{
return defaultSync;
}
void WiFiClient::setDefaultNoDelay(bool noDelay)
void WiFiClient::setDefaultNoDelay (bool noDelay)
{
defaultNoDelay = noDelay;
}
void WiFiClient::setDefaultSync(bool sync)
void WiFiClient::setDefaultSync (bool sync)
{
defaultSync = sync;
}
bool WiFiClient::getDefaultNoDelay()
bool WiFiClient::getDefaultNoDelay ()
{
return defaultNoDelay;
}
bool WiFiClient::getDefaultSync()
bool WiFiClient::getDefaultSync ()
{
return defaultSync;
}
@ -76,14 +76,14 @@ WiFiClient* SList<WiFiClient>::_s_first = 0;
WiFiClient::WiFiClient()
: _client(0)
: _client(0)
{
_timeout = 5000;
WiFiClient::_add(this);
}
WiFiClient::WiFiClient(ClientContext* client)
: _client(client)
: _client(client)
{
_timeout = 5000;
_client->ref();
@ -97,9 +97,7 @@ WiFiClient::~WiFiClient()
{
WiFiClient::_remove(this);
if (_client)
{
_client->unref();
}
}
WiFiClient::WiFiClient(const WiFiClient& other)
@ -108,25 +106,19 @@ WiFiClient::WiFiClient(const WiFiClient& other)
_timeout = other._timeout;
_localPort = other._localPort;
if (_client)
{
_client->ref();
}
WiFiClient::_add(this);
}
WiFiClient& WiFiClient::operator=(const WiFiClient& other)
{
if (_client)
{
if (_client)
_client->unref();
}
_client = other._client;
_timeout = other._timeout;
_localPort = other._localPort;
if (_client)
{
_client->ref();
}
return *this;
}
@ -147,8 +139,7 @@ int WiFiClient::connect(const String& host, uint16_t port)
int WiFiClient::connect(IPAddress ip, uint16_t port)
{
if (_client)
{
if (_client) {
stop();
_client->unref();
_client = nullptr;
@ -159,8 +150,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
// ever calling tcp_err
// http://lists.gnu.org/archive/html/lwip-devel/2010-05/msg00001.html
netif* interface = ip_route(ip);
if (!interface)
{
if (!interface) {
DEBUGV("no route to host\r\n");
return 0;
}
@ -168,12 +158,9 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
tcp_pcb* pcb = tcp_new();
if (!pcb)
{
return 0;
}
if (_localPort > 0)
{
if (_localPort > 0) {
pcb->local_port = _localPort++;
}
@ -181,8 +168,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
_client->ref();
_client->setTimeout(_timeout);
int res = _client->connect(ip, port);
if (res == 0)
{
if (res == 0) {
_client->unref();
_client = nullptr;
return 0;
@ -194,45 +180,35 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
return 1;
}
void WiFiClient::setNoDelay(bool nodelay)
{
void WiFiClient::setNoDelay(bool nodelay) {
if (!_client)
{
return;
}
_client->setNoDelay(nodelay);
}
bool WiFiClient::getNoDelay() const
{
bool WiFiClient::getNoDelay() const {
if (!_client)
{
return false;
}
return _client->getNoDelay();
}
void WiFiClient::setSync(bool sync)
{
if (!_client)
{
return;
}
_client->setSync(sync);
}
bool WiFiClient::getSync() const
{
if (!_client)
{
return false;
}
return _client->getSync();
}
size_t WiFiClient::availableForWrite()
size_t WiFiClient::availableForWrite ()
{
return _client ? _client->availableForWrite() : 0;
return _client? _client->availableForWrite(): 0;
}
size_t WiFiClient::write(uint8_t b)
@ -279,14 +255,11 @@ size_t WiFiClient::write_P(PGM_P buf, size_t size)
int WiFiClient::available()
{
if (!_client)
{
return false;
}
int result = _client->getSize();
if (!result)
{
if (!result) {
optimistic_yield(100);
}
return result;
@ -295,9 +268,7 @@ int WiFiClient::available()
int WiFiClient::read()
{
if (!available())
{
return -1;
}
return _client->read();
}
@ -311,34 +282,26 @@ int WiFiClient::read(uint8_t* buf, size_t size)
int WiFiClient::peek()
{
if (!available())
{
return -1;
}
return _client->peek();
}
size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length)
{
size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) {
size_t count = 0;
if (!_client)
{
if(!_client) {
return 0;
}
_startMillis = millis();
while ((available() < (int) length) && ((millis() - _startMillis) < _timeout))
{
while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) {
yield();
}
if (available() < (int) length)
{
if(available() < (int) length) {
count = available();
}
else
{
} else {
count = length;
}
@ -348,38 +311,28 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length)
bool WiFiClient::flush(unsigned int maxWaitMs)
{
if (!_client)
{
return true;
}
if (maxWaitMs == 0)
{
maxWaitMs = WIFICLIENT_MAX_FLUSH_WAIT_MS;
}
return _client->wait_until_sent(maxWaitMs);
}
bool WiFiClient::stop(unsigned int maxWaitMs)
{
if (!_client)
{
return true;
}
bool ret = flush(maxWaitMs); // virtual, may be ssl's
if (_client->close() != ERR_OK)
{
ret = false;
}
return ret;
}
uint8_t WiFiClient::connected()
{
if (!_client || _client->state() == CLOSED)
{
return 0;
}
return _client->state() == ESTABLISHED || available();
}
@ -387,9 +340,7 @@ uint8_t WiFiClient::connected()
uint8_t WiFiClient::status()
{
if (!_client)
{
return CLOSED;
}
return _client->state();
}
@ -401,9 +352,7 @@ WiFiClient::operator bool()
IPAddress WiFiClient::remoteIP()
{
if (!_client || !_client->getRemoteAddress())
{
return IPAddress(0U);
}
return _client->getRemoteAddress();
}
@ -411,9 +360,7 @@ IPAddress WiFiClient::remoteIP()
uint16_t WiFiClient::remotePort()
{
if (!_client)
{
return 0;
}
return _client->getRemotePort();
}
@ -421,9 +368,7 @@ uint16_t WiFiClient::remotePort()
IPAddress WiFiClient::localIP()
{
if (!_client)
{
return IPAddress(0U);
}
return IPAddress(_client->getLocalAddress());
}
@ -431,55 +376,50 @@ IPAddress WiFiClient::localIP()
uint16_t WiFiClient::localPort()
{
if (!_client)
{
return 0;
}
return _client->getLocalPort();
}
void WiFiClient::stopAll()
{
for (WiFiClient* it = _s_first; it; it = it->_next)
{
for (WiFiClient* it = _s_first; it; it = it->_next) {
it->stop();
}
}
void WiFiClient::stopAllExcept(WiFiClient* except)
void WiFiClient::stopAllExcept(WiFiClient* except)
{
for (WiFiClient* it = _s_first; it; it = it->_next)
{
if (it != except)
{
for (WiFiClient* it = _s_first; it; it = it->_next) {
if (it != except) {
it->stop();
}
}
}
void WiFiClient::keepAlive(uint16_t idle_sec, uint16_t intv_sec, uint8_t count)
void WiFiClient::keepAlive (uint16_t idle_sec, uint16_t intv_sec, uint8_t count)
{
_client->keepAlive(idle_sec, intv_sec, count);
}
bool WiFiClient::isKeepAliveEnabled() const
bool WiFiClient::isKeepAliveEnabled () const
{
return _client->isKeepAliveEnabled();
}
uint16_t WiFiClient::getKeepAliveIdle() const
uint16_t WiFiClient::getKeepAliveIdle () const
{
return _client->getKeepAliveIdle();
}
uint16_t WiFiClient::getKeepAliveInterval() const
uint16_t WiFiClient::getKeepAliveInterval () const
{
return _client->getKeepAliveInterval();
}
uint8_t WiFiClient::getKeepAliveCount() const
uint8_t WiFiClient::getKeepAliveCount () const
{
return _client->getKeepAliveCount();
}

View File

@ -1,22 +1,22 @@
/*
WiFiClient.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
WiFiClient.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is 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.
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
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
Modified by Ivan Grokhotkov, December 2014 - esp8266 support
Modified by Ivan Grokhotkov, December 2014 - esp8266 support
*/
#ifndef wificlient_h
@ -42,108 +42,94 @@
class ClientContext;
class WiFiServer;
class WiFiClient : public Client, public SList<WiFiClient>
{
class WiFiClient : public Client, public SList<WiFiClient> {
protected:
WiFiClient(ClientContext* client);
WiFiClient(ClientContext* client);
public:
WiFiClient();
virtual ~WiFiClient();
WiFiClient(const WiFiClient&);
WiFiClient& operator=(const WiFiClient&);
WiFiClient();
virtual ~WiFiClient();
WiFiClient(const WiFiClient&);
WiFiClient& operator=(const WiFiClient&);
uint8_t status();
virtual int connect(IPAddress ip, uint16_t port) override;
virtual int connect(const char *host, uint16_t port) override;
virtual int connect(const String& host, uint16_t port);
virtual size_t write(uint8_t) override;
virtual size_t write(const uint8_t *buf, size_t size) override;
virtual size_t write_P(PGM_P buf, size_t size);
size_t write(Stream& stream);
uint8_t status();
virtual int connect(IPAddress ip, uint16_t port) override;
virtual int connect(const char *host, uint16_t port) override;
virtual int connect(const String& host, uint16_t port);
virtual size_t write(uint8_t) override;
virtual size_t write(const uint8_t *buf, size_t size) override;
virtual size_t write_P(PGM_P buf, size_t size);
size_t write(Stream& stream);
// This one is deprecated, use write(Stream& instead)
size_t write(Stream& stream, size_t unitSize) __attribute__((deprecated));
// This one is deprecated, use write(Stream& instead)
size_t write(Stream& stream, size_t unitSize) __attribute__ ((deprecated));
virtual int available() override;
virtual int read() override;
virtual int read(uint8_t *buf, size_t size) override;
virtual int peek() override;
virtual size_t peekBytes(uint8_t *buffer, size_t length);
size_t peekBytes(char *buffer, size_t length)
{
return peekBytes((uint8_t *) buffer, length);
}
virtual void flush() override
{
(void)flush(0);
}
virtual void stop() override
{
(void)stop(0);
}
bool flush(unsigned int maxWaitMs);
bool stop(unsigned int maxWaitMs);
virtual uint8_t connected() override;
virtual operator bool() override;
virtual int available() override;
virtual int read() override;
virtual int read(uint8_t *buf, size_t size) override;
virtual int peek() override;
virtual size_t peekBytes(uint8_t *buffer, size_t length);
size_t peekBytes(char *buffer, size_t length) {
return peekBytes((uint8_t *) buffer, length);
}
virtual void flush() override { (void)flush(0); }
virtual void stop() override { (void)stop(0); }
bool flush(unsigned int maxWaitMs);
bool stop(unsigned int maxWaitMs);
virtual uint8_t connected() override;
virtual operator bool() override;
IPAddress remoteIP();
uint16_t remotePort();
IPAddress localIP();
uint16_t localPort();
IPAddress remoteIP();
uint16_t remotePort();
IPAddress localIP();
uint16_t localPort();
static void setLocalPortStart(uint16_t port)
{
_localPort = port;
}
static void setLocalPortStart(uint16_t port) { _localPort = port; }
size_t availableForWrite();
size_t availableForWrite();
friend class WiFiServer;
friend class WiFiServer;
using Print::write;
using Print::write;
static void stopAll();
static void stopAllExcept(WiFiClient * c);
static void stopAll();
static void stopAllExcept(WiFiClient * c);
void keepAlive(uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT);
bool isKeepAliveEnabled() const;
uint16_t getKeepAliveIdle() const;
uint16_t getKeepAliveInterval() const;
uint8_t getKeepAliveCount() const;
void disableKeepAlive()
{
keepAlive(0, 0, 0);
}
void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT);
bool isKeepAliveEnabled () const;
uint16_t getKeepAliveIdle () const;
uint16_t getKeepAliveInterval () const;
uint8_t getKeepAliveCount () const;
void disableKeepAlive () { keepAlive(0, 0, 0); }
// default NoDelay=False (Nagle=True=!NoDelay)
// Nagle is for shortly delaying outgoing data, to send less/bigger packets
// Nagle should be disabled for telnet-like/interactive streams
// Nagle is meaningless/ignored when Sync=true
static void setDefaultNoDelay(bool noDelay);
static bool getDefaultNoDelay();
bool getNoDelay() const;
void setNoDelay(bool nodelay);
// default NoDelay=False (Nagle=True=!NoDelay)
// Nagle is for shortly delaying outgoing data, to send less/bigger packets
// Nagle should be disabled for telnet-like/interactive streams
// Nagle is meaningless/ignored when Sync=true
static void setDefaultNoDelay (bool noDelay);
static bool getDefaultNoDelay ();
bool getNoDelay() const;
void setNoDelay(bool nodelay);
// default Sync=false
// When sync is true, all writes are automatically flushed.
// This is slower but also does not allocate
// temporary memory for sending data
static void setDefaultSync(bool sync);
static bool getDefaultSync();
bool getSync() const;
void setSync(bool sync);
// default Sync=false
// When sync is true, all writes are automatically flushed.
// This is slower but also does not allocate
// temporary memory for sending data
static void setDefaultSync (bool sync);
static bool getDefaultSync ();
bool getSync() const;
void setSync(bool sync);
protected:
static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
static void _s_err(void* arg, int8_t err);
static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
static void _s_err(void* arg, int8_t err);
int8_t _connected(void* tpcb, int8_t err);
void _err(int8_t err);
int8_t _connected(void* tpcb, int8_t err);
void _err(int8_t err);
ClientContext* _client;
static uint16_t _localPort;
ClientContext* _client;
static uint16_t _localPort;
};
#endif

View File

@ -1,22 +1,22 @@
/*
WiFiClientSecure.h - Variant of WiFiClient with TLS support
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
WiFiClientSecure.h - Variant of WiFiClient with TLS support
Copyright (c) 2015 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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
@ -24,18 +24,18 @@
//using namespace axTLS;
/**********************************
!! Now BearSSL is the default !!
While not advised,
Use legacy API without updating with:
#define USING_AXTLS
#include <ESP8266WiFi.h>
//#include <WiFiClientSecure.h>
#include "WiFiClientSecureAxTLS.h"
using namespace axTLS;
* !! Now BearSSL is the default !!
*
* While not advised,
* Use legacy API without updating with:
*
#define USING_AXTLS
#include <ESP8266WiFi.h>
//#include <WiFiClientSecure.h>
#include "WiFiClientSecureAxTLS.h"
using namespace axTLS;
*
*
**********************************/
#include "WiFiClientSecureBearSSL.h"

View File

@ -1,22 +1,22 @@
/*
WiFiClientSecure.cpp - Variant of WiFiClient with TLS support
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
WiFiClientSecure.cpp - Variant of WiFiClient with TLS support
Copyright (c) 2015 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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
@ -42,8 +42,7 @@
#include "include/SSLContext.h"
#include "include/ClientContext.h"
namespace axTLS
{
namespace axTLS {
SSL_CTX* SSLContext::_ssl_client_ctx = nullptr;
int SSLContext::_ssl_client_ctx_refcnt = 0;
@ -58,7 +57,7 @@ WiFiClientSecure::WiFiClientSecure()
WiFiClientSecure::~WiFiClientSecure()
{
_ssl = nullptr;
_ssl = nullptr;
}
// Only called by the WifiServerSecure, need to get the keys/certs loaded before beginning
@ -78,25 +77,18 @@ WiFiClientSecure::WiFiClientSecure(ClientContext* client, bool usePMEM,
std::shared_ptr<SSLContext> _new_ssl_shared(_new_ssl);
_ssl = _new_ssl_shared;
if (usePMEM)
{
if (rsakey && rsakeyLen)
{
if (usePMEM) {
if (rsakey && rsakeyLen) {
_ssl->loadObject_P(SSL_OBJ_RSA_KEY, rsakey, rsakeyLen);
}
if (cert && certLen)
{
if (cert && certLen) {
_ssl->loadObject_P(SSL_OBJ_X509_CERT, cert, certLen);
}
}
else
{
if (rsakey && rsakeyLen)
{
} else {
if (rsakey && rsakeyLen) {
_ssl->loadObject(SSL_OBJ_RSA_KEY, rsakey, rsakeyLen);
}
if (cert && certLen)
{
if (cert && certLen) {
_ssl->loadObject(SSL_OBJ_X509_CERT, cert, certLen);
}
}
@ -105,8 +97,7 @@ WiFiClientSecure::WiFiClientSecure(ClientContext* client, bool usePMEM,
int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
{
if (!WiFiClient::connect(ip, port))
{
if (!WiFiClient::connect(ip, port)) {
return 0;
}
@ -116,12 +107,10 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
int WiFiClientSecure::connect(const char* name, uint16_t port)
{
IPAddress remote_addr;
if (!WiFi.hostByName(name, remote_addr))
{
if (!WiFi.hostByName(name, remote_addr)) {
return 0;
}
if (!WiFiClient::connect(remote_addr, port))
{
if (!WiFiClient::connect(remote_addr, port)) {
return 0;
}
return _connectSSL(name);
@ -134,15 +123,13 @@ int WiFiClientSecure::connect(const String& host, uint16_t port)
int WiFiClientSecure::_connectSSL(const char* hostName)
{
if (!_ssl)
{
if (!_ssl) {
_ssl = std::make_shared<SSLContext>();
}
_ssl->connect(_client, hostName, _timeout);
auto status = ssl_handshake_status(*_ssl);
if (status != SSL_OK)
{
if (status != SSL_OK) {
_ssl = nullptr;
return 0;
}
@ -152,19 +139,16 @@ int WiFiClientSecure::_connectSSL(const char* hostName)
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
{
if (!_ssl)
{
if (!_ssl) {
return 0;
}
int rc = _ssl->write(buf, size);
if (rc >= 0)
{
if (rc >= 0) {
return rc;
}
if (rc != SSL_CLOSE_NOTIFY)
{
if (rc != SSL_CLOSE_NOTIFY) {
_ssl = nullptr;
}
@ -190,25 +174,22 @@ size_t WiFiClientSecure::write(Stream& stream)
{
return 0;
}
do
{
do {
uint8_t temp[256]; // Temporary chunk size same as ClientContext
countSent = 0;
countRead = stream.readBytes(temp, sizeof(temp));
if (countRead)
{
if (countRead) {
countSent = write(temp, countRead);
totalSent += countSent;
}
yield(); // Feed the WDT
} while ((countSent == countRead) && (countSent > 0));
} while ( (countSent == countRead) && (countSent > 0) );
return totalSent;
}
int WiFiClientSecure::read(uint8_t *buf, size_t size)
{
if (!_ssl)
{
if (!_ssl) {
return 0;
}
@ -217,8 +198,7 @@ int WiFiClientSecure::read(uint8_t *buf, size_t size)
int WiFiClientSecure::read()
{
if (!_ssl)
{
if (!_ssl) {
return -1;
}
@ -227,8 +207,7 @@ int WiFiClientSecure::read()
int WiFiClientSecure::peek()
{
if (!_ssl)
{
if (!_ssl) {
return -1;
}
@ -239,28 +218,22 @@ size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length)
{
size_t count = 0;
if (!_ssl)
{
if (!_ssl) {
return 0;
}
_startMillis = millis();
while ((available() < (int) length) && ((millis() - _startMillis) < _timeout))
{
while ((available() < (int) length) && ((millis() - _startMillis) < _timeout)) {
yield();
}
if (!_ssl)
{
if (!_ssl) {
return 0;
}
if (available() < (int) length)
{
if (available() < (int) length) {
count = available();
}
else
{
} else {
count = length;
}
@ -269,8 +242,7 @@ size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length)
int WiFiClientSecure::available()
{
if (!_ssl)
{
if (!_ssl) {
return 0;
}
@ -279,23 +251,20 @@ int WiFiClientSecure::available()
/*
SSL TCP RX data connected
null x x N
!null x Y Y
Y Y x Y
x N N N
err x N N
SSL TCP RX data connected
null x x N
!null x Y Y
Y Y x Y
x N N N
err x N N
*/
uint8_t WiFiClientSecure::connected()
{
if (_ssl)
{
if (_ssl->hasData())
{
if (_ssl) {
if (_ssl->hasData()) {
return true;
}
if (_client && _client->state() == ESTABLISHED && _ssl->connected())
{
if (_client && _client->state() == ESTABLISHED && _ssl->connected()) {
return true;
}
}
@ -304,8 +273,7 @@ uint8_t WiFiClientSecure::connected()
bool WiFiClientSecure::stop(unsigned int maxWaitMs)
{
if (_ssl)
{
if (_ssl) {
_ssl->stop();
}
return WiFiClient::stop(maxWaitMs);
@ -313,17 +281,12 @@ bool WiFiClientSecure::stop(unsigned int maxWaitMs)
static bool parseHexNibble(char pb, uint8_t* res)
{
if (pb >= '0' && pb <= '9')
{
*res = (uint8_t)(pb - '0'); return true;
}
else if (pb >= 'a' && pb <= 'f')
{
*res = (uint8_t)(pb - 'a' + 10); return true;
}
else if (pb >= 'A' && pb <= 'F')
{
*res = (uint8_t)(pb - 'A' + 10); return true;
if (pb >= '0' && pb <= '9') {
*res = (uint8_t) (pb - '0'); return true;
} else if (pb >= 'a' && pb <= 'f') {
*res = (uint8_t) (pb - 'a' + 10); return true;
} else if (pb >= 'A' && pb <= 'F') {
*res = (uint8_t) (pb - 'A' + 10); return true;
}
return false;
}
@ -332,27 +295,23 @@ static bool parseHexNibble(char pb, uint8_t* res)
static bool matchName(const String& name, const String& domainName)
{
int wildcardPos = name.indexOf('*');
if (wildcardPos == -1)
{
if (wildcardPos == -1) {
// Not a wildcard, expect an exact match
return name == domainName;
}
int firstDotPos = name.indexOf('.');
if (wildcardPos > firstDotPos)
{
if (wildcardPos > firstDotPos) {
// Wildcard is not part of leftmost component of domain name
// Do not attempt to match (rfc6125 6.4.3.1)
return false;
}
if (wildcardPos != 0 || firstDotPos != 1)
{
if (wildcardPos != 0 || firstDotPos != 1) {
// Matching of wildcards such as baz*.example.com and b*z.example.com
// is optional. Maybe implement this in the future?
return false;
}
int domainNameFirstDotPos = domainName.indexOf('.');
if (domainNameFirstDotPos < 0)
{
if (domainNameFirstDotPos < 0) {
return false;
}
return domainName.substring(domainNameFirstDotPos) == name.substring(firstDotPos);
@ -360,36 +319,30 @@ static bool matchName(const String& name, const String& domainName)
bool WiFiClientSecure::verify(const char* fp, const char* domain_name)
{
if (!_ssl)
{
if (!_ssl) {
return false;
}
uint8_t sha1[20];
int len = strlen(fp);
int pos = 0;
for (size_t i = 0; i < sizeof(sha1); ++i)
{
while (pos < len && ((fp[pos] == ' ') || (fp[pos] == ':')))
{
for (size_t i = 0; i < sizeof(sha1); ++i) {
while (pos < len && ((fp[pos] == ' ') || (fp[pos] == ':'))) {
++pos;
}
if (pos > len - 2)
{
if (pos > len - 2) {
DEBUGV("pos:%d len:%d fingerprint too short\r\n", pos, len);
return false;
}
uint8_t high, low;
if (!parseHexNibble(fp[pos], &high) || !parseHexNibble(fp[pos + 1], &low))
{
DEBUGV("pos:%d len:%d invalid hex sequence: %c%c\r\n", pos, len, fp[pos], fp[pos + 1]);
if (!parseHexNibble(fp[pos], &high) || !parseHexNibble(fp[pos+1], &low)) {
DEBUGV("pos:%d len:%d invalid hex sequence: %c%c\r\n", pos, len, fp[pos], fp[pos+1]);
return false;
}
pos += 2;
sha1[i] = low | (high << 4);
}
if (ssl_match_fingerprint(*_ssl, sha1) != 0)
{
if (ssl_match_fingerprint(*_ssl, sha1) != 0) {
DEBUGV("fingerprint doesn't match\r\n");
return false;
}
@ -399,18 +352,16 @@ bool WiFiClientSecure::verify(const char* fp, const char* domain_name)
bool WiFiClientSecure::_verifyDN(const char* domain_name)
{
DEBUGV("domain name: '%s'\r\n", (domain_name) ? domain_name : "(null)");
DEBUGV("domain name: '%s'\r\n", (domain_name)?domain_name:"(null)");
String domain_name_str(domain_name);
domain_name_str.toLowerCase();
const char* san = nullptr;
int i = 0;
while ((san = ssl_get_cert_subject_alt_dnsname(*_ssl, i)) != nullptr)
{
while ((san = ssl_get_cert_subject_alt_dnsname(*_ssl, i)) != nullptr) {
String san_str(san);
san_str.toLowerCase();
if (matchName(san_str, domain_name_str))
{
if (matchName(san_str, domain_name_str)) {
return true;
}
DEBUGV("SAN %d: '%s', no match\r\n", i, san);
@ -419,23 +370,20 @@ bool WiFiClientSecure::_verifyDN(const char* domain_name)
const char* common_name = ssl_get_cert_dn(*_ssl, SSL_X509_CERT_COMMON_NAME);
String common_name_str(common_name);
common_name_str.toLowerCase();
if (common_name && matchName(common_name_str, domain_name_str))
{
if (common_name && matchName(common_name_str, domain_name_str)) {
return true;
}
DEBUGV("CN: '%s', no match\r\n", (common_name) ? common_name : "(null)");
DEBUGV("CN: '%s', no match\r\n", (common_name)?common_name:"(null)");
return false;
}
bool WiFiClientSecure::verifyCertChain(const char* domain_name)
{
if (!_ssl)
{
if (!_ssl) {
return false;
}
if (!_ssl->verifyCert())
{
if (!_ssl->verifyCert()) {
return false;
}
return _verifyDN(domain_name);
@ -443,8 +391,7 @@ bool WiFiClientSecure::verifyCertChain(const char* domain_name)
void WiFiClientSecure::_initSSLContext()
{
if (!_ssl)
{
if (!_ssl) {
_ssl = std::make_shared<SSLContext>();
}
}
@ -512,42 +459,37 @@ void WiFiClientSecure::allowSelfSignedCerts()
extern "C" int __ax_port_read(int fd, uint8_t* buffer, size_t count)
{
ClientContext* _client = SSLContext::getIOContext(fd);
if (!_client || (_client->state() != ESTABLISHED && !_client->getSize()))
{
if (!_client || (_client->state() != ESTABLISHED && !_client->getSize())) {
errno = EIO;
return -1;
}
size_t cb = _client->read((char*) buffer, count);
if (cb != count)
{
if (cb != count) {
errno = EAGAIN;
}
if (cb == 0)
{
if (cb == 0) {
optimistic_yield(100);
return -1;
}
return cb;
}
extern "C" void ax_port_read() __attribute__((weak, alias("__ax_port_read")));
extern "C" void ax_port_read() __attribute__ ((weak, alias("__ax_port_read")));
extern "C" int __ax_port_write(int fd, uint8_t* buffer, size_t count)
{
ClientContext* _client = SSLContext::getIOContext(fd);
if (!_client || _client->state() != ESTABLISHED)
{
if (!_client || _client->state() != ESTABLISHED) {
errno = EIO;
return -1;
}
size_t cb = _client->write(buffer, count);
if (cb != count)
{
if (cb != count) {
errno = EAGAIN;
}
return cb;
}
extern "C" void ax_port_write() __attribute__((weak, alias("__ax_port_write")));
extern "C" void ax_port_write() __attribute__ ((weak, alias("__ax_port_write")));
extern "C" int __ax_get_file(const char *filename, uint8_t **buf)
{
@ -555,12 +497,12 @@ extern "C" int __ax_get_file(const char *filename, uint8_t **buf)
*buf = 0;
return 0;
}
extern "C" void ax_get_file() __attribute__((weak, alias("__ax_get_file")));
extern "C" void ax_get_file() __attribute__ ((weak, alias("__ax_get_file")));
extern "C" void __ax_wdt_feed()
{
optimistic_yield(10000);
}
extern "C" void ax_wdt_feed() __attribute__((weak, alias("__ax_wdt_feed")));
extern "C" void ax_wdt_feed() __attribute__ ((weak, alias("__ax_wdt_feed")));
};

View File

@ -1,22 +1,22 @@
/*
WiFiClientSecure.h - Variant of WiFiClient with TLS support
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
WiFiClientSecure.h - Variant of WiFiClient with TLS support
Copyright (c) 2015 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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
@ -26,75 +26,67 @@
#include "include/ssl.h"
namespace axTLS
{
namespace axTLS {
class SSLContext;
class WiFiClientSecure : public WiFiClient
{
class WiFiClientSecure : public WiFiClient {
public:
WiFiClientSecure() __attribute__((deprecated("Upgrade to BearSSL is advised, check https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/WiFiClientSecure.h#L25-L99")));
~WiFiClientSecure() override;
WiFiClientSecure() __attribute__((deprecated("Upgrade to BearSSL is advised, check https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/WiFiClientSecure.h#L25-L99")));
~WiFiClientSecure() override;
int connect(IPAddress ip, uint16_t port) override;
int connect(const String& host, uint16_t port) override;
int connect(const char* name, uint16_t port) override;
int connect(IPAddress ip, uint16_t port) override;
int connect(const String& host, uint16_t port) override;
int connect(const char* name, uint16_t port) override;
bool verify(const char* fingerprint, const char* domain_name);
bool verifyCertChain(const char* domain_name);
bool verify(const char* fingerprint, const char* domain_name);
bool verifyCertChain(const char* domain_name);
uint8_t connected() override;
size_t write(const uint8_t *buf, size_t size) override;
size_t write_P(PGM_P buf, size_t size) override;
size_t write(Stream& stream); // Note this is not virtual
int read(uint8_t *buf, size_t size) override;
int available() override;
int read() override;
int peek() override;
size_t peekBytes(uint8_t *buffer, size_t length) override;
void stop() override
{
(void)stop(0);
}
bool stop(unsigned int maxWaitMs);
uint8_t connected() override;
size_t write(const uint8_t *buf, size_t size) override;
size_t write_P(PGM_P buf, size_t size) override;
size_t write(Stream& stream); // Note this is not virtual
int read(uint8_t *buf, size_t size) override;
int available() override;
int read() override;
int peek() override;
size_t peekBytes(uint8_t *buffer, size_t length) override;
void stop() override { (void)stop(0); }
bool stop(unsigned int maxWaitMs);
bool setCACert(const uint8_t* pk, size_t size);
bool setCertificate(const uint8_t* pk, size_t size);
bool setPrivateKey(const uint8_t* pk, size_t size);
bool setCACert(const uint8_t* pk, size_t size);
bool setCertificate(const uint8_t* pk, size_t size);
bool setPrivateKey(const uint8_t* pk, size_t size);
bool setCACert_P(PGM_VOID_P pk, size_t size);
bool setCertificate_P(PGM_VOID_P pk, size_t size);
bool setPrivateKey_P(PGM_VOID_P pk, size_t size);
bool setCACert_P(PGM_VOID_P pk, size_t size);
bool setCertificate_P(PGM_VOID_P pk, size_t size);
bool setPrivateKey_P(PGM_VOID_P pk, size_t size);
bool loadCACert(Stream& stream, size_t size);
bool loadCertificate(Stream& stream, size_t size);
bool loadPrivateKey(Stream& stream, size_t size);
bool loadCACert(Stream& stream, size_t size);
bool loadCertificate(Stream& stream, size_t size);
bool loadPrivateKey(Stream& stream, size_t size);
void allowSelfSignedCerts();
void allowSelfSignedCerts();
template<typename TFile>
bool loadCertificate(TFile& file)
{
return loadCertificate(file, file.size());
}
template<typename TFile>
bool loadCertificate(TFile& file) {
return loadCertificate(file, file.size());
}
template<typename TFile>
bool loadPrivateKey(TFile& file)
{
return loadPrivateKey(file, file.size());
}
template<typename TFile>
bool loadPrivateKey(TFile& file) {
return loadPrivateKey(file, file.size());
}
template<typename TFile>
bool loadCACert(TFile& file) {
return loadCACert(file, file.size());
}
template<typename TFile>
bool loadCACert(TFile& file)
{
return loadCACert(file, file.size());
}
friend class WiFiServerSecure; // Needs access to custom constructor below
friend class WiFiServerSecure; // Needs access to custom constructor below
protected:
// Only called by WiFiServerSecure
WiFiClientSecure(ClientContext* client, bool usePMEM, const uint8_t *rsakey, int rsakeyLen, const uint8_t *cert, int certLen);
// Only called by WiFiServerSecure
WiFiClientSecure(ClientContext* client, bool usePMEM, const uint8_t *rsakey, int rsakeyLen, const uint8_t *cert, int certLen);
protected:
void _initSSLContext();

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,23 @@
/*
WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries
- Mostly compatible with Arduino WiFi shield library and standard
WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries
- Mostly compatible with Arduino WiFi shield library and standard
WiFiClient/ServerSecure (except for certificate handling).
Copyright (c) 2018 Earle F. Philhower, III
Copyright (c) 2018 Earle F. Philhower, III
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 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.
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
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
*/
@ -29,12 +29,10 @@
#include "BearSSLHelpers.h"
#include "CertStoreBearSSL.h"
namespace BearSSL
{
namespace BearSSL {
class WiFiClientSecure : public WiFiClient
{
public:
class WiFiClientSecure : public WiFiClient {
public:
WiFiClientSecure();
WiFiClientSecure(const WiFiClientSecure &rhs);
~WiFiClientSecure() override;
@ -46,13 +44,11 @@ public:
uint8_t connected() override;
size_t write(const uint8_t *buf, size_t size) override;
size_t write_P(PGM_P buf, size_t size) override;
size_t write(const char *buf)
{
return write((const uint8_t*)buf, strlen(buf));
size_t write(const char *buf) {
return write((const uint8_t*)buf, strlen(buf));
}
size_t write_P(const char *buf)
{
return write_P((PGM_P)buf, strlen_P(buf));
size_t write_P(const char *buf) {
return write_P((PGM_P)buf, strlen_P(buf));
}
size_t write(Stream& stream); // Note this is not virtual
int read(uint8_t *buf, size_t size) override;
@ -62,59 +58,44 @@ public:
size_t peekBytes(uint8_t *buffer, size_t length) override;
bool flush(unsigned int maxWaitMs);
bool stop(unsigned int maxWaitMs);
void flush() override
{
(void)flush(0);
}
void stop() override
{
(void)stop(0);
}
void flush() override { (void)flush(0); }
void stop() override { (void)stop(0); }
// Allow sessions to be saved/restored automatically to a memory area
void setSession(Session *session)
{
_session = session;
}
void setSession(Session *session) { _session = session; }
// Don't validate the chain, just accept whatever is given. VERY INSECURE!
void setInsecure()
{
_clearAuthenticationSettings();
_use_insecure = true;
void setInsecure() {
_clearAuthenticationSettings();
_use_insecure = true;
}
// Assume a given public key, don't validate or use cert info at all
void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN)
{
_clearAuthenticationSettings();
_knownkey = pk;
_knownkey_usages = usages;
void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN) {
_clearAuthenticationSettings();
_knownkey = pk;
_knownkey_usages = usages;
}
// Only check SHA1 fingerprint of certificate
bool setFingerprint(const uint8_t fingerprint[20])
{
_clearAuthenticationSettings();
_use_fingerprint = true;
memcpy_P(_fingerprint, fingerprint, 20);
return true;
bool setFingerprint(const uint8_t fingerprint[20]) {
_clearAuthenticationSettings();
_use_fingerprint = true;
memcpy_P(_fingerprint, fingerprint, 20);
return true;
}
bool setFingerprint(const char *fpStr);
// Accept any certificate that's self-signed
void allowSelfSignedCerts()
{
_clearAuthenticationSettings();
_use_self_signed = true;
void allowSelfSignedCerts() {
_clearAuthenticationSettings();
_use_self_signed = true;
}
// Install certificates of trusted CAs or specific site
void setTrustAnchors(const X509List *ta)
{
_clearAuthenticationSettings();
_ta = ta;
void setTrustAnchors(const X509List *ta) {
_clearAuthenticationSettings();
_ta = ta;
}
// In cases when NTP is not used, app must set a time manually to check cert validity
void setX509Time(time_t now)
{
_now = now;
void setX509Time(time_t now) {
_now = now;
}
// Install a client certificate for this connection, in case the server requires it (i.e. MQTT)
void setClientRSACert(const X509List *cert, const PrivateKey *sk);
@ -125,18 +106,16 @@ public:
void setBufferSizes(int recv, int xmit);
// Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection)
int getMFLNStatus()
{
return connected() && br_ssl_engine_get_mfln_negotiated(_eng);
int getMFLNStatus() {
return connected() && br_ssl_engine_get_mfln_negotiated(_eng);
}
// Return an error code and possibly a text string in a passed-in buffer with last SSL failure
int getLastSSLError(char *dest = NULL, size_t len = 0);
// Attach a preconfigured certificate store
void setCertStore(CertStore *certStore)
{
_certStore = certStore;
void setCertStore(CertStore *certStore) {
_certStore = certStore;
}
// Select specific ciphers (i.e. optimize for speed over security)
@ -153,7 +132,7 @@ public:
////////////////////////////////////////////////////
// AxTLS API deprecated warnings to help upgrading
#define AXTLS_DEPRECATED \
#define AXTLS_DEPRECATED \
__attribute__((deprecated( \
"This is deprecated AxTLS API, " \
"check https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/WiFiClientSecure.h#L25-L99")))
@ -169,66 +148,57 @@ public:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
bool setCACert_P(PGM_VOID_P pk, size_t size) AXTLS_DEPRECATED
{
return setCACert((const uint8_t *)pk, size);
bool setCACert_P(PGM_VOID_P pk, size_t size) AXTLS_DEPRECATED {
return setCACert((const uint8_t *)pk, size);
}
bool setCertificate_P(PGM_VOID_P pk, size_t size) AXTLS_DEPRECATED
{
return setCertificate((const uint8_t *)pk, size);
bool setCertificate_P(PGM_VOID_P pk, size_t size) AXTLS_DEPRECATED {
return setCertificate((const uint8_t *)pk, size);
}
bool setPrivateKey_P(PGM_VOID_P pk, size_t size) AXTLS_DEPRECATED
{
return setPrivateKey((const uint8_t *)pk, size);
bool setPrivateKey_P(PGM_VOID_P pk, size_t size) AXTLS_DEPRECATED {
return setPrivateKey((const uint8_t *)pk, size);
}
#pragma GCC diagnostic pop
template<typename TFile>
bool loadCertificate(TFile& file)
{
return loadCertificate(file, file.size());
bool loadCertificate(TFile& file) {
return loadCertificate(file, file.size());
}
template<typename TFile>
bool loadPrivateKey(TFile& file)
{
return loadPrivateKey(file, file.size());
bool loadPrivateKey(TFile& file) {
return loadPrivateKey(file, file.size());
}
template<typename TFile>
bool loadCACert(TFile& file)
{
return loadCACert(file, file.size());
bool loadCACert(TFile& file) {
return loadCACert(file, file.size());
}
bool verify(const char* fingerprint, const char* domain_name) AXTLS_DEPRECATED
{
(void)fingerprint;
(void)domain_name;
return connected();
bool verify(const char* fingerprint, const char* domain_name) AXTLS_DEPRECATED {
(void)fingerprint;
(void)domain_name;
return connected();
}
bool verifyCertChain(const char* domain_name) AXTLS_DEPRECATED
{
(void)domain_name;
return connected();
bool verifyCertChain(const char* domain_name) AXTLS_DEPRECATED {
(void)domain_name;
return connected();
}
// AxTLS API deprecated section end
/////////////////////////////////////
private:
private:
void _clear();
void _clearAuthenticationSettings();
// Only one of the following two should ever be != nullptr!
std::shared_ptr<br_ssl_client_context> _sc;
std::shared_ptr<br_ssl_server_context> _sc_svr;
inline bool ctx_present()
{
return (_sc != nullptr) || (_sc_svr != nullptr);
inline bool ctx_present() {
return (_sc != nullptr) || (_sc_svr != nullptr);
}
br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts
std::shared_ptr<br_x509_minimal_context> _x509_minimal;
@ -286,9 +256,9 @@ private:
// Methods for handling server.available() call which returns a client connection.
friend class WiFiServerSecure; // Server needs to access these constructors
WiFiClientSecure(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type,
const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta);
const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta);
WiFiClientSecure(ClientContext* client, const X509List *chain, const PrivateKey *sk,
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta);
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta);
// RSA keyed server
bool _connectSSLServerRSA(const X509List *chain, const PrivateKey *sk, const X509List *client_CA_ta);

View File

@ -1,31 +1,31 @@
/*
WiFiServer.cpp - TCP/IP server for esp8266, mostly compatible
WiFiServer.cpp - TCP/IP server for esp8266, mostly compatible
with Arduino WiFi shield library
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
#define LWIP_INTERNAL
extern "C" {
#include "osapi.h"
#include "ets_sys.h"
#include "osapi.h"
#include "ets_sys.h"
}
#include "debug.h"
@ -38,53 +38,47 @@ extern "C" {
#include <include/ClientContext.h>
WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port)
: _port(port)
, _addr(addr)
, _pcb(nullptr)
, _unclaimed(nullptr)
, _discarded(nullptr)
: _port(port)
, _addr(addr)
, _pcb(nullptr)
, _unclaimed(nullptr)
, _discarded(nullptr)
{
}
WiFiServer::WiFiServer(uint16_t port)
: _port(port)
, _addr(IP_ANY_TYPE)
, _pcb(nullptr)
, _unclaimed(nullptr)
, _discarded(nullptr)
: _port(port)
, _addr(IP_ANY_TYPE)
, _pcb(nullptr)
, _unclaimed(nullptr)
, _discarded(nullptr)
{
}
void WiFiServer::begin()
{
begin(_port);
void WiFiServer::begin() {
begin(_port);
}
void WiFiServer::begin(uint16_t port)
{
void WiFiServer::begin(uint16_t port) {
close();
_port = port;
err_t err;
tcp_pcb* pcb = tcp_new();
if (!pcb)
{
return;
}
pcb->so_options |= SOF_REUSEADDR;
// (IPAddress _addr) operator-converted to (const ip_addr_t*)
err = tcp_bind(pcb, _addr, _port);
if (err != ERR_OK)
{
if (err != ERR_OK) {
tcp_close(pcb);
return;
}
tcp_pcb* listen_pcb = tcp_listen(pcb);
if (!listen_pcb)
{
if (!listen_pcb) {
tcp_close(pcb);
return;
}
@ -93,13 +87,11 @@ void WiFiServer::begin(uint16_t port)
tcp_arg(listen_pcb, (void*) this);
}
void WiFiServer::setNoDelay(bool nodelay)
{
_noDelay = nodelay ? _ndTrue : _ndFalse;
void WiFiServer::setNoDelay(bool nodelay) {
_noDelay = nodelay? _ndTrue: _ndFalse;
}
bool WiFiServer::getNoDelay()
{
bool WiFiServer::getNoDelay() {
switch (_noDelay)
{
case _ndFalse: return false;
@ -108,20 +100,15 @@ bool WiFiServer::getNoDelay()
}
}
bool WiFiServer::hasClient()
{
bool WiFiServer::hasClient() {
if (_unclaimed)
{
return true;
}
return false;
}
WiFiClient WiFiServer::available(byte* status)
{
WiFiClient WiFiServer::available(byte* status) {
(void) status;
if (_unclaimed)
{
if (_unclaimed) {
WiFiClient result(_unclaimed);
_unclaimed = _unclaimed->next();
result.setNoDelay(getNoDelay());
@ -133,37 +120,29 @@ WiFiClient WiFiServer::available(byte* status)
return WiFiClient();
}
uint8_t WiFiServer::status()
{
uint8_t WiFiServer::status() {
if (!_pcb)
{
return CLOSED;
}
return _pcb->state;
}
void WiFiServer::close()
{
if (!_pcb)
{
return;
void WiFiServer::close() {
if (!_pcb) {
return;
}
tcp_close(_pcb);
_pcb = nullptr;
}
void WiFiServer::stop()
{
void WiFiServer::stop() {
close();
}
size_t WiFiServer::write(uint8_t b)
{
size_t WiFiServer::write(uint8_t b) {
return write(&b, 1);
}
size_t WiFiServer::write(const uint8_t *buffer, size_t size)
{
size_t WiFiServer::write(const uint8_t *buffer, size_t size) {
// write to all clients
// not implemented
(void) buffer;
@ -172,23 +151,17 @@ size_t WiFiServer::write(const uint8_t *buffer, size_t size)
}
template<typename T>
T* slist_append_tail(T* head, T* item)
{
T* slist_append_tail(T* head, T* item) {
if (!head)
{
return item;
}
T* last = head;
while (last->next())
{
while(last->next())
last = last->next();
}
last->next(item);
return head;
}
long WiFiServer::_accept(tcp_pcb* apcb, long err)
{
long WiFiServer::_accept(tcp_pcb* apcb, long err) {
(void) err;
DEBUGV("WS:ac\r\n");
ClientContext* client = new ClientContext(apcb, &WiFiServer::_s_discard, this);
@ -197,19 +170,16 @@ long WiFiServer::_accept(tcp_pcb* apcb, long err)
return ERR_OK;
}
void WiFiServer::_discard(ClientContext* client)
{
void WiFiServer::_discard(ClientContext* client) {
(void) client;
// _discarded = slist_append_tail(_discarded, client);
DEBUGV("WS:dis\r\n");
}
long WiFiServer::_s_accept(void *arg, tcp_pcb* newpcb, long err)
{
long WiFiServer::_s_accept(void *arg, tcp_pcb* newpcb, long err) {
return reinterpret_cast<WiFiServer*>(arg)->_accept(newpcb, err);
}
void WiFiServer::_s_discard(void* server, ClientContext* ctx)
{
void WiFiServer::_s_discard(void* server, ClientContext* ctx) {
reinterpret_cast<WiFiServer*>(server)->_discard(ctx);
}

View File

@ -1,31 +1,31 @@
/*
WiFiServer.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino LLC. All right reserved.
WiFiServer.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is 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.
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
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
Modified by Ivan Grokhotkov, December 2014 - esp8266 support
Modified by Ivan Grokhotkov, December 2014 - esp8266 support
*/
#ifndef wifiserver_h
#define wifiserver_h
extern "C" {
#include "include/wl_definitions.h"
#include "include/wl_definitions.h"
struct tcp_pcb;
struct tcp_pcb;
}
#include "Server.h"
@ -34,42 +34,41 @@ extern "C" {
class ClientContext;
class WiFiClient;
class WiFiServer : public Server
{
// Secure server needs access to all the private entries here
class WiFiServer : public Server {
// Secure server needs access to all the private entries here
protected:
uint16_t _port;
IPAddress _addr;
tcp_pcb* _pcb;
uint16_t _port;
IPAddress _addr;
tcp_pcb* _pcb;
ClientContext* _unclaimed;
ClientContext* _discarded;
enum { _ndDefault, _ndFalse, _ndTrue } _noDelay = _ndDefault;
ClientContext* _unclaimed;
ClientContext* _discarded;
enum { _ndDefault, _ndFalse, _ndTrue } _noDelay = _ndDefault;
public:
WiFiServer(const IPAddress& addr, uint16_t port);
WiFiServer(uint16_t port);
virtual ~WiFiServer() {}
WiFiClient available(uint8_t* status = NULL);
bool hasClient();
void begin();
void begin(uint16_t port);
void setNoDelay(bool nodelay);
bool getNoDelay();
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
uint8_t status();
void close();
void stop();
WiFiServer(const IPAddress& addr, uint16_t port);
WiFiServer(uint16_t port);
virtual ~WiFiServer() {}
WiFiClient available(uint8_t* status = NULL);
bool hasClient();
void begin();
void begin(uint16_t port);
void setNoDelay(bool nodelay);
bool getNoDelay();
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
uint8_t status();
void close();
void stop();
using Print::write;
using Print::write;
protected:
long _accept(tcp_pcb* newpcb, long err);
void _discard(ClientContext* client);
long _accept(tcp_pcb* newpcb, long err);
void _discard(ClientContext* client);
static long _s_accept(void *arg, tcp_pcb* newpcb, long err);
static void _s_discard(void* server, ClientContext* ctx);
static long _s_accept(void *arg, tcp_pcb* newpcb, long err);
static void _s_discard(void* server, ClientContext* ctx);
};
#endif

View File

@ -1,20 +1,20 @@
/*
WiFiServerSecure.h - Library for Arduino ESP8266
Copyright (c) 2017 Earle F. Philhower, III
WiFiServerSecure.h - Library for Arduino ESP8266
Copyright (c) 2017 Earle F. Philhower, III
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 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.
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
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 <WiFiClientSecure.h>

View File

@ -1,29 +1,29 @@
/*
WiFiServerSecure.cpp - SSL server for esp8266, mostly compatible
WiFiServerSecure.cpp - SSL server for esp8266, mostly compatible
with Arduino WiFi shield library
Copyright (c) 2017 Earle F. Philhower, III
Copyright (c) 2017 Earle F. Philhower, III
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 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.
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
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
*/
#define LWIP_INTERNAL
extern "C" {
#include "osapi.h"
#include "ets_sys.h"
#include "osapi.h"
#include "ets_sys.h"
}
#include "debug.h"
@ -38,8 +38,7 @@ extern "C" {
#include "WiFiServerSecureAxTLS.h"
namespace axTLS
{
namespace axTLS {
WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port)
{
@ -70,8 +69,7 @@ void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, con
WiFiClientSecure WiFiServerSecure::available(uint8_t* status)
{
(void) status; // Unused
if (_unclaimed)
{
if (_unclaimed) {
WiFiClientSecure result(_unclaimed, usePMEM, rsakey, rsakeyLen, cert, certLen);
_unclaimed = _unclaimed->next();
result.setNoDelay(_noDelay);

View File

@ -1,20 +1,20 @@
/*
WiFiServerSecure.h - Library for Arduino ESP8266
Copyright (c) 2017 Earle F. Philhower, III
WiFiServerSecure.h - Library for Arduino ESP8266
Copyright (c) 2017 Earle F. Philhower, III
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 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.
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
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 wifiserversecure_h
@ -22,26 +22,24 @@
#include "WiFiServer.h"
namespace axTLS
{
namespace axTLS {
class WiFiClientSecure;
class WiFiServerSecure : public WiFiServer
{
class WiFiServerSecure : public WiFiServer {
public:
WiFiServerSecure(IPAddress addr, uint16_t port);
WiFiServerSecure(uint16_t port);
void setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen);
void setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen);
virtual ~WiFiServerSecure() {}
WiFiClientSecure available(uint8_t* status = NULL);
WiFiServerSecure(IPAddress addr, uint16_t port);
WiFiServerSecure(uint16_t port);
void setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen);
void setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen);
virtual ~WiFiServerSecure() {}
WiFiClientSecure available(uint8_t* status = NULL);
private:
bool usePMEM = false;
const uint8_t *rsakey = nullptr;
int rsakeyLen = 0;
const uint8_t *cert = nullptr;
int certLen = 0;
bool usePMEM = false;
const uint8_t *rsakey = nullptr;
int rsakeyLen = 0;
const uint8_t *cert = nullptr;
int certLen = 0;
};
};

View File

@ -1,22 +1,22 @@
/*
WiFiServerBearSSL.cpp - SSL server for esp8266, mostly compatible
WiFiServerBearSSL.cpp - SSL server for esp8266, mostly compatible
with Arduino WiFi shield library
Copyright (c) 2018 Earle F. Philhower, III
Copyright (c) 2018 Earle F. Philhower, III
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 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.
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
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
*/
#define LWIP_INTERNAL
@ -37,99 +37,83 @@ extern "C" {
#include <include/ClientContext.h>
#include "WiFiServerSecureBearSSL.h"
namespace BearSSL
{
namespace BearSSL {
// Only need to call the standard server constructor
WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port)
{
stack_thunk_add_ref();
WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port) {
stack_thunk_add_ref();
}
// Only need to call the standard server constructor
WiFiServerSecure::WiFiServerSecure(uint16_t port) : WiFiServer(port)
{
stack_thunk_add_ref();
WiFiServerSecure::WiFiServerSecure(uint16_t port) : WiFiServer(port) {
stack_thunk_add_ref();
}
WiFiServerSecure::WiFiServerSecure(const WiFiServerSecure &rhs) : WiFiServer(rhs)
{
*this = rhs;
stack_thunk_add_ref();
WiFiServerSecure::WiFiServerSecure(const WiFiServerSecure &rhs) : WiFiServer(rhs) {
*this = rhs;
stack_thunk_add_ref();
}
WiFiServerSecure::~WiFiServerSecure()
{
stack_thunk_del_ref();
_axtls_chain = nullptr;
_axtls_sk = nullptr;
WiFiServerSecure::~WiFiServerSecure() {
stack_thunk_del_ref();
_axtls_chain = nullptr;
_axtls_sk = nullptr;
}
// Specify a RSA-signed certificate and key for the server. Only copies the pointer, the
// caller needs to preserve this chain and key for the life of the object.
void WiFiServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk)
{
_chain = chain;
_sk = sk;
void WiFiServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk) {
_chain = chain;
_sk = sk;
}
// Specify a EC-signed certificate and key for the server. Only copies the pointer, the
// caller needs to preserve this chain and key for the life of the object.
void WiFiServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk)
{
_chain = chain;
_cert_issuer_key_type = cert_issuer_key_type;
_sk = sk;
void WiFiServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk) {
_chain = chain;
_cert_issuer_key_type = cert_issuer_key_type;
_sk = sk;
}
// Return a client if there's an available connection waiting. If one is returned,
// then any validation (i.e. client cert checking) will have succeeded.
WiFiClientSecure WiFiServerSecure::available(uint8_t* status)
{
(void) status; // Unused
if (_unclaimed)
{
if (_sk && _sk->isRSA())
{
WiFiClientSecure result(_unclaimed, _chain, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
_unclaimed = _unclaimed->next();
result.setNoDelay(_noDelay);
DEBUGV("WS:av\r\n");
return result;
}
else if (_sk && _sk->isEC())
{
WiFiClientSecure result(_unclaimed, _chain, _cert_issuer_key_type, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
_unclaimed = _unclaimed->next();
result.setNoDelay(_noDelay);
DEBUGV("WS:av\r\n");
return result;
}
else
{
// No key was defined, so we can't actually accept and attempt accept() and SSL handshake.
DEBUGV("WS:nokey\r\n");
}
WiFiClientSecure WiFiServerSecure::available(uint8_t* status) {
(void) status; // Unused
if (_unclaimed) {
if (_sk && _sk->isRSA()) {
WiFiClientSecure result(_unclaimed, _chain, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
_unclaimed = _unclaimed->next();
result.setNoDelay(_noDelay);
DEBUGV("WS:av\r\n");
return result;
} else if (_sk && _sk->isEC()) {
WiFiClientSecure result(_unclaimed, _chain, _cert_issuer_key_type, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
_unclaimed = _unclaimed->next();
result.setNoDelay(_noDelay);
DEBUGV("WS:av\r\n");
return result;
} else {
// No key was defined, so we can't actually accept and attempt accept() and SSL handshake.
DEBUGV("WS:nokey\r\n");
}
}
// Something weird, return a no-op object
optimistic_yield(1000);
return WiFiClientSecure();
// Something weird, return a no-op object
optimistic_yield(1000);
return WiFiClientSecure();
}
void WiFiServerSecure::setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen)
{
_axtls_chain = nullptr;
_axtls_sk = nullptr;
_axtls_chain = std::shared_ptr<X509List>(new X509List(cert, certLen));
_axtls_sk = std::shared_ptr<PrivateKey>(new PrivateKey(key, keyLen));
setRSACert(_axtls_chain.get(), _axtls_sk.get());
void WiFiServerSecure::setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) {
_axtls_chain = nullptr;
_axtls_sk = nullptr;
_axtls_chain = std::shared_ptr<X509List>(new X509List(cert, certLen));
_axtls_sk = std::shared_ptr<PrivateKey>(new PrivateKey(key, keyLen));
setRSACert(_axtls_chain.get(), _axtls_sk.get());
}
void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen)
{
setServerKeyAndCert(key, keyLen, cert, certLen);
void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) {
setServerKeyAndCert(key, keyLen, cert, certLen);
}

View File

@ -1,20 +1,20 @@
/*
WiFiServerBearSSL.h - Library for Arduino ESP8266
Copyright (c) 2018 Earle F. Philhower, III
WiFiServerBearSSL.h - Library for Arduino ESP8266
Copyright (c) 2018 Earle F. Philhower, III
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 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.
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
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 wifiserverbearssl_h
@ -25,24 +25,21 @@
#include "BearSSLHelpers.h"
#include <bearssl/bearssl.h>
namespace BearSSL
{
namespace BearSSL {
class WiFiClientSecure;
class WiFiServerSecure : public WiFiServer
{
public:
class WiFiServerSecure : public WiFiServer {
public:
WiFiServerSecure(IPAddress addr, uint16_t port);
WiFiServerSecure(uint16_t port);
WiFiServerSecure(const WiFiServerSecure &rhs);
virtual ~WiFiServerSecure();
// Override the default buffer sizes, if you know what you're doing...
void setBufferSizes(int recv, int xmit)
{
_iobuf_in_size = recv;
_iobuf_out_size = xmit;
void setBufferSizes(int recv, int xmit) {
_iobuf_in_size = recv;
_iobuf_out_size = xmit;
}
// Set the server's RSA key and x509 certificate (required, pick one).
@ -54,9 +51,8 @@ public:
// Require client certificates validated against the passed in x509 trust anchor
// Caller needs to preserve the cert throughout the life of the server.
void setClientTrustAnchor(const X509List *client_CA_ta)
{
_client_CA_ta = client_CA_ta;
void setClientTrustAnchor(const X509List *client_CA_ta) {
_client_CA_ta = client_CA_ta;
}
// If awaiting connection available and authenticated (i.e. client cert), return it.
@ -66,7 +62,7 @@ public:
void setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen);
void setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen);
private:
private:
const X509List *_chain = nullptr;
unsigned _cert_issuer_key_type = 0;
const PrivateKey *_sk = nullptr;

View File

@ -1,23 +1,23 @@
/*
WiFiUdp.cpp - UDP client/server for esp8266, mostly compatible
WiFiUdp.cpp - UDP client/server for esp8266, mostly compatible
with Arduino WiFi shield library
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
Copyright (c) 2015 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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
#define LWIP_INTERNAL
@ -25,9 +25,9 @@
extern "C"
{
#include "include/wl_definitions.h"
#include "osapi.h"
#include "ets_sys.h"
#include "include/wl_definitions.h"
#include "osapi.h"
#include "ets_sys.h"
}
#include "debug.h"
@ -53,9 +53,7 @@ WiFiUDP::WiFiUDP(const WiFiUDP& other)
{
_ctx = other._ctx;
if (_ctx)
{
_ctx->ref();
}
WiFiUDP::_add(this);
}
@ -63,9 +61,7 @@ WiFiUDP& WiFiUDP::operator=(const WiFiUDP& rhs)
{
_ctx = rhs._ctx;
if (_ctx)
{
_ctx->ref();
}
return *this;
}
@ -73,16 +69,13 @@ WiFiUDP::~WiFiUDP()
{
WiFiUDP::_remove(this);
if (_ctx)
{
_ctx->unref();
}
}
/* Start WiFiUDP socket, listening at local port */
uint8_t WiFiUDP::begin(uint16_t port)
{
if (_ctx)
{
if (_ctx) {
_ctx->unref();
_ctx = 0;
}
@ -94,41 +87,35 @@ uint8_t WiFiUDP::begin(uint16_t port)
uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port)
{
if (_ctx)
{
if (_ctx) {
_ctx->unref();
_ctx = 0;
}
if (igmp_joingroup(interfaceAddr, multicast) != ERR_OK)
{
if (igmp_joingroup(interfaceAddr, multicast)!= ERR_OK) {
return 0;
}
_ctx = new UdpContext;
_ctx->ref();
ip_addr_t addr = IPADDR4_INIT(INADDR_ANY);
if (!_ctx->listen(&addr, port))
{
if (!_ctx->listen(&addr, port)) {
return 0;
}
return 1;
}
/* return number of bytes available in the current packet,
will return zero if parsePacket hasn't been called yet */
int WiFiUDP::available()
{
/* return number of bytes available in the current packet,
will return zero if parsePacket hasn't been called yet */
int WiFiUDP::available() {
int result = 0;
if (_ctx)
{
if (_ctx) {
result = static_cast<int>(_ctx->getSize());
}
if (!result)
{
if (!result) {
// yielding here will not make more data "available",
// but it will prevent the system from going into WDT reset
optimistic_yield(1000);
@ -140,8 +127,7 @@ int WiFiUDP::available()
/* Release any resources being used by this WiFiUDP instance */
void WiFiUDP::stop()
{
if (_ctx)
{
if (_ctx) {
_ctx->disconnect();
_ctx->unref();
}
@ -160,8 +146,7 @@ int WiFiUDP::beginPacket(const char *host, uint16_t port)
int WiFiUDP::beginPacket(IPAddress ip, uint16_t port)
{
if (!_ctx)
{
if (!_ctx) {
_ctx = new UdpContext;
_ctx->ref();
}
@ -169,15 +154,13 @@ int WiFiUDP::beginPacket(IPAddress ip, uint16_t port)
}
int WiFiUDP::beginPacketMulticast(IPAddress multicastAddress, uint16_t port,
IPAddress interfaceAddress, int ttl)
IPAddress interfaceAddress, int ttl)
{
if (!_ctx)
{
if (!_ctx) {
_ctx = new UdpContext;
_ctx->ref();
}
if (!_ctx->connect(multicastAddress, port))
{
if (!_ctx->connect(multicastAddress, port)) {
return 0;
}
_ctx->setMulticastInterface(interfaceAddress);
@ -188,9 +171,7 @@ int WiFiUDP::beginPacketMulticast(IPAddress multicastAddress, uint16_t port,
int WiFiUDP::endPacket()
{
if (!_ctx)
{
return 0;
}
return (_ctx->send()) ? 1 : 0;
}
@ -203,9 +184,7 @@ size_t WiFiUDP::write(uint8_t byte)
size_t WiFiUDP::write(const uint8_t *buffer, size_t size)
{
if (!_ctx)
{
return 0;
}
return _ctx->append(reinterpret_cast<const char*>(buffer), size);
}
@ -213,12 +192,9 @@ size_t WiFiUDP::write(const uint8_t *buffer, size_t size)
int WiFiUDP::parsePacket()
{
if (!_ctx)
{
return 0;
}
if (!_ctx->next())
{
if (!_ctx->next()) {
optimistic_yield(100);
return 0;
}
@ -229,9 +205,7 @@ int WiFiUDP::parsePacket()
int WiFiUDP::read()
{
if (!_ctx)
{
return -1;
}
return _ctx->read();
}
@ -239,9 +213,7 @@ int WiFiUDP::read()
int WiFiUDP::read(unsigned char* buffer, size_t len)
{
if (!_ctx)
{
return 0;
}
return _ctx->read(reinterpret_cast<char*>(buffer), len);
}
@ -249,9 +221,7 @@ int WiFiUDP::read(unsigned char* buffer, size_t len)
int WiFiUDP::peek()
{
if (!_ctx)
{
return -1;
}
return _ctx->peek();
}
@ -264,9 +234,7 @@ void WiFiUDP::flush()
IPAddress WiFiUDP::remoteIP()
{
if (!_ctx)
{
return INADDR_ANY;
}
return _ctx->getRemoteAddress();
}
@ -274,9 +242,7 @@ IPAddress WiFiUDP::remoteIP()
uint16_t WiFiUDP::remotePort()
{
if (!_ctx)
{
return 0;
}
return _ctx->getRemotePort();
}
@ -284,9 +250,7 @@ uint16_t WiFiUDP::remotePort()
IPAddress WiFiUDP::destinationIP() const
{
if (!_ctx)
{
return INADDR_ANY;
}
return _ctx->getDestAddress();
}
@ -294,28 +258,22 @@ IPAddress WiFiUDP::destinationIP() const
uint16_t WiFiUDP::localPort() const
{
if (!_ctx)
{
return 0;
}
return _ctx->getLocalPort();
}
void WiFiUDP::stopAll()
{
for (WiFiUDP* it = _s_first; it; it = it->_next)
{
for (WiFiUDP* it = _s_first; it; it = it->_next) {
DEBUGV("%s %p %p\n", __func__, it, _s_first);
it->stop();
}
}
void WiFiUDP::stopAllExcept(WiFiUDP * exC)
{
for (WiFiUDP* it = _s_first; it; it = it->_next)
{
if (it->_ctx != exC->_ctx)
{
void WiFiUDP::stopAllExcept(WiFiUDP * exC) {
for (WiFiUDP* it = _s_first; it; it = it->_next) {
if (it->_ctx != exC->_ctx) {
DEBUGV("%s %p %p\n", __func__, it, _s_first);
it->stop();
}

View File

@ -1,22 +1,22 @@
/*
WiFiUdp.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino LLC. All right reserved.
WiFiUdp.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is 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.
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
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
Modified by Ivan Grokhotkov, January 2015 - esp8266 support
Modified by Ivan Grokhotkov, January 2015 - esp8266 support
*/
#ifndef WIFIUDP_H
@ -29,90 +29,83 @@
class UdpContext;
class WiFiUDP : public UDP, public SList<WiFiUDP>
{
class WiFiUDP : public UDP, public SList<WiFiUDP> {
private:
UdpContext* _ctx;
UdpContext* _ctx;
public:
WiFiUDP(); // Constructor
WiFiUDP(const WiFiUDP& other);
WiFiUDP& operator=(const WiFiUDP& rhs);
virtual ~WiFiUDP();
WiFiUDP(); // Constructor
WiFiUDP(const WiFiUDP& other);
WiFiUDP& operator=(const WiFiUDP& rhs);
virtual ~WiFiUDP();
operator bool() const
{
return _ctx != 0;
}
operator bool() const { return _ctx != 0; }
// initialize, start listening on specified port.
// Returns 1 if successful, 0 if there are no sockets available to use
uint8_t begin(uint16_t port) override;
// Finish with the UDP connetion
void stop() override;
// join a multicast group and listen on the given port
uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port);
// initialize, start listening on specified port.
// Returns 1 if successful, 0 if there are no sockets available to use
uint8_t begin(uint16_t port) override;
// Finish with the UDP connetion
void stop() override;
// join a multicast group and listen on the given port
uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port);
// Sending UDP packets
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
int beginPacket(IPAddress ip, uint16_t port) override;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
int beginPacket(const char *host, uint16_t port) override;
// Start building up a packet to send to the multicast address
// multicastAddress - muticast address to send to
// interfaceAddress - the local IP address of the interface that should be used
// use WiFi.localIP() or WiFi.softAPIP() depending on the interface you need
// ttl - multicast packet TTL (default is 1)
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacketMulticast(IPAddress multicastAddress,
uint16_t port,
IPAddress interfaceAddress,
int ttl = 1);
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
int endPacket() override;
// Write a single byte into the packet
size_t write(uint8_t) override;
// Write size bytes from buffer into the packet
size_t write(const uint8_t *buffer, size_t size) override;
using Print::write;
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
int beginPacket(IPAddress ip, uint16_t port) override;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
int beginPacket(const char *host, uint16_t port) override;
// Start building up a packet to send to the multicast address
// multicastAddress - muticast address to send to
// interfaceAddress - the local IP address of the interface that should be used
// use WiFi.localIP() or WiFi.softAPIP() depending on the interface you need
// ttl - multicast packet TTL (default is 1)
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacketMulticast(IPAddress multicastAddress,
uint16_t port,
IPAddress interfaceAddress,
int ttl = 1);
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
int endPacket() override;
// Write a single byte into the packet
size_t write(uint8_t) override;
// Write size bytes from buffer into the packet
size_t write(const uint8_t *buffer, size_t size) override;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
int parsePacket() override;
// Number of bytes remaining in the current packet
int available() override;
// Read a single byte from the current packet
int read() override;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
int read(unsigned char* buffer, size_t len) override;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
int read(char* buffer, size_t len) override { return read((unsigned char*)buffer, len); };
// Return the next byte from the current packet without moving on to the next byte
int peek() override;
void flush() override; // Finish reading the current packet
using Print::write;
// Return the IP address of the host who sent the current incoming packet
IPAddress remoteIP() override;
// Return the port of the host who sent the current incoming packet
uint16_t remotePort() override;
// Return the destination address for incoming packets,
// useful to distinguish multicast and ordinary packets
IPAddress destinationIP() const;
// Return the local port for outgoing packets
uint16_t localPort() const;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
int parsePacket() override;
// Number of bytes remaining in the current packet
int available() override;
// Read a single byte from the current packet
int read() override;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
int read(unsigned char* buffer, size_t len) override;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
int read(char* buffer, size_t len) override
{
return read((unsigned char*)buffer, len);
};
// Return the next byte from the current packet without moving on to the next byte
int peek() override;
void flush() override; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
IPAddress remoteIP() override;
// Return the port of the host who sent the current incoming packet
uint16_t remotePort() override;
// Return the destination address for incoming packets,
// useful to distinguish multicast and ordinary packets
IPAddress destinationIP() const;
// Return the local port for outgoing packets
uint16_t localPort() const;
static void stopAll();
static void stopAllExcept(WiFiUDP * exC);
static void stopAll();
static void stopAllExcept(WiFiUDP * exC);
};

View File

@ -1,23 +1,23 @@
/*
ClientContext.h - TCP connection handling on top of lwIP
ClientContext.h - TCP 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.
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
version 2.1 of the License, or (at your option) any later version.
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.
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
*/
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 CLIENTCONTEXT_H
#define CLIENTCONTEXT_H
@ -31,7 +31,7 @@ extern "C" void esp_schedule();
#include "DataSource.h"
bool getDefaultPrivateGlobalSyncValue();
bool getDefaultPrivateGlobalSyncValue ();
class ClientContext
{
@ -53,8 +53,7 @@ public:
err_t abort()
{
if (_pcb)
{
if(_pcb) {
DEBUGV(":abort\r\n");
tcp_arg(_pcb, NULL);
tcp_sent(_pcb, NULL);
@ -70,8 +69,7 @@ public:
err_t close()
{
err_t err = ERR_OK;
if (_pcb)
{
if(_pcb) {
DEBUGV(":close\r\n");
tcp_arg(_pcb, NULL);
tcp_sent(_pcb, NULL);
@ -79,8 +77,7 @@ public:
tcp_err(_pcb, NULL);
tcp_poll(_pcb, NULL, 0);
err = tcp_close(_pcb);
if (err != ERR_OK)
{
if(err != ERR_OK) {
DEBUGV(":tc err %d\r\n", (int) err);
tcp_abort(_pcb);
err = ERR_ABRT;
@ -114,12 +111,10 @@ public:
void unref()
{
DEBUGV(":ur %d\r\n", _refcnt);
if (--_refcnt == 0)
{
if(--_refcnt == 0) {
discard_received();
close();
if (_discard_cb)
{
if(_discard_cb) {
_discard_cb(_discard_cb_arg, this);
}
DEBUGV(":del\r\n");
@ -130,8 +125,7 @@ public:
int connect(CONST ip_addr_t* addr, uint16_t port)
{
err_t err = tcp_connect(_pcb, addr, port, &ClientContext::_s_connected);
if (err != ERR_OK)
{
if (err != ERR_OK) {
return 0;
}
_connect_pending = 1;
@ -139,13 +133,11 @@ public:
// This delay will be interrupted by esp_schedule in the connect callback
delay(_timeout_ms);
_connect_pending = 0;
if (!_pcb)
{
if (!_pcb) {
DEBUGV(":cabrt\r\n");
return 0;
}
if (state() != ESTABLISHED)
{
if (state() != ESTABLISHED) {
DEBUGV(":ctmo\r\n");
abort();
return 0;
@ -155,29 +147,24 @@ public:
size_t availableForWrite() const
{
return _pcb ? tcp_sndbuf(_pcb) : 0;
return _pcb? tcp_sndbuf(_pcb): 0;
}
void setNoDelay(bool nodelay)
{
if (!_pcb)
{
if(!_pcb) {
return;
}
if (nodelay)
{
if(nodelay) {
tcp_nagle_disable(_pcb);
}
else
{
} else {
tcp_nagle_enable(_pcb);
}
}
bool getNoDelay() const
{
if (!_pcb)
{
if(!_pcb) {
return false;
}
return tcp_nagle_disabled(_pcb);
@ -195,8 +182,7 @@ public:
const ip_addr_t* getRemoteAddress() const
{
if (!_pcb)
{
if(!_pcb) {
return 0;
}
@ -205,8 +191,7 @@ public:
uint16_t getRemotePort() const
{
if (!_pcb)
{
if(!_pcb) {
return 0;
}
@ -215,8 +200,7 @@ public:
const ip_addr_t* getLocalAddress() const
{
if (!_pcb)
{
if(!_pcb) {
return 0;
}
@ -225,8 +209,7 @@ public:
uint16_t getLocalPort() const
{
if (!_pcb)
{
if(!_pcb) {
return 0;
}
@ -235,8 +218,7 @@ public:
size_t getSize() const
{
if (!_rx_buf)
{
if(!_rx_buf) {
return 0;
}
@ -245,8 +227,7 @@ public:
char read()
{
if (!_rx_buf)
{
if(!_rx_buf) {
return 0;
}
@ -257,8 +238,7 @@ public:
size_t read(char* dst, size_t size)
{
if (!_rx_buf)
{
if(!_rx_buf) {
return 0;
}
@ -267,8 +247,7 @@ public:
DEBUGV(":rd %d, %d, %d\r\n", size, _rx_buf->tot_len, _rx_buf_offset);
size_t size_read = 0;
while (size)
{
while(size) {
size_t buf_size = _rx_buf->len - _rx_buf_offset;
size_t copy_size = (size < buf_size) ? size : buf_size;
DEBUGV(":rdi %d, %d\r\n", buf_size, copy_size);
@ -283,8 +262,7 @@ public:
char peek() const
{
if (!_rx_buf)
{
if(!_rx_buf) {
return 0;
}
@ -293,8 +271,7 @@ public:
size_t peekBytes(char *dst, size_t size) const
{
if (!_rx_buf)
{
if(!_rx_buf) {
return 0;
}
@ -311,12 +288,10 @@ public:
void discard_received()
{
if (!_rx_buf)
{
if(!_rx_buf) {
return;
}
if (_pcb)
{
if(_pcb) {
tcp_recved(_pcb, (size_t) _rx_buf->tot_len);
}
pbuf_free(_rx_buf);
@ -331,18 +306,14 @@ public:
// option 2 / _write_some() not necessary since _datasource is always nullptr here
if (!_pcb)
{
return true;
}
int prevsndbuf = -1;
// wait for peer's acks to flush lwIP's output buffer
uint32_t last_sent = millis();
while (1)
{
if (millis() - last_sent > (uint32_t) max_wait_ms)
{
while (1) {
if (millis() - last_sent > (uint32_t) max_wait_ms) {
#ifdef DEBUGV
// wait until sent: timeout
DEBUGV(":wustmo\n");
@ -355,8 +326,7 @@ public:
tcp_output(_pcb);
int sndbuf = tcp_sndbuf(_pcb);
if (sndbuf != prevsndbuf)
{
if (sndbuf != prevsndbuf) {
// send buffer has changed (or first iteration)
prevsndbuf = sndbuf;
// We just sent a bit, move timeout forward
@ -365,8 +335,7 @@ public:
delay(0); // from sys or os context
if ((state() != ESTABLISHED) || (sndbuf == TCP_SND_BUF))
{
if ((state() != ESTABLISHED) || (sndbuf == TCP_SND_BUF)) {
break;
}
}
@ -377,8 +346,7 @@ public:
uint8_t state() const
{
if (!_pcb)
{
if(!_pcb) {
return CLOSED;
}
@ -387,8 +355,7 @@ public:
size_t write(const uint8_t* data, size_t size)
{
if (!_pcb)
{
if (!_pcb) {
return 0;
}
return _write_from_source(new BufferDataSource(data, size));
@ -396,8 +363,7 @@ public:
size_t write(Stream& stream)
{
if (!_pcb)
{
if (!_pcb) {
return 0;
}
return _write_from_source(new BufferedStreamDataSource<Stream>(stream, stream.available()));
@ -405,55 +371,51 @@ public:
size_t write_P(PGM_P buf, size_t size)
{
if (!_pcb)
{
if (!_pcb) {
return 0;
}
ProgmemStream stream(buf, size);
return _write_from_source(new BufferedStreamDataSource<ProgmemStream>(stream, size));
}
void keepAlive(uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
{
if (idle_sec && intv_sec && count)
{
if (idle_sec && intv_sec && count) {
_pcb->so_options |= SOF_KEEPALIVE;
_pcb->keep_idle = (uint32_t)1000 * idle_sec;
_pcb->keep_intvl = (uint32_t)1000 * intv_sec;
_pcb->keep_cnt = count;
}
else
{
_pcb->so_options &= ~SOF_KEEPALIVE;
}
}
bool isKeepAliveEnabled() const
bool isKeepAliveEnabled () const
{
return !!(_pcb->so_options & SOF_KEEPALIVE);
}
uint16_t getKeepAliveIdle() const
uint16_t getKeepAliveIdle () const
{
return isKeepAliveEnabled() ? (_pcb->keep_idle + 500) / 1000 : 0;
return isKeepAliveEnabled()? (_pcb->keep_idle + 500) / 1000: 0;
}
uint16_t getKeepAliveInterval() const
uint16_t getKeepAliveInterval () const
{
return isKeepAliveEnabled() ? (_pcb->keep_intvl + 500) / 1000 : 0;
return isKeepAliveEnabled()? (_pcb->keep_intvl + 500) / 1000: 0;
}
uint8_t getKeepAliveCount() const
uint8_t getKeepAliveCount () const
{
return isKeepAliveEnabled() ? _pcb->keep_cnt : 0;
return isKeepAliveEnabled()? _pcb->keep_cnt: 0;
}
bool getSync() const
bool getSync () const
{
return _sync;
}
void setSync(bool sync)
void setSync (bool sync)
{
_sync = sync;
}
@ -467,8 +429,7 @@ protected:
void _notify_error()
{
if (_connect_pending || _send_waiting)
{
if (_connect_pending || _send_waiting) {
esp_schedule();
}
}
@ -480,17 +441,13 @@ protected:
_datasource = ds;
_written = 0;
_op_start_time = millis();
do
{
if (_write_some())
{
do {
if (_write_some()) {
_op_start_time = millis();
}
if (!_datasource->available() || _is_timeout() || state() == CLOSED)
{
if (_is_timeout())
{
if (!_datasource->available() || _is_timeout() || state() == CLOSED) {
if (_is_timeout()) {
DEBUGV(":wtmo\r\n");
}
delete _datasource;
@ -500,21 +457,18 @@ protected:
++_send_waiting;
esp_yield();
} while (true);
} while(true);
_send_waiting = 0;
if (_sync)
{
wait_until_sent();
}
return _written;
}
bool _write_some()
{
if (!_datasource || !_pcb)
{
if (!_datasource || !_pcb) {
return false;
}
@ -522,17 +476,12 @@ protected:
bool has_written = false;
while (_datasource)
{
while (_datasource) {
if (state() == CLOSED)
{
return false;
}
size_t next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), _datasource->available());
if (!next_chunk_size)
{
break;
}
const uint8_t* buf = _datasource->get_buffer(next_chunk_size);
uint8_t flags = 0;
@ -542,30 +491,23 @@ protected:
// PUSH does not break Nagle
// #5173: windows needs this flag
// more info: https://lists.gnu.org/archive/html/lwip-users/2009-11/msg00018.html
{
flags |= TCP_WRITE_FLAG_MORE; // do not tcp-PuSH (yet)
}
flags |= TCP_WRITE_FLAG_MORE; // do not tcp-PuSH (yet)
if (!_sync)
// user data must be copied when data are sent but not yet acknowledged
// (with sync, we wait for acknowledgment before returning to user)
{
flags |= TCP_WRITE_FLAG_COPY;
}
err_t err = tcp_write(_pcb, buf, next_chunk_size, flags);
DEBUGV(":wrc %d %d %d\r\n", next_chunk_size, _datasource->available(), (int)err);
if (err == ERR_OK)
{
if (err == ERR_OK) {
_datasource->release_buffer(buf, next_chunk_size);
_written += next_chunk_size;
has_written = true;
}
else
{
// ERR_MEM(-1) is a valid error meaning
// "come back later". It leaves state() opened
} else {
// ERR_MEM(-1) is a valid error meaning
// "come back later". It leaves state() opened
break;
}
}
@ -583,8 +525,7 @@ protected:
void _write_some_from_cb()
{
if (_send_waiting == 1)
{
if (_send_waiting == 1) {
_send_waiting--;
esp_schedule();
}
@ -601,24 +542,17 @@ protected:
void _consume(size_t size)
{
if (_pcb)
{
if(_pcb)
tcp_recved(_pcb, size);
}
ptrdiff_t left = _rx_buf->len - _rx_buf_offset - size;
if (left > 0)
{
if(left > 0) {
_rx_buf_offset += size;
}
else if (!_rx_buf->next)
{
} else if(!_rx_buf->next) {
DEBUGV(":c0 %d, %d\r\n", size, _rx_buf->tot_len);
pbuf_free(_rx_buf);
_rx_buf = 0;
_rx_buf_offset = 0;
}
else
{
} else {
DEBUGV(":c %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf->tot_len);
auto head = _rx_buf;
_rx_buf = _rx_buf->next;
@ -632,21 +566,17 @@ protected:
{
(void) pcb;
(void) err;
if (pb == 0) // connection closed
{
if(pb == 0) { // connection closed
DEBUGV(":rcl\r\n");
_notify_error();
abort();
return ERR_ABRT;
}
if (_rx_buf)
{
if(_rx_buf) {
DEBUGV(":rch %d, %d\r\n", _rx_buf->tot_len, pb->tot_len);
pbuf_cat(_rx_buf, pb);
}
else
{
} else {
DEBUGV(":rn %d\r\n", pb->tot_len);
_rx_buf = pb;
_rx_buf_offset = 0;

View File

@ -1,14 +1,13 @@
/* DataSource.h - a read-only object similar to Stream, but with less methods
Copyright (c) 2016 Ivan Grokhotkov. All rights reserved.
This file is distributed under MIT license.
*/
/* DataSource.h - a read-only object similar to Stream, but with less methods
* Copyright (c) 2016 Ivan Grokhotkov. All rights reserved.
* This file is distributed under MIT license.
*/
#ifndef DATASOURCE_H
#define DATASOURCE_H
#include <assert.h>
class DataSource
{
class DataSource {
public:
virtual ~DataSource() {}
virtual size_t available() = 0;
@ -17,8 +16,7 @@ public:
};
class BufferDataSource : public DataSource
{
class BufferDataSource : public DataSource {
public:
BufferDataSource(const uint8_t* data, size_t size) :
_data(data),
@ -52,8 +50,7 @@ protected:
};
template<typename TStream>
class BufferedStreamDataSource : public DataSource
{
class BufferedStreamDataSource : public DataSource {
public:
BufferedStreamDataSource(TStream& stream, size_t size) :
_stream(stream),
@ -77,12 +74,10 @@ public:
const size_t min_buffer_size = size > stream_read ? size : stream_read;
//Buffer too small?
if (_bufferSize < min_buffer_size)
{
if (_bufferSize < min_buffer_size) {
uint8_t *new_buffer = new uint8_t[min_buffer_size];
//If stream reading is ahead, than some data is already in the old buffer and needs to be copied to new resized buffer
if (_buffer && stream_read > 0)
{
if (_buffer && stream_read > 0) {
memcpy(new_buffer, _buffer.get(), stream_read);
}
_buffer.reset(new_buffer);
@ -91,8 +86,7 @@ public:
//Fetch remaining data from stream
//If error in tcp_write in ClientContext::_write_some() occured earlier and therefore release_buffer was not called last time, than the requested stream data is already in the buffer.
if (size > stream_read)
{
if (size > stream_read) {
//Remaining bytes to read from stream
const size_t stream_rem = size - stream_read;
const size_t cb = _stream.readBytes(reinterpret_cast<char*>(_buffer.get() + stream_read), stream_rem);
@ -106,20 +100,18 @@ public:
void release_buffer(const uint8_t* buffer, size_t size) override
{
if (size == 0)
{
if (size == 0) {
return;
}
(void)buffer;
_pos += size;
_pos += size;
//Cannot release more than acquired through get_buffer
assert(_pos <= _streamPos);
//Release less than requested with get_buffer?
if (_pos < _streamPos)
{
if (_pos < _streamPos) {
// Move unreleased stream data in buffer to front
assert(_buffer);
memmove(_buffer.get(), _buffer.get() + size, _streamPos - _pos);

View File

@ -1,22 +1,22 @@
/*
SSLContext.h - Used by WiFiClientAxTLS
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
SSLContext.h - Used by WiFiClientAxTLS
Copyright (c) 2015 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
version 2.1 of the License, or (at your option) any later version.
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.
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
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
*/
@ -41,20 +41,16 @@ extern "C"
#include <WiFiClientSecureAxTLS.h>
#include "c_types.h"
namespace axTLS
{
namespace axTLS {
typedef struct BufferItem
{
BufferItem(const uint8_t* data_, size_t size_)
: size(size_), data(new uint8_t[size])
: size(size_), data(new uint8_t[size])
{
if (data.get() != nullptr)
{
if (data.get() != nullptr) {
memcpy(data.get(), data_, size);
}
else
{
} else {
DEBUGV(":wcs alloc %d failed\r\n", size_);
size = 0;
}
@ -72,18 +68,13 @@ public:
SSLContext(bool isServer = false)
{
_isServer = isServer;
if (!_isServer)
{
if (_ssl_client_ctx_refcnt == 0)
{
if (!_isServer) {
if (_ssl_client_ctx_refcnt == 0) {
_ssl_client_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS | SSL_CONNECT_IN_PARTS | SSL_READ_BLOCKING | SSL_NO_DEFAULT_KEY, 0);
}
++_ssl_client_ctx_refcnt;
}
else
{
if (_ssl_svr_ctx_refcnt == 0)
{
} else {
if (_ssl_svr_ctx_refcnt == 0) {
_ssl_svr_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS | SSL_CONNECT_IN_PARTS | SSL_READ_BLOCKING | SSL_NO_DEFAULT_KEY, 0);
}
++_ssl_svr_ctx_refcnt;
@ -92,26 +83,20 @@ public:
~SSLContext()
{
if (io_ctx)
{
if (io_ctx) {
io_ctx->unref();
io_ctx = nullptr;
}
_ssl = nullptr;
if (!_isServer)
{
if (!_isServer) {
--_ssl_client_ctx_refcnt;
if (_ssl_client_ctx_refcnt == 0)
{
if (_ssl_client_ctx_refcnt == 0) {
ssl_ctx_free(_ssl_client_ctx);
_ssl_client_ctx = nullptr;
}
}
else
{
} else {
--_ssl_svr_ctx_refcnt;
if (_ssl_svr_ctx_refcnt == 0)
{
if (_ssl_svr_ctx_refcnt == 0) {
ssl_ctx_free(_ssl_svr_ctx);
_ssl_svr_ctx = nullptr;
}
@ -127,11 +112,10 @@ public:
{
SSL_EXTENSIONS* ext = ssl_ext_new();
ssl_ext_set_host_name(ext, hostName);
if (_ssl)
{
/* Creating a new TLS session on top of a new TCP connection.
ssl_free will want to send a close notify alert, but the old TCP connection
is already gone at this point, so reset io_ctx. */
if (_ssl) {
/* Creating a new TLS session on top of a new TCP connection.
ssl_free will want to send a close notify alert, but the old TCP connection
is already gone at this point, so reset io_ctx. */
io_ctx = nullptr;
_ssl = nullptr;
_available = 0;
@ -147,12 +131,10 @@ public:
uint32_t t = millis();
while (millis() - t < timeout_ms && ssl_handshake_status(_ssl.get()) != SSL_OK)
{
while (millis() - t < timeout_ms && ssl_handshake_status(_ssl.get()) != SSL_OK) {
uint8_t* data;
int rc = ssl_read(_ssl.get(), &data);
if (rc < SSL_OK)
{
if (rc < SSL_OK) {
ssl_display_error(rc);
break;
}
@ -165,18 +147,16 @@ public:
ctx->ref();
// Wrap the new SSL with a smart pointer, custom deleter to call ssl_free
SSL *_new_ssl = ssl_server_new(_ssl_svr_ctx, reinterpret_cast<int>(this));
SSL *_new_ssl = ssl_server_new(_ssl_svr_ctx, reinterpret_cast<int>(this));
std::shared_ptr<SSL> _new_ssl_shared(_new_ssl, _delete_shared_SSL);
_ssl = _new_ssl_shared;
uint32_t t = millis();
while (millis() - t < timeout_ms && ssl_handshake_status(_ssl.get()) != SSL_OK)
{
while (millis() - t < timeout_ms && ssl_handshake_status(_ssl.get()) != SSL_OK) {
uint8_t* data;
int rc = ssl_read(_ssl.get(), &data);
if (rc < SSL_OK)
{
if (rc < SSL_OK) {
ssl_display_error(rc);
break;
}
@ -185,8 +165,7 @@ public:
void stop()
{
if (io_ctx)
{
if (io_ctx) {
io_ctx->unref();
}
io_ctx = nullptr;
@ -194,22 +173,17 @@ public:
bool connected()
{
if (_isServer)
{
if (_isServer) {
return _ssl != nullptr;
}
else
{
} else {
return _ssl != nullptr && ssl_handshake_status(_ssl.get()) == SSL_OK;
}
}
int read(uint8_t* dst, size_t size)
{
if (!_available)
{
if (!_readAll())
{
if (!_available) {
if (!_readAll()) {
return 0;
}
}
@ -217,12 +191,10 @@ public:
memcpy(dst, _read_ptr, will_copy);
_read_ptr += will_copy;
_available -= will_copy;
if (_available == 0)
{
if (_available == 0) {
_read_ptr = nullptr;
/* Send pending outgoing data, if any */
if (_hasWriteBuffers())
{
if (_hasWriteBuffers()) {
_writeBuffersSend();
}
}
@ -231,22 +203,18 @@ public:
int read()
{
if (!_available)
{
if (!_readAll())
{
if (!_available) {
if (!_readAll()) {
return -1;
}
}
int result = _read_ptr[0];
++_read_ptr;
--_available;
if (_available == 0)
{
if (_available == 0) {
_read_ptr = nullptr;
/* Send pending outgoing data, if any */
if (_hasWriteBuffers())
{
if (_hasWriteBuffers()) {
_writeBuffersSend();
}
}
@ -255,37 +223,30 @@ public:
int write(const uint8_t* src, size_t size)
{
if (_isServer)
{
if (_isServer) {
return _write(src, size);
}
else if (!_available)
{
if (_hasWriteBuffers())
{
} else if (!_available) {
if (_hasWriteBuffers()) {
int rc = _writeBuffersSend();
if (rc < 0)
{
if (rc < 0) {
return rc;
}
}
return _write(src, size);
}
/* Some received data is still present in the axtls fragment buffer.
We can't call ssl_write now, as that will overwrite the contents of
the fragment buffer, corrupting the received data.
Save a copy of the outgoing data, and call ssl_write when all
recevied data has been consumed by the application.
/* Some received data is still present in the axtls fragment buffer.
We can't call ssl_write now, as that will overwrite the contents of
the fragment buffer, corrupting the received data.
Save a copy of the outgoing data, and call ssl_write when all
recevied data has been consumed by the application.
*/
return _writeBufferAdd(src, size);
}
int peek()
{
if (!_available)
{
if (!_readAll())
{
if (!_available) {
if (!_readAll()) {
return -1;
}
}
@ -294,10 +255,8 @@ public:
size_t peekBytes(char *dst, size_t size)
{
if (!_available)
{
if (!_readAll())
{
if (!_available) {
if (!_readAll()) {
return -1;
}
}
@ -310,12 +269,9 @@ public:
int available()
{
auto cb = _available;
if (cb == 0)
{
if (cb == 0) {
cb = _readAll();
}
else
{
} else {
optimistic_yield(100);
}
return cb;
@ -330,15 +286,13 @@ public:
bool loadObject(int type, Stream& stream, size_t size)
{
std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
if (!buf.get())
{
if (!buf.get()) {
DEBUGV("loadObject: failed to allocate memory\n");
return false;
}
size_t cb = stream.readBytes(buf.get(), size);
if (cb != size)
{
if (cb != size) {
DEBUGV("loadObject: reading %u bytes, got %u\n", size, cb);
return false;
}
@ -349,15 +303,14 @@ public:
bool loadObject_P(int type, PGM_VOID_P data, size_t size)
{
std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
memcpy_P(buf.get(), data, size);
memcpy_P(buf.get(),data, size);
return loadObject(type, buf.get(), size);
}
bool loadObject(int type, const uint8_t* data, size_t size)
{
int rc = ssl_obj_memory_load(_isServer ? _ssl_svr_ctx : _ssl_client_ctx, type, data, static_cast<int>(size), nullptr);
if (rc != SSL_OK)
{
int rc = ssl_obj_memory_load(_isServer?_ssl_svr_ctx:_ssl_client_ctx, type, data, static_cast<int>(size), nullptr);
if (rc != SSL_OK) {
DEBUGV("loadObject: ssl_obj_memory_load returned %d\n", rc);
return false;
}
@ -367,13 +320,10 @@ public:
bool verifyCert()
{
int rc = ssl_verify_cert(_ssl.get());
if (_allowSelfSignedCerts && rc == SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED))
{
if (_allowSelfSignedCerts && rc == SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED)) {
DEBUGV("Allowing self-signed certificate\n");
return true;
}
else if (rc != SSL_OK)
{
} else if (rc != SSL_OK) {
DEBUGV("ssl_verify_cert returned %d\n", rc);
ssl_display_error(rc);
return false;
@ -393,8 +343,7 @@ public:
static ClientContext* getIOContext(int fd)
{
if (fd)
{
if (fd) {
SSLContext *thisSSL = reinterpret_cast<SSLContext*>(fd);
return thisSSL->io_ctx;
}
@ -404,8 +353,7 @@ public:
protected:
int _readAll()
{
if (!_ssl)
{
if (!_ssl) {
return 0;
}
@ -413,10 +361,8 @@ protected:
uint8_t* data;
int rc = ssl_read(_ssl.get(), &data);
if (rc <= 0)
{
if (rc < SSL_OK && rc != SSL_CLOSE_NOTIFY && rc != SSL_ERROR_CONN_LOST)
{
if (rc <= 0) {
if (rc < SSL_OK && rc != SSL_CLOSE_NOTIFY && rc != SSL_ERROR_CONN_LOST) {
_ssl = nullptr;
}
return 0;
@ -429,14 +375,12 @@ protected:
int _write(const uint8_t* src, size_t size)
{
if (!_ssl)
{
if (!_ssl) {
return 0;
}
int rc = ssl_write(_ssl.get(), src, size);
if (rc >= 0)
{
if (rc >= 0) {
return rc;
}
DEBUGV(":wcs write rc=%d\r\n", rc);
@ -445,14 +389,12 @@ protected:
int _writeBufferAdd(const uint8_t* data, size_t size)
{
if (!_ssl)
{
if (!_ssl) {
return 0;
}
_writeBuffers.emplace_back(data, size);
if (_writeBuffers.back().data.get() == nullptr)
{
if (_writeBuffers.back().data.get() == nullptr) {
_writeBuffers.pop_back();
return 0;
}
@ -461,15 +403,12 @@ protected:
int _writeBuffersSend()
{
while (!_writeBuffers.empty())
{
while (!_writeBuffers.empty()) {
auto& first = _writeBuffers.front();
int rc = _write(first.data.get(), first.size);
_writeBuffers.pop_front();
if (rc < 0)
{
if (_hasWriteBuffers())
{
if (rc < 0) {
if (_hasWriteBuffers()) {
DEBUGV(":wcs _writeBuffersSend dropping unsent data\r\n");
_writeBuffers.clear();
}

View File

@ -1,22 +1,22 @@
/*
UdpContext.h - UDP connection handling on top of lwIP
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.
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
version 2.1 of the License, or (at your option) any later version.
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.
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
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 UDPCONTEXT_H
#define UDPCONTEXT_H
@ -24,8 +24,8 @@
class UdpContext;
extern "C" {
void esp_yield();
void esp_schedule();
void esp_yield();
void esp_schedule();
#include "lwip/init.h" // LWIP_VERSION_
#include <assert.h>
}
@ -42,14 +42,14 @@ public:
typedef std::function<void(void)> rxhandler_t;
UdpContext()
: _pcb(0)
, _rx_buf(0)
, _first_buf_taken(false)
, _rx_buf_offset(0)
, _refcnt(0)
, _tx_buf_head(0)
, _tx_buf_cur(0)
, _tx_buf_offset(0)
: _pcb(0)
, _rx_buf(0)
, _first_buf_taken(false)
, _rx_buf_offset(0)
, _refcnt(0)
, _tx_buf_head(0)
, _tx_buf_cur(0)
, _tx_buf_offset(0)
{
_pcb = udp_new();
#ifdef LWIP_MAYBE_XCC
@ -83,11 +83,9 @@ public:
void unref()
{
if (this != 0)
{
if(this != 0) {
DEBUGV(":ur %d\r\n", _refcnt);
if (--_refcnt == 0)
{
if(--_refcnt == 0) {
delete this;
}
}
@ -144,7 +142,7 @@ public:
if (!addr.isV4())
{
for (auto a : addrList)
for (auto a: addrList)
if (a.addr() == addr)
{
// found the IPv6 address,
@ -181,17 +179,14 @@ public:
// warning: handler is called from tcp stack context
// esp_yield and non-reentrant functions which depend on it will fail
void onRx(rxhandler_t handler)
{
void onRx(rxhandler_t handler) {
_on_rx = handler;
}
size_t getSize() const
{
if (!_rx_buf)
{
return 0;
}
return _rx_buf->len - _rx_buf_offset;
}
@ -207,8 +202,7 @@ public:
_rx_buf_offset = pos;
}
bool isValidOffset(const size_t pos) const
{
bool isValidOffset(const size_t pos) const {
return (pos <= _rx_buf->len);
}
@ -230,18 +224,14 @@ public:
uint16_t getLocalPort() const
{
if (!_pcb)
{
return 0;
}
return _pcb->local_port;
}
bool next()
{
if (!_rx_buf)
{
return false;
}
if (!_first_buf_taken)
{
_first_buf_taken = true;
@ -282,9 +272,7 @@ public:
int read()
{
if (!_rx_buf || _rx_buf_offset >= _rx_buf->len)
{
return -1;
}
char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
_consume(1);
@ -294,9 +282,7 @@ public:
size_t read(char* dst, size_t size)
{
if (!_rx_buf)
{
return 0;
}
size_t max_size = _rx_buf->len - _rx_buf_offset;
size = (size < max_size) ? size : max_size;
@ -311,9 +297,7 @@ public:
int peek() const
{
if (!_rx_buf || _rx_buf_offset == _rx_buf->len)
{
return -1;
}
return reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
}
@ -322,9 +306,7 @@ public:
{
//XXX this does not follow Arduino's flush definition
if (!_rx_buf)
{
return;
}
_consume(_rx_buf->len - _rx_buf_offset);
}
@ -342,7 +324,7 @@ public:
}
size_t left_to_copy = size;
while (left_to_copy)
while(left_to_copy)
{
// size already used in current pbuf
size_t used_cur = _tx_buf_offset - (_tx_buf_head->tot_len - _tx_buf_cur->tot_len);
@ -365,15 +347,12 @@ public:
{
size_t data_size = _tx_buf_offset;
pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM);
if (!tx_copy)
{
if(!tx_copy){
DEBUGV("failed pbuf_alloc");
}
else
{
else{
uint8_t* dst = reinterpret_cast<uint8_t*>(tx_copy->payload);
for (pbuf* p = _tx_buf_head; p; p = p->next)
{
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;
@ -381,33 +360,27 @@ public:
}
}
if (_tx_buf_head)
{
pbuf_free(_tx_buf_head);
}
_tx_buf_head = 0;
_tx_buf_cur = 0;
_tx_buf_offset = 0;
if (!tx_copy)
{
if(!tx_copy){
return false;
}
if (!addr)
{
if (!addr) {
addr = &_pcb->remote_ip;
port = _pcb->remote_port;
}
#ifdef LWIP_MAYBE_XCC
uint16_t old_ttl = _pcb->ttl;
if (ip_addr_ismulticast(addr))
{
if (ip_addr_ismulticast(addr)) {
_pcb->ttl = _mcast_ttl;
}
#endif
err_t err = udp_sendto(_pcb, tx_copy, addr, port);
if (err != ERR_OK)
{
if (err != ERR_OK) {
DEBUGV(":ust rc=%d\r\n", (int) err);
}
#ifdef LWIP_MAYBE_XCC
@ -435,13 +408,11 @@ private:
size_t cur_size = _tx_buf_head->tot_len;
if (size < cur_size)
{
return;
}
size_t grow_size = size - cur_size;
while (grow_size)
while(grow_size)
{
pbuf* pb = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM);
if (!pb)
@ -450,9 +421,7 @@ private:
}
pbuf_cat(_tx_buf_head, pb);
if (grow_size < pbuf_unit_size)
{
return;
}
grow_size -= pbuf_unit_size;
}
}
@ -460,21 +429,20 @@ private:
void _consume(size_t size)
{
_rx_buf_offset += size;
if (_rx_buf_offset > _rx_buf->len)
{
if (_rx_buf_offset > _rx_buf->len) {
_rx_buf_offset = _rx_buf->len;
}
}
void _recv(udp_pcb *upcb, pbuf *pb,
const ip_addr_t *srcaddr, u16_t srcport)
const ip_addr_t *srcaddr, u16_t srcport)
{
(void) upcb;
#if LWIP_VERSION_MAJOR == 1
#define TEMPDSTADDR (&current_iphdr_dest)
#define TEMPDSTADDR (&current_iphdr_dest)
#else
#define TEMPDSTADDR (ip_current_dest_addr())
#define TEMPDSTADDR (ip_current_dest_addr())
#endif
// chain this helper pbuf first
@ -502,7 +470,7 @@ private:
return;
}
// construct in place
new (PBUF_ALIGNER(pb_helper->payload)) AddrHelper(srcaddr, TEMPDSTADDR, srcport);
new(PBUF_ALIGNER(pb_helper->payload)) AddrHelper(srcaddr, TEMPDSTADDR, srcport);
// chain it
pbuf_cat(_rx_buf, pb_helper);
@ -522,18 +490,17 @@ private:
_rx_buf_offset = 0;
}
if (_on_rx)
{
if (_on_rx) {
_on_rx();
}
#undef TEMPDSTADDR
#undef TEMPDSTADDR
}
static void _s_recv(void *arg,
udp_pcb *upcb, pbuf *p,
CONST ip_addr_t *srcaddr, u16_t srcport)
udp_pcb *upcb, pbuf *p,
CONST ip_addr_t *srcaddr, u16_t srcport)
{
reinterpret_cast<UdpContext*>(arg)->_recv(upcb, p, srcaddr, srcport);
}

View File

@ -2,42 +2,36 @@
#define SLIST_H
template<typename T>
class SList
{
class SList {
public:
SList() : _next(0) { }
SList() : _next(0) { }
protected:
static void _add(T* self)
{
T* tmp = _s_first;
_s_first = self;
self->_next = tmp;
static void _add(T* self) {
T* tmp = _s_first;
_s_first = self;
self->_next = tmp;
}
static void _remove(T* self) {
if (_s_first == self) {
_s_first = self->_next;
self->_next = 0;
return;
}
static void _remove(T* self)
{
if (_s_first == self)
{
_s_first = self->_next;
self->_next = 0;
return;
}
for (T* prev = _s_first; prev->_next; prev = prev->_next)
{
if (prev->_next == self)
{
prev->_next = self->_next;
self->_next = 0;
return;
}
}
for (T* prev = _s_first; prev->_next; prev = prev->_next) {
if (prev->_next == self) {
prev->_next = self->_next;
self->_next = 0;
return;
}
}
}
static T* _s_first;
T* _next;
static T* _s_first;
T* _next;
};

View File

@ -1,65 +1,65 @@
/*
Copyright (c) 2007-2016, Cameron Rich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Copyright (c) 2007-2016, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* * 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.
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/**
@mainpage axTLS API
@image html axolotl.jpg
The axTLS library has features such as:
- The TLSv1 SSL client/server protocol
- No requirement to use any openssl libraries.
- A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers.
- RSA encryption/decryption with variable sized keys (up to 4096 bits).
- Certificate chaining and peer authentication.
- Session resumption, session renegotiation.
- ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding.
- Highly configurable compile time options.
- Portable across many platforms (written in ANSI C), and has language
bindings in C, C#, VB.NET, Java, Perl and Lua.
- Partial openssl API compatibility (via a wrapper).
- A very small footprint (around 50-60kB for the library in 'server-only'
mode).
- No dependencies on sockets - can use serial connections for example.
- A very simple API - ~ 20 functions/methods.
A list of these functions/methods are described below.
@ref c_api
@ref bigint_api
@ref csharp_api
@ref java_api
*/
* @mainpage axTLS API
*
* @image html axolotl.jpg
*
* The axTLS library has features such as:
* - The TLSv1 SSL client/server protocol
* - No requirement to use any openssl libraries.
* - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers.
* - RSA encryption/decryption with variable sized keys (up to 4096 bits).
* - Certificate chaining and peer authentication.
* - Session resumption, session renegotiation.
* - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding.
* - Highly configurable compile time options.
* - Portable across many platforms (written in ANSI C), and has language
* bindings in C, C#, VB.NET, Java, Perl and Lua.
* - Partial openssl API compatibility (via a wrapper).
* - A very small footprint (around 50-60kB for the library in 'server-only'
* mode).
* - No dependencies on sockets - can use serial connections for example.
* - A very simple API - ~ 20 functions/methods.
*
* A list of these functions/methods are described below.
*
* @ref c_api
*
* @ref bigint_api
*
* @ref csharp_api
*
* @ref java_api
*/
#ifndef HEADER_SSL_H
#define HEADER_SSL_H
@ -187,391 +187,391 @@ typedef struct SSL_EXTENSIONS_ SSL_EXTENSIONS;
#define SSL_OBJ_PKCS12 5
/**
@defgroup c_api Standard C API
@brief The standard interface in C.
@{
*/
* @defgroup c_api Standard C API
* @brief The standard interface in C.
* @{
*/
/**
@brief Establish a new client/server context.
This function is called before any client/server SSL connections are made.
Each new connection will use the this context's private key and
certificate chain. If a different certificate chain is required, then a
different context needs to be be used.
There are two threading models supported - a single thread with one
SSL_CTX can support any number of SSL connections - and multiple threads can
support one SSL_CTX object each (the default). But if a single SSL_CTX
object uses many SSL objects in individual threads, then the
CONFIG_SSL_CTX_MUTEXING option needs to be configured.
@param options [in] Any particular options. At present the options
supported are:
- SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server
authentication fails. The certificate can be authenticated later with a
call to ssl_verify_cert().
- SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication
i.e. each handshake will include a "certificate request" message from the
server. Only available if verification has been enabled.
- SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences
during the handshake.
- SSL_DISPLAY_STATES (full mode build only): Display the state changes
during the handshake.
- SSL_DISPLAY_CERTS (full mode build only): Display the certificates that
are passed during a handshake.
- SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that
are passed during a handshake.
- SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of
ssl_client_new().
@param num_sessions [in] The number of sessions to be used for session
caching. If this value is 0, then there is no session caching. This option
is not used in skeleton mode.
@return A client/server context.
*/
* @brief Establish a new client/server context.
*
* This function is called before any client/server SSL connections are made.
*
* Each new connection will use the this context's private key and
* certificate chain. If a different certificate chain is required, then a
* different context needs to be be used.
*
* There are two threading models supported - a single thread with one
* SSL_CTX can support any number of SSL connections - and multiple threads can
* support one SSL_CTX object each (the default). But if a single SSL_CTX
* object uses many SSL objects in individual threads, then the
* CONFIG_SSL_CTX_MUTEXING option needs to be configured.
*
* @param options [in] Any particular options. At present the options
* supported are:
* - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server
* authentication fails. The certificate can be authenticated later with a
* call to ssl_verify_cert().
* - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication
* i.e. each handshake will include a "certificate request" message from the
* server. Only available if verification has been enabled.
* - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences
* during the handshake.
* - SSL_DISPLAY_STATES (full mode build only): Display the state changes
* during the handshake.
* - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that
* are passed during a handshake.
* - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that
* are passed during a handshake.
* - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of
* ssl_client_new().
* @param num_sessions [in] The number of sessions to be used for session
* caching. If this value is 0, then there is no session caching. This option
* is not used in skeleton mode.
* @return A client/server context.
*/
EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions);
/**
@brief Remove a client/server context.
Frees any used resources used by this context. Each connection will be
sent a "Close Notify" alert (if possible).
@param ssl_ctx [in] The client/server context.
*/
* @brief Remove a client/server context.
*
* Frees any used resources used by this context. Each connection will be
* sent a "Close Notify" alert (if possible).
* @param ssl_ctx [in] The client/server context.
*/
EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx);
/**
@brief Allocates new SSL extensions structure and returns pointer to it
@return ssl_ext Pointer to SSL_EXTENSIONS structure
*/
* @brief Allocates new SSL extensions structure and returns pointer to it
*
* @return ssl_ext Pointer to SSL_EXTENSIONS structure
*
*/
EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new();
/**
@brief Set the host name for SNI extension
@param ssl_ext pointer returned by ssl_ext_new
@param host_name pointer to a zero-terminated string containing host name
*/
* @brief Set the host name for SNI extension
* @param ssl_ext pointer returned by ssl_ext_new
* @param host_name pointer to a zero-terminated string containing host name
*/
EXP_FUNC void STDCALL ssl_ext_set_host_name(SSL_EXTENSIONS * ext, const char* host_name);
/**
@brief Set the maximum fragment size for the fragment size negotiation extension
@param ssl_ext pointer returned by ssl_ext_new
@param fragment_size fragment size, allowed values: 2^9, 2^10 ... 2^14
*/
* @brief Set the maximum fragment size for the fragment size negotiation extension
* @param ssl_ext pointer returned by ssl_ext_new
* @param fragment_size fragment size, allowed values: 2^9, 2^10 ... 2^14
*/
EXP_FUNC void STDCALL ssl_ext_set_max_fragment_size(SSL_EXTENSIONS * ext, unsigned fragment_size);
/**
@brief Frees SSL extensions structure
@param ssl_ext [in] Pointer to SSL_EXTENSION structure
*/
* @brief Frees SSL extensions structure
*
* @param ssl_ext [in] Pointer to SSL_EXTENSION structure
*
*/
EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext);
/**
@brief (server only) Establish a new SSL connection to an SSL client.
It is up to the application to establish the logical connection (whether it
is a socket, serial connection etc).
@param ssl_ctx [in] The server context.
@param client_fd [in] The client's file descriptor.
@return An SSL object reference.
*/
* @brief (server only) Establish a new SSL connection to an SSL client.
*
* It is up to the application to establish the logical connection (whether it
* is a socket, serial connection etc).
* @param ssl_ctx [in] The server context.
* @param client_fd [in] The client's file descriptor.
* @return An SSL object reference.
*/
EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
/**
@brief (client only) Establish a new SSL connection to an SSL server.
It is up to the application to establish the initial logical connection
(whether it is a socket, serial connection etc).
This is a normally a blocking call - it will finish when the handshake is
complete (or has failed). To use in non-blocking mode, set
SSL_CONNECT_IN_PARTS in ssl_ctx_new().
@param ssl_ctx [in] The client context.
@param client_fd [in] The client's file descriptor.
@param session_id [in] A 32 byte session id for session resumption. This
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 ssl_ext pointer to a structure with the activated SSL extensions and their values
@return An SSL object reference. Use ssl_handshake_status() to check
if a handshake succeeded.
*/
* @brief (client only) Establish a new SSL connection to an SSL server.
*
* It is up to the application to establish the initial logical connection
* (whether it is a socket, serial connection etc).
*
* This is a normally a blocking call - it will finish when the handshake is
* complete (or has failed). To use in non-blocking mode, set
* SSL_CONNECT_IN_PARTS in ssl_ctx_new().
* @param ssl_ctx [in] The client context.
* @param client_fd [in] The client's file descriptor.
* @param session_id [in] A 32 byte session id for session resumption. This
* 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 ssl_ext pointer to a structure with the activated SSL extensions and their values
* @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, SSL_EXTENSIONS* ssl_ext);
/**
@brief Free any used resources on this connection.
* @brief Free any used resources on this connection.
A "Close Notify" message is sent on this connection (if possible). It is up
to the application to close the socket or file descriptor.
@param ssl [in] The ssl object reference.
*/
* A "Close Notify" message is sent on this connection (if possible). It is up
* to the application to close the socket or file descriptor.
* @param ssl [in] The ssl object reference.
*/
EXP_FUNC void STDCALL ssl_free(SSL *ssl);
/**
@brief Read the SSL data stream.
If the socket is non-blocking and data is blocked then SSO_OK will be
returned.
@param ssl [in] An SSL object reference.
@param in_data [out] If the read was successful, a pointer to the read
buffer will be here. Do NOT ever free this memory as this buffer is used in
sucessive calls. If the call was unsuccessful, this value will be null.
@return The number of decrypted bytes:
- if > 0, then the handshaking is complete and we are returning the number
of decrypted bytes.
- SSL_OK if the handshaking stage is successful (but not yet complete).
- < 0 if an error.
@see ssl.h for the error code list.
@note Use in_data before doing any successive ssl calls.
*/
* @brief Read the SSL data stream.
* If the socket is non-blocking and data is blocked then SSO_OK will be
* returned.
* @param ssl [in] An SSL object reference.
* @param in_data [out] If the read was successful, a pointer to the read
* buffer will be here. Do NOT ever free this memory as this buffer is used in
* sucessive calls. If the call was unsuccessful, this value will be null.
* @return The number of decrypted bytes:
* - if > 0, then the handshaking is complete and we are returning the number
* of decrypted bytes.
* - SSL_OK if the handshaking stage is successful (but not yet complete).
* - < 0 if an error.
* @see ssl.h for the error code list.
* @note Use in_data before doing any successive ssl calls.
*/
EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data);
/**
@brief Write to the SSL data stream.
if the socket is non-blocking and data is blocked then a check is made
to ensure that all data is sent (i.e. blocked mode is forced).
@param ssl [in] An SSL obect reference.
@param out_data [in] The data to be written
@param out_len [in] The number of bytes to be written.
@return The number of bytes sent, or if < 0 if an error.
@see ssl.h for the error code list.
*/
* @brief Write to the SSL data stream.
* if the socket is non-blocking and data is blocked then a check is made
* to ensure that all data is sent (i.e. blocked mode is forced).
* @param ssl [in] An SSL obect reference.
* @param out_data [in] The data to be written
* @param out_len [in] The number of bytes to be written.
* @return The number of bytes sent, or if < 0 if an error.
* @see ssl.h for the error code list.
*/
EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len);
/**
@brief Calculate the size of the encrypted data from what you are about to send
@param ssl [in] An SSL obect reference.
@param out_len [in] The number of bytes to be written.
@return The number of bytes that will be sent, or if < 0 if an error.
@see ssl.h for the error code list.
*/
* @brief Calculate the size of the encrypted data from what you are about to send
* @param ssl [in] An SSL obect reference.
* @param out_len [in] The number of bytes to be written.
* @return The number of bytes that will be sent, or if < 0 if an error.
* @see ssl.h for the error code list.
*/
EXP_FUNC int STDCALL ssl_calculate_write_length(SSL *ssl, int out_len);
/**
@brief Find an ssl object based on a file descriptor.
Goes through the list of SSL objects maintained in a client/server context
to look for a file descriptor match.
@param ssl_ctx [in] The client/server context.
@param client_fd [in] The file descriptor.
@return A reference to the SSL object. Returns null if the object could not
be found.
*/
* @brief Find an ssl object based on a file descriptor.
*
* Goes through the list of SSL objects maintained in a client/server context
* to look for a file descriptor match.
* @param ssl_ctx [in] The client/server context.
* @param client_fd [in] The file descriptor.
* @return A reference to the SSL object. Returns null if the object could not
* be found.
*/
EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd);
/**
@brief Get the session id for a handshake.
This will be a 32 byte sequence and is available after the first
handshaking messages are sent.
@param ssl [in] An SSL object reference.
@return The session id as a 32 byte sequence.
@note A SSLv23 handshake may have only 16 valid bytes.
*/
* @brief Get the session id for a handshake.
*
* This will be a 32 byte sequence and is available after the first
* handshaking messages are sent.
* @param ssl [in] An SSL object reference.
* @return The session id as a 32 byte sequence.
* @note A SSLv23 handshake may have only 16 valid bytes.
*/
EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl);
/**
@brief Get the session id size for a handshake.
This will normally be 32 but could be 0 (no session id) or something else.
@param ssl [in] An SSL object reference.
@return The size of the session id.
*/
* @brief Get the session id size for a handshake.
*
* This will normally be 32 but could be 0 (no session id) or something else.
* @param ssl [in] An SSL object reference.
* @return The size of the session id.
*/
EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl);
/**
@brief Return the cipher id (in the SSL form).
@param ssl [in] An SSL object reference.
@return The cipher id. This will be one of the following:
- SSL_AES128_SHA (0x2f)
- SSL_AES256_SHA (0x35)
- SSL_RC4_128_SHA (0x05)
- SSL_RC4_128_MD5 (0x04)
*/
* @brief Return the cipher id (in the SSL form).
* @param ssl [in] An SSL object reference.
* @return The cipher id. This will be one of the following:
* - SSL_AES128_SHA (0x2f)
* - SSL_AES256_SHA (0x35)
* - SSL_RC4_128_SHA (0x05)
* - SSL_RC4_128_MD5 (0x04)
*/
EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl);
/**
@brief Return the status of the handshake.
@param ssl [in] An SSL object reference.
@return SSL_OK if the handshake is complete and ok.
@see ssl.h for the error code list.
*/
* @brief Return the status of the handshake.
* @param ssl [in] An SSL object reference.
* @return SSL_OK if the handshake is complete and ok.
* @see ssl.h for the error code list.
*/
EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl);
/**
@brief Retrieve various parameters about the axTLS engine.
@param offset [in] The configuration offset. It will be one of the following:
- SSL_BUILD_MODE The build mode. This will be one of the following:
- SSL_BUILD_SERVER_ONLY (basic server mode)
- SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication)
- SSL_BUILD_ENABLE_CLIENT (client/server capabilties)
- SSL_BUILD_FULL_MODE (client/server with diagnostics)
- SSL_BUILD_SKELETON_MODE (skeleton mode)
- SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed.
- SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed.
- SSL_HAS_PEM 1 if supported
@return The value of the requested parameter.
*/
* @brief Retrieve various parameters about the axTLS engine.
* @param offset [in] The configuration offset. It will be one of the following:
* - SSL_BUILD_MODE The build mode. This will be one of the following:
* - SSL_BUILD_SERVER_ONLY (basic server mode)
* - SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication)
* - SSL_BUILD_ENABLE_CLIENT (client/server capabilties)
* - SSL_BUILD_FULL_MODE (client/server with diagnostics)
* - SSL_BUILD_SKELETON_MODE (skeleton mode)
* - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed.
* - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed.
* - SSL_HAS_PEM 1 if supported
* @return The value of the requested parameter.
*/
EXP_FUNC int STDCALL ssl_get_config(int offset);
/**
@brief Display why the handshake failed.
This call is only useful in a 'full mode' build. The output is to stdout.
@param error_code [in] An error code.
@see ssl.h for the error code list.
*/
* @brief Display why the handshake failed.
*
* This call is only useful in a 'full mode' build. The output is to stdout.
* @param error_code [in] An error code.
* @see ssl.h for the error code list.
*/
EXP_FUNC void STDCALL ssl_display_error(int error_code);
/**
@brief Authenticate a received certificate.
This call is usually made by a client after a handshake is complete and the
context is in SSL_SERVER_VERIFY_LATER mode.
@param ssl [in] An SSL object reference.
@return SSL_OK if the certificate is verified.
*/
* @brief Authenticate a received certificate.
*
* This call is usually made by a client after a handshake is complete and the
* context is in SSL_SERVER_VERIFY_LATER mode.
* @param ssl [in] An SSL object reference.
* @return SSL_OK if the certificate is verified.
*/
EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
/**
@brief Check if certificate fingerprint (SHA1) matches the one given.
@param ssl [in] An SSL object reference.
@param fp [in] SHA1 fingerprint to match against
@return SSL_OK if the certificate is verified.
*/
* @brief Check if certificate fingerprint (SHA1) matches the one given.
*
* @param ssl [in] An SSL object reference.
* @param fp [in] SHA1 fingerprint to match against
* @return SSL_OK if the certificate is verified.
*/
EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp);
/**
@brief Check if SHA256 hash of Subject Public Key Info matches the one given.
@param ssl [in] An SSL object reference.
@param fp [in] SHA256 hash to match against
@return SSL_OK if the certificate is verified.
*/
* @brief Check if SHA256 hash of Subject Public Key Info matches the one given.
*
* @param ssl [in] An SSL object reference.
* @param fp [in] SHA256 hash to match against
* @return SSL_OK if the certificate is verified.
*/
EXP_FUNC int STDCALL ssl_match_spki_sha256(const SSL *ssl, const uint8_t* hash);
/**
@brief Retrieve an X.509 distinguished name component.
When a handshake is complete and a certificate has been exchanged, then the
details of the remote certificate can be retrieved.
This will usually be used by a client to check that the server's common
name matches the URL.
@param ssl [in] An SSL object reference.
@param component [in] one of:
- SSL_X509_CERT_COMMON_NAME
- SSL_X509_CERT_ORGANIZATION
- SSL_X509_CERT_ORGANIZATIONAL_NAME
- SSL_X509_CA_CERT_COMMON_NAME
- SSL_X509_CA_CERT_ORGANIZATION
- SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
@return The appropriate string (or null if not defined)
@note Verification build mode must be enabled.
*/
* @brief Retrieve an X.509 distinguished name component.
*
* When a handshake is complete and a certificate has been exchanged, then the
* details of the remote certificate can be retrieved.
*
* This will usually be used by a client to check that the server's common
* name matches the URL.
*
* @param ssl [in] An SSL object reference.
* @param component [in] one of:
* - SSL_X509_CERT_COMMON_NAME
* - SSL_X509_CERT_ORGANIZATION
* - SSL_X509_CERT_ORGANIZATIONAL_NAME
* - SSL_X509_CA_CERT_COMMON_NAME
* - SSL_X509_CA_CERT_ORGANIZATION
* - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
* @return The appropriate string (or null if not defined)
* @note Verification build mode must be enabled.
*/
EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component);
/**
@brief Retrieve a Subject Alternative DNSName
When a handshake is complete and a certificate has been exchanged, then the
details of the remote certificate can be retrieved.
This will usually be used by a client to check that the server's DNS
name matches the URL.
@param ssl [in] An SSL object reference.
@param dnsindex [in] The index of the DNS name to retrieve.
@return The appropriate string (or null if not defined)
@note Verification build mode must be enabled.
*/
* @brief Retrieve a Subject Alternative DNSName
*
* When a handshake is complete and a certificate has been exchanged, then the
* details of the remote certificate can be retrieved.
*
* This will usually be used by a client to check that the server's DNS
* name matches the URL.
*
* @param ssl [in] An SSL object reference.
* @param dnsindex [in] The index of the DNS name to retrieve.
* @return The appropriate string (or null if not defined)
* @note Verification build mode must be enabled.
*/
EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex);
/**
@brief Force the client to perform its handshake again.
For a client this involves sending another "client hello" message.
For the server is means sending a "hello request" message.
This is a blocking call on the client (until the handshake completes).
@param ssl [in] An SSL object reference.
@return SSL_OK if renegotiation instantiation was ok
*/
* @brief Force the client to perform its handshake again.
*
* For a client this involves sending another "client hello" message.
* For the server is means sending a "hello request" message.
*
* This is a blocking call on the client (until the handshake completes).
*
* @param ssl [in] An SSL object reference.
* @return SSL_OK if renegotiation instantiation was ok
*/
EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl);
/**
@brief Process a file that is in binary DER or ASCII PEM format.
These are temporary objects that are used to load private keys,
certificates etc into memory.
@param ssl_ctx [in] The client/server context.
@param obj_type [in] The format of the file. Can be one of:
- SSL_OBJ_X509_CERT (no password required)
- SSL_OBJ_X509_CACERT (no password required)
- SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
- SSL_OBJ_PKCS8 (RC4-128 encrypted data supported)
- SSL_OBJ_PKCS12 (RC4-128 encrypted data supported)
PEM files are automatically detected (if supported). The object type is
also detected, and so is not relevant for these types of files.
@param filename [in] The location of a file in DER/PEM format.
@param password [in] The password used. Can be null if not required.
@return SSL_OK if all ok
@note Not available in skeleton build mode.
*/
* @brief Process a file that is in binary DER or ASCII PEM format.
*
* These are temporary objects that are used to load private keys,
* certificates etc into memory.
* @param ssl_ctx [in] The client/server context.
* @param obj_type [in] The format of the file. Can be one of:
* - SSL_OBJ_X509_CERT (no password required)
* - SSL_OBJ_X509_CACERT (no password required)
* - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
* - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported)
* - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported)
*
* PEM files are automatically detected (if supported). The object type is
* also detected, and so is not relevant for these types of files.
* @param filename [in] The location of a file in DER/PEM format.
* @param password [in] The password used. Can be null if not required.
* @return SSL_OK if all ok
* @note Not available in skeleton build mode.
*/
EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password);
/**
@brief Process binary data.
These are temporary objects that are used to load private keys,
certificates etc into memory.
@param ssl_ctx [in] The client/server context.
@param obj_type [in] The format of the memory data.
@param data [in] The binary data to be loaded.
@param len [in] The amount of data to be loaded.
@param password [in] The password used. Can be null if not required.
@return SSL_OK if all ok
@see ssl_obj_load for more details on obj_type.
*/
* @brief Process binary data.
*
* These are temporary objects that are used to load private keys,
* certificates etc into memory.
* @param ssl_ctx [in] The client/server context.
* @param obj_type [in] The format of the memory data.
* @param data [in] The binary data to be loaded.
* @param len [in] The amount of data to be loaded.
* @param password [in] The password used. Can be null if not required.
* @return SSL_OK if all ok
* @see ssl_obj_load for more details on obj_type.
*/
EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password);
#ifdef CONFIG_SSL_GENERATE_X509_CERT
/**
@brief Create an X.509 certificate.
This certificate is a self-signed v1 cert with a fixed start/stop validity
times. It is signed with an internal private key in ssl_ctx.
@param ssl_ctx [in] The client/server context.
@param options [in] Not used yet.
@param dn [in] An array of distinguished name strings. The array is defined
by:
- SSL_X509_CERT_COMMON_NAME (0)
- If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the
hostname will be used.
- SSL_X509_CERT_ORGANIZATION (1)
- If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME
will be used.
- SSL_X509_CERT_ORGANIZATIONAL_NAME (2)
- SSL_X509_CERT_ORGANIZATIONAL_NAME is optional.
@param cert_data [out] The certificate as a sequence of bytes.
@return < 0 if an error, or the size of the certificate in bytes.
@note cert_data must be freed when there is no more need for it.
*/
* @brief Create an X.509 certificate.
*
* This certificate is a self-signed v1 cert with a fixed start/stop validity
* times. It is signed with an internal private key in ssl_ctx.
*
* @param ssl_ctx [in] The client/server context.
* @param options [in] Not used yet.
* @param dn [in] An array of distinguished name strings. The array is defined
* by:
* - SSL_X509_CERT_COMMON_NAME (0)
* - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the
* hostname will be used.
* - SSL_X509_CERT_ORGANIZATION (1)
* - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME
* will be used.
* - SSL_X509_CERT_ORGANIZATIONAL_NAME (2)
* - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional.
* @param cert_data [out] The certificate as a sequence of bytes.
* @return < 0 if an error, or the size of the certificate in bytes.
* @note cert_data must be freed when there is no more need for it.
*/
EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data);
#endif
/**
@brief Return the axTLS library version as a string.
*/
* @brief Return the axTLS library version as a string.
*/
EXP_FUNC const char * STDCALL ssl_version(void);
/** @} */

View File

@ -1,27 +1,27 @@
/*
wl_definitions.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
wl_definitions.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is 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.
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
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
*/
/*
wl_definitions.h
Created on: Mar 6, 2011
Author: dlafauci
*/
* wl_definitions.h
*
* Created on: Mar 6, 2011
* Author: dlafauci
*/
#ifndef WL_DEFINITIONS_H_
#define WL_DEFINITIONS_H_
@ -47,8 +47,7 @@
//Maximum number of attempts to establish wifi connection
#define WL_MAX_ATTEMPT_CONNECTION 10
typedef enum
{
typedef enum {
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL = 1,
@ -60,30 +59,28 @@ typedef enum
} wl_status_t;
/* Encryption modes */
enum wl_enc_type /* Values map to 802.11 encryption suites... */
{
ENC_TYPE_WEP = 5,
ENC_TYPE_TKIP = 2,
ENC_TYPE_CCMP = 4,
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
ENC_TYPE_NONE = 7,
ENC_TYPE_AUTO = 8
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
ENC_TYPE_WEP = 5,
ENC_TYPE_TKIP = 2,
ENC_TYPE_CCMP = 4,
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
ENC_TYPE_NONE = 7,
ENC_TYPE_AUTO = 8
};
#if !defined(LWIP_INTERNAL) && !defined(__LWIP_TCP_H__)
enum wl_tcp_state
{
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
enum wl_tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};
#endif