mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-15 00:02:49 +03:00
committed by
david gauchard
parent
98125f8860
commit
eea9999dc5
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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("): ");
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
@ -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_ */
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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")));
|
||||
|
||||
};
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 (¤t_iphdr_dest)
|
||||
#define TEMPDSTADDR (¤t_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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/** @} */
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user