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

Migrate from astyle to clang-format (#8464)

This commit is contained in:
Maxim Prokhorov 2022-02-20 19:23:33 +03:00 committed by Max Prokhorov
parent 46190b61f1
commit 19b7a29720
241 changed files with 15925 additions and 16197 deletions

View File

@ -238,11 +238,20 @@ jobs:
python-version: '3.x'
- name: Style check
env:
LLVM_SNAPSHOT_KEY: "6084F3CF814B57C1CF12EFD515CF4D18AF4F7421"
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
run: |
export GNUPGHOME=$(mktemp -d)
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$LLVM_SNAPSHOT_KEY"
gpg --batch --armor --export "$LLVM_SNAPSHOT_KEY" | \
sudo tee /etc/apt/trusted.gpg.d/llvm-snapshot.gpg.asc
rm -r $GNUPGHOME
echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main" | \
sudo tee /etc/apt/sources.list.d/llvm.list
sudo apt update
sudo apt install astyle
sudo apt install clang-format-13
pip3 install pyyaml
bash ./tests/ci/style_check.sh

View File

@ -23,7 +23,7 @@
// these functions must exists as-is with "C" interface,
// nonos-sdk calls them at boot time and later
#include <lwip/init.h> // LWIP_VERSION
#include <lwip/init.h> // LWIP_VERSION
#include <lwip/netif.h>
#include "LwipDhcpServer.h"
@ -35,8 +35,7 @@ DhcpServer dhcpSoftAP(&netif_git[SOFTAP_IF]);
extern "C"
{
void dhcps_start(struct ip_info *info, netif* apnetif)
void dhcps_start(struct ip_info* info, netif* apnetif)
{
// apnetif is esp interface, replaced by lwip2's
// netif_git[SOFTAP_IF] interface in constructor
@ -61,4 +60,4 @@ extern "C"
dhcpSoftAP.end();
}
} // extern "C"
} // extern "C"

File diff suppressed because it is too large Load Diff

View File

@ -31,12 +31,11 @@
#ifndef __DHCPS_H__
#define __DHCPS_H__
#include <lwip/init.h> // LWIP_VERSION
#include <lwip/init.h> // LWIP_VERSION
class DhcpServer
{
public:
DhcpServer(netif* netif);
~DhcpServer();
@ -53,72 +52,64 @@ public:
// legacy public C structure and API to eventually turn into C++
void init_dhcps_lease(uint32 ip);
bool set_dhcps_lease(struct dhcps_lease *please);
bool get_dhcps_lease(struct dhcps_lease *please);
bool set_dhcps_offer_option(uint8 level, void* optarg);
bool set_dhcps_lease_time(uint32 minute);
bool reset_dhcps_lease_time(void);
void init_dhcps_lease(uint32 ip);
bool set_dhcps_lease(struct dhcps_lease* please);
bool get_dhcps_lease(struct dhcps_lease* please);
bool set_dhcps_offer_option(uint8 level, void* optarg);
bool set_dhcps_lease_time(uint32 minute);
bool reset_dhcps_lease_time(void);
uint32 get_dhcps_lease_time(void);
bool add_dhcps_lease(uint8 *macaddr);
bool add_dhcps_lease(uint8* macaddr);
void dhcps_set_dns(int num, const ipv4_addr_t* dns);
protected:
// legacy C structure and API to eventually turn into C++
typedef struct _list_node
{
void *pnode;
struct _list_node *pnext;
void* pnode;
struct _list_node* pnext;
} list_node;
void node_insert_to_list(list_node **phead, list_node* pinsert);
void node_remove_from_list(list_node **phead, list_node* pdelete);
uint8_t* add_msg_type(uint8_t *optptr, uint8_t type);
uint8_t* add_offer_options(uint8_t *optptr);
uint8_t* add_end(uint8_t *optptr);
void create_msg(struct dhcps_msg *m);
void send_offer(struct dhcps_msg *m);
void send_nak(struct dhcps_msg *m);
void send_ack(struct dhcps_msg *m);
uint8_t parse_options(uint8_t *optptr, sint16_t len);
sint16_t parse_msg(struct dhcps_msg *m, u16_t len);
static void S_handle_dhcp(void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
const ip_addr_t *addr,
void node_insert_to_list(list_node** phead, list_node* pinsert);
void node_remove_from_list(list_node** phead, list_node* pdelete);
uint8_t* add_msg_type(uint8_t* optptr, uint8_t type);
uint8_t* add_offer_options(uint8_t* optptr);
uint8_t* add_end(uint8_t* optptr);
void create_msg(struct dhcps_msg* m);
void send_offer(struct dhcps_msg* m);
void send_nak(struct dhcps_msg* m);
void send_ack(struct dhcps_msg* m);
uint8_t parse_options(uint8_t* optptr, sint16_t len);
sint16_t parse_msg(struct dhcps_msg* m, u16_t len);
static void S_handle_dhcp(void* arg, struct udp_pcb* pcb, struct pbuf* p, const ip_addr_t* addr,
uint16_t port);
void handle_dhcp(
struct udp_pcb *pcb,
struct pbuf *p,
const ip_addr_t *addr,
uint16_t port);
void kill_oldest_dhcps_pool(void);
void dhcps_coarse_tmr(void); // CURRENTLY NOT CALLED
void dhcps_client_leave(u8 *bssid, struct ipv4_addr *ip, bool force);
uint32 dhcps_client_update(u8 *bssid, struct ipv4_addr *ip);
void handle_dhcp(struct udp_pcb* pcb, struct pbuf* p, const ip_addr_t* addr, uint16_t port);
void kill_oldest_dhcps_pool(void);
void dhcps_coarse_tmr(void); // CURRENTLY NOT CALLED
void dhcps_client_leave(u8* bssid, struct ipv4_addr* ip, bool force);
uint32 dhcps_client_update(u8* bssid, struct ipv4_addr* ip);
netif* _netif;
struct udp_pcb *pcb_dhcps;
ip_addr_t broadcast_dhcps;
struct udp_pcb* pcb_dhcps;
ip_addr_t broadcast_dhcps;
struct ipv4_addr server_address;
struct ipv4_addr client_address;
struct ipv4_addr dns_address;
uint32 dhcps_lease_time;
uint32 dhcps_lease_time;
struct dhcps_lease dhcps_lease;
list_node *plist;
uint8 offer;
bool renew;
list_node* plist;
uint8 offer;
bool renew;
static const uint32 magic_cookie;
};
// SoftAP DHCP server always exists and is started on boot
extern DhcpServer dhcpSoftAP;
extern "C" int fw_has_started_softap_dhcps;
extern "C" int fw_has_started_softap_dhcps;
#endif // __DHCPS_H__
#endif // __DHCPS_H__

View File

@ -1,12 +1,13 @@
extern "C" {
extern "C"
{
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/dns.h"
#include "lwip/dhcp.h"
#include "lwip/init.h" // LWIP_VERSION_
#include "lwip/init.h" // LWIP_VERSION_
#if LWIP_IPV6
#include "lwip/netif.h" // struct netif
#include "lwip/netif.h" // struct netif
#endif
#include <user_interface.h>
@ -24,19 +25,23 @@ extern "C" {
//
// result stored into gateway/netmask/dns1
bool LwipIntf::ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, const IPAddress& arg3,
IPAddress& gateway, IPAddress& netmask, IPAddress& dns1)
bool LwipIntf::ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1,
const IPAddress& arg2, const IPAddress& arg3, IPAddress& gateway,
IPAddress& netmask, IPAddress& dns1)
{
//To allow compatibility, check first octet of 3rd arg. If 255, interpret as ESP order, otherwise Arduino order.
// To allow compatibility, check first octet of 3rd arg. If 255, interpret as ESP order,
// otherwise Arduino order.
gateway = arg1;
netmask = arg2;
dns1 = arg3;
dns1 = arg3;
if (netmask[0] != 255)
{
//octet is not 255 => interpret as Arduino order
// octet is not 255 => interpret as Arduino order
gateway = arg2;
netmask = arg3[0] == 0 ? IPAddress(255, 255, 255, 0) : arg3; //arg order is arduino and 4th arg not given => assign it arduino default
netmask = arg3[0] == 0 ? IPAddress(255, 255, 255, 0)
: arg3; // arg order is arduino and 4th arg not given => assign it
// arduino default
dns1 = arg1;
}
@ -46,7 +51,7 @@ bool LwipIntf::ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1
return false;
}
//ip and gateway must be in the same netmask
// ip and gateway must be in the same netmask
if (gateway.isSet() && (local_ip.v4() & netmask.v4()) != (gateway.v4() & netmask.v4()))
{
return false;
@ -143,7 +148,6 @@ bool LwipIntf::hostname(const char* aHostname)
// harmless for AP, also compatible with ethernet adapters (to come)
for (netif* intf = netif_list; intf; intf = intf->next)
{
// unconditionally update all known interfaces
intf->hostname = wifi_station_get_hostname();
@ -162,4 +166,3 @@ bool LwipIntf::hostname(const char* aHostname)
return ret && compliant;
}

View File

@ -10,8 +10,7 @@
class LwipIntf
{
public:
using CBType = std::function <void(netif*)>;
using CBType = std::function<void(netif*)>;
static bool stateUpCB(LwipIntf::CBType&& cb);
@ -24,12 +23,12 @@ public:
// arg3 | dns1 netmask
//
// result stored into gateway/netmask/dns1
static
bool ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, const IPAddress& arg3,
IPAddress& gateway, IPAddress& netmask, IPAddress& dns1);
static bool ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1,
const IPAddress& arg2, const IPAddress& arg3, IPAddress& gateway,
IPAddress& netmask, IPAddress& dns1);
String hostname();
bool hostname(const String& aHostname)
bool hostname(const String& aHostname)
{
return hostname(aHostname.c_str());
}
@ -42,8 +41,7 @@ public:
const char* getHostname();
protected:
static bool stateChangeSysCB(LwipIntf::CBType&& cb);
};
#endif // _LWIPINTF_H
#endif // _LWIPINTF_H

View File

@ -5,8 +5,8 @@
#define NETIF_STATUS_CB_SIZE 3
static int netifStatusChangeListLength = 0;
LwipIntf::CBType netifStatusChangeList [NETIF_STATUS_CB_SIZE];
static int netifStatusChangeListLength = 0;
LwipIntf::CBType netifStatusChangeList[NETIF_STATUS_CB_SIZE];
extern "C" void netif_status_changed(struct netif* netif)
{
@ -33,12 +33,14 @@ bool LwipIntf::stateChangeSysCB(LwipIntf::CBType&& cb)
bool LwipIntf::stateUpCB(LwipIntf::CBType&& cb)
{
return stateChangeSysCB([cb](netif * nif)
{
if (netif_is_up(nif))
schedule_function([cb, nif]()
return stateChangeSysCB(
[cb](netif* nif)
{
cb(nif);
if (netif_is_up(nif))
schedule_function(
[cb, nif]()
{
cb(nif);
});
});
});
}

View File

@ -14,7 +14,7 @@
#include <lwip/dns.h>
#include <lwip/apps/sntp.h>
#include <user_interface.h> // wifi_get_macaddr()
#include <user_interface.h> // wifi_get_macaddr()
#include "SPI.h"
#include "Schedule.h"
@ -25,41 +25,36 @@
#define DEFAULT_MTU 1500
#endif
template <class RawDev>
template<class RawDev>
class LwipIntfDev: public LwipIntf, public RawDev
{
public:
LwipIntfDev(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1):
RawDev(cs, spi, intr),
_mtu(DEFAULT_MTU),
_intrPin(intr),
_started(false),
_default(false)
LwipIntfDev(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1) :
RawDev(cs, spi, intr), _mtu(DEFAULT_MTU), _intrPin(intr), _started(false), _default(false)
{
memset(&_netif, 0, sizeof(_netif));
}
boolean config(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, const IPAddress& arg3 = IPADDR_NONE, const IPAddress& dns2 = IPADDR_NONE);
boolean config(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2,
const IPAddress& arg3 = IPADDR_NONE, const IPAddress& dns2 = IPADDR_NONE);
// default mac-address is inferred from esp8266's STA interface
boolean begin(const uint8_t *macAddress = nullptr, const uint16_t mtu = DEFAULT_MTU);
boolean begin(const uint8_t* macAddress = nullptr, const uint16_t mtu = DEFAULT_MTU);
const netif* getNetIf() const
{
return &_netif;
}
IPAddress localIP() const
IPAddress localIP() const
{
return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.ip_addr)));
}
IPAddress subnetMask() const
IPAddress subnetMask() const
{
return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.netmask)));
}
IPAddress gatewayIP() const
IPAddress gatewayIP() const
{
return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.gw)));
}
@ -77,12 +72,11 @@ public:
wl_status_t status();
protected:
err_t netif_init();
void netif_status_callback();
static err_t netif_init_s(netif* netif);
static err_t linkoutput_s(netif *netif, struct pbuf *p);
static err_t linkoutput_s(netif* netif, struct pbuf* p);
static void netif_status_callback_s(netif* netif);
// called on a regular basis or on interrupt
@ -90,18 +84,19 @@ protected:
// members
netif _netif;
uint16_t _mtu;
int8_t _intrPin;
uint8_t _macAddress[6];
bool _started;
bool _default;
netif _netif;
uint16_t _mtu;
int8_t _intrPin;
uint8_t _macAddress[6];
bool _started;
bool _default;
};
template <class RawDev>
boolean LwipIntfDev<RawDev>::config(const IPAddress& localIP, const IPAddress& gateway, const IPAddress& netmask, const IPAddress& dns1, const IPAddress& dns2)
template<class RawDev>
boolean LwipIntfDev<RawDev>::config(const IPAddress& localIP, const IPAddress& gateway,
const IPAddress& netmask, const IPAddress& dns1,
const IPAddress& dns2)
{
if (_started)
{
@ -132,7 +127,7 @@ boolean LwipIntfDev<RawDev>::config(const IPAddress& localIP, const IPAddress& g
return true;
}
template <class RawDev>
template<class RawDev>
boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu)
{
if (mtu)
@ -162,9 +157,9 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
memset(_macAddress, 0, 6);
_macAddress[0] = 0xEE;
#endif
_macAddress[3] += _netif.num; // alter base mac address
_macAddress[0] &= 0xfe; // set as locally administered, unicast, per
_macAddress[0] |= 0x02; // https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
_macAddress[3] += _netif.num; // alter base mac address
_macAddress[0] &= 0xfe; // set as locally administered, unicast, per
_macAddress[0] |= 0x02; // https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
}
if (!RawDev::begin(_macAddress))
@ -183,7 +178,8 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
ip_addr_copy(netmask, _netif.netmask);
ip_addr_copy(gw, _netif.gw);
if (!netif_add(&_netif, ip_2_ip4(&ip_addr), ip_2_ip4(&netmask), ip_2_ip4(&gw), this, netif_init_s, ethernet_input))
if (!netif_add(&_netif, ip_2_ip4(&ip_addr), ip_2_ip4(&netmask), ip_2_ip4(&gw), this,
netif_init_s, ethernet_input))
{
return false;
}
@ -212,20 +208,24 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
{
if (RawDev::interruptIsPossible())
{
//attachInterrupt(_intrPin, [&]() { this->handlePackets(); }, FALLING);
// attachInterrupt(_intrPin, [&]() { this->handlePackets(); }, FALLING);
}
else
{
::printf((PGM_P)F("lwIP_Intf: Interrupt not implemented yet, enabling transparent polling\r\n"));
::printf((PGM_P)F(
"lwIP_Intf: Interrupt not implemented yet, enabling transparent polling\r\n"));
_intrPin = -1;
}
}
if (_intrPin < 0 && !schedule_recurrent_function_us([&]()
{
this->handlePackets();
return true;
}, 100))
if (_intrPin < 0
&& !schedule_recurrent_function_us(
[&]()
{
this->handlePackets();
return true;
},
100))
{
netif_remove(&_netif);
return false;
@ -234,14 +234,14 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
return true;
}
template <class RawDev>
template<class RawDev>
wl_status_t LwipIntfDev<RawDev>::status()
{
return _started ? (connected() ? WL_CONNECTED : WL_DISCONNECTED) : WL_NO_SHIELD;
}
template <class RawDev>
err_t LwipIntfDev<RawDev>::linkoutput_s(netif *netif, struct pbuf *pbuf)
template<class RawDev>
err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf)
{
LwipIntfDev* ths = (LwipIntfDev*)netif->state;
@ -255,37 +255,34 @@ err_t LwipIntfDev<RawDev>::linkoutput_s(netif *netif, struct pbuf *pbuf)
#if PHY_HAS_CAPTURE
if (phy_capture)
{
phy_capture(ths->_netif.num, (const char*)pbuf->payload, pbuf->len, /*out*/1, /*success*/len == pbuf->len);
phy_capture(ths->_netif.num, (const char*)pbuf->payload, pbuf->len, /*out*/ 1,
/*success*/ len == pbuf->len);
}
#endif
return len == pbuf->len ? ERR_OK : ERR_MEM;
}
template <class RawDev>
template<class RawDev>
err_t LwipIntfDev<RawDev>::netif_init_s(struct netif* netif)
{
return ((LwipIntfDev*)netif->state)->netif_init();
}
template <class RawDev>
template<class RawDev>
void LwipIntfDev<RawDev>::netif_status_callback_s(struct netif* netif)
{
((LwipIntfDev*)netif->state)->netif_status_callback();
}
template <class RawDev>
template<class RawDev>
err_t LwipIntfDev<RawDev>::netif_init()
{
_netif.name[0] = 'e';
_netif.name[1] = '0' + _netif.num;
_netif.mtu = _mtu;
_netif.name[0] = 'e';
_netif.name[1] = '0' + _netif.num;
_netif.mtu = _mtu;
_netif.chksum_flags = NETIF_CHECKSUM_ENABLE_ALL;
_netif.flags =
NETIF_FLAG_ETHARP
| NETIF_FLAG_IGMP
| NETIF_FLAG_BROADCAST
| NETIF_FLAG_LINK_UP;
_netif.flags = NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP | NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP;
// lwIP's doc: This function typically first resolves the hardware
// address, then sends the packet. For ethernet physical layer, this is
@ -301,7 +298,7 @@ err_t LwipIntfDev<RawDev>::netif_init()
return ERR_OK;
}
template <class RawDev>
template<class RawDev>
void LwipIntfDev<RawDev>::netif_status_callback()
{
if (connected())
@ -321,14 +318,14 @@ void LwipIntfDev<RawDev>::netif_status_callback()
}
}
template <class RawDev>
template<class RawDev>
err_t LwipIntfDev<RawDev>::handlePackets()
{
int pkt = 0;
while (1)
{
if (++pkt == 10)
// prevent starvation
// prevent starvation
{
return ERR_OK;
}
@ -374,7 +371,8 @@ err_t LwipIntfDev<RawDev>::handlePackets()
#if PHY_HAS_CAPTURE
if (phy_capture)
{
phy_capture(_netif.num, (const char*)pbuf->payload, tot_len, /*out*/0, /*success*/err == ERR_OK);
phy_capture(_netif.num, (const char*)pbuf->payload, tot_len, /*out*/ 0,
/*success*/ err == ERR_OK);
}
#endif
@ -384,11 +382,10 @@ err_t LwipIntfDev<RawDev>::handlePackets()
return err;
}
// (else) allocated pbuf is now lwIP's responsibility
}
}
template <class RawDev>
template<class RawDev>
void LwipIntfDev<RawDev>::setDefault()
{
_default = true;
@ -398,4 +395,4 @@ void LwipIntfDev<RawDev>::setDefault()
}
}
#endif // _LWIPINTFDEV_H
#endif // _LWIPINTFDEV_H

View File

@ -19,20 +19,17 @@
parsing functions based on TextFinder library by Michael Margolis
*/
#include <Arduino.h>
#include <StreamDev.h>
size_t Stream::sendGeneric(Print* to,
const ssize_t len,
const int readUntilChar,
size_t Stream::sendGeneric(Print* to, const ssize_t len, const int readUntilChar,
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
{
setReport(Report::Success);
if (len == 0)
{
return 0; // conveniently avoids timeout for no requested data
return 0; // conveniently avoids timeout for no requested data
}
// There are two timeouts:
@ -57,14 +54,17 @@ size_t Stream::sendGeneric(Print* to,
return SendGenericRegular(to, len, timeoutMs);
}
size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int readUntilChar, const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
size_t
Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int readUntilChar,
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
{
// "neverExpires (default, impossible)" is translated to default timeout
esp8266::polledTimeout::oneShotFastMs timedOut(timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout() : timeoutMs);
esp8266::polledTimeout::oneShotFastMs timedOut(
timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
: timeoutMs);
// len==-1 => maxLen=0 <=> until starvation
const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0;
const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0;
while (!maxLen || written < maxLen)
{
@ -90,13 +90,13 @@ size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int rea
if (w)
{
const char* directbuf = peekBuffer();
bool foundChar = false;
bool foundChar = false;
if (readUntilChar >= 0)
{
const char* last = (const char*)memchr(directbuf, readUntilChar, w);
if (last)
{
w = std::min((size_t)(last - directbuf), w);
w = std::min((size_t)(last - directbuf), w);
foundChar = true;
}
}
@ -104,7 +104,7 @@ size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int rea
{
peekConsume(w);
written += w;
timedOut.reset(); // something has been written
timedOut.reset(); // something has been written
}
if (foundChar)
{
@ -145,16 +145,20 @@ size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int rea
return written;
}
size_t Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int readUntilChar, const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
size_t
Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int readUntilChar,
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
{
// regular Stream API
// no other choice than reading byte by byte
// "neverExpires (default, impossible)" is translated to default timeout
esp8266::polledTimeout::oneShotFastMs timedOut(timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout() : timeoutMs);
esp8266::polledTimeout::oneShotFastMs timedOut(
timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
: timeoutMs);
// len==-1 => maxLen=0 <=> until starvation
const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0;
const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0;
while (!maxLen || written < maxLen)
{
@ -186,7 +190,7 @@ size_t Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int r
break;
}
written += 1;
timedOut.reset(); // something has been written
timedOut.reset(); // something has been written
}
if (timedOut)
@ -221,16 +225,19 @@ size_t Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int r
return written;
}
size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
size_t Stream::SendGenericRegular(Print* to, const ssize_t len,
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
{
// regular Stream API
// use an intermediary buffer
// "neverExpires (default, impossible)" is translated to default timeout
esp8266::polledTimeout::oneShotFastMs timedOut(timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout() : timeoutMs);
esp8266::polledTimeout::oneShotFastMs timedOut(
timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
: timeoutMs);
// len==-1 => maxLen=0 <=> until starvation
const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0;
const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0;
while (!maxLen || written < maxLen)
{
@ -243,7 +250,7 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p
size_t w = to->availableForWrite();
if (w == 0 && !to->outputCanTimeout())
// no more data can be written, ever
// no more data can be written, ever
{
break;
}
@ -256,7 +263,7 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p
w = std::min(w, (decltype(w))temporaryStackBufferSize);
if (w)
{
char temp[w];
char temp[w];
ssize_t r = read(temp, w);
if (r < 0)
{
@ -270,7 +277,7 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p
setReport(Report::WriteError);
break;
}
timedOut.reset(); // something has been written
timedOut.reset(); // something has been written
}
if (timedOut)
@ -305,19 +312,19 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p
return written;
}
Stream& operator << (Stream& out, String& string)
Stream& operator<<(Stream& out, String& string)
{
StreamConstPtr(string).sendAll(out);
return out;
}
Stream& operator << (Stream& out, StreamString& stream)
Stream& operator<<(Stream& out, StreamString& stream)
{
stream.sendAll(out);
return out;
}
Stream& operator << (Stream& out, Stream& stream)
Stream& operator<<(Stream& out, Stream& stream)
{
if (stream.streamRemaining() < 0)
{
@ -339,13 +346,13 @@ Stream& operator << (Stream& out, Stream& stream)
return out;
}
Stream& operator << (Stream& out, const char* text)
Stream& operator<<(Stream& out, const char* text)
{
StreamConstPtr(text, strlen_P(text)).sendAll(out);
return out;
}
Stream& operator << (Stream& out, const __FlashStringHelper* text)
Stream& operator<<(Stream& out, const __FlashStringHelper* text)
{
StreamConstPtr(text).sendAll(out);
return out;

View File

@ -35,16 +35,9 @@
class S2Stream: public Stream
{
public:
S2Stream(String& string, int peekPointer = -1) : string(&string), peekPointer(peekPointer) { }
S2Stream(String& string, int peekPointer = -1):
string(&string), peekPointer(peekPointer)
{
}
S2Stream(String* string, int peekPointer = -1):
string(string), peekPointer(peekPointer)
{
}
S2Stream(String* string, int peekPointer = -1) : string(string), peekPointer(peekPointer) { }
virtual int available() override
{
@ -207,18 +200,15 @@ public:
}
protected:
String* string;
int peekPointer; // -1:String is consumed / >=0:resettable pointer
int peekPointer; // -1:String is consumed / >=0:resettable pointer
};
// StreamString is a S2Stream holding the String
class StreamString: public String, public S2Stream
{
protected:
void resetpp()
{
if (peekPointer > 0)
@ -228,55 +218,68 @@ protected:
}
public:
StreamString(StreamString&& bro): String(bro), S2Stream(this) { }
StreamString(const StreamString& bro): String(bro), S2Stream(this) { }
StreamString(StreamString&& bro) : String(bro), S2Stream(this) { }
StreamString(const StreamString& bro) : String(bro), S2Stream(this) { }
// duplicate String constructors and operator=:
StreamString(const char* text = nullptr): String(text), S2Stream(this) { }
StreamString(const String& string): String(string), S2Stream(this) { }
StreamString(const __FlashStringHelper *str): String(str), S2Stream(this) { }
StreamString(String&& string): String(string), S2Stream(this) { }
StreamString(const char* text = nullptr) : String(text), S2Stream(this) { }
StreamString(const String& string) : String(string), S2Stream(this) { }
StreamString(const __FlashStringHelper* str) : String(str), S2Stream(this) { }
StreamString(String&& string) : String(string), S2Stream(this) { }
explicit StreamString(char c): String(c), S2Stream(this) { }
explicit StreamString(unsigned char c, unsigned char base = 10): String(c, base), S2Stream(this) { }
explicit StreamString(int i, unsigned char base = 10): String(i, base), S2Stream(this) { }
explicit StreamString(unsigned int i, unsigned char base = 10): String(i, base), S2Stream(this) { }
explicit StreamString(long l, unsigned char base = 10): String(l, base), S2Stream(this) { }
explicit StreamString(unsigned long l, unsigned char base = 10): String(l, base), S2Stream(this) { }
explicit StreamString(float f, unsigned char decimalPlaces = 2): String(f, decimalPlaces), S2Stream(this) { }
explicit StreamString(double d, unsigned char decimalPlaces = 2): String(d, decimalPlaces), S2Stream(this) { }
explicit StreamString(char c) : String(c), S2Stream(this) { }
explicit StreamString(unsigned char c, unsigned char base = 10) :
String(c, base), S2Stream(this)
{
}
explicit StreamString(int i, unsigned char base = 10) : String(i, base), S2Stream(this) { }
explicit StreamString(unsigned int i, unsigned char base = 10) : String(i, base), S2Stream(this)
{
}
explicit StreamString(long l, unsigned char base = 10) : String(l, base), S2Stream(this) { }
explicit StreamString(unsigned long l, unsigned char base = 10) :
String(l, base), S2Stream(this)
{
}
explicit StreamString(float f, unsigned char decimalPlaces = 2) :
String(f, decimalPlaces), S2Stream(this)
{
}
explicit StreamString(double d, unsigned char decimalPlaces = 2) :
String(d, decimalPlaces), S2Stream(this)
{
}
StreamString& operator= (const StreamString& rhs)
StreamString& operator=(const StreamString& rhs)
{
String::operator=(rhs);
resetpp();
return *this;
}
StreamString& operator= (const String& rhs)
StreamString& operator=(const String& rhs)
{
String::operator=(rhs);
resetpp();
return *this;
}
StreamString& operator= (const char* cstr)
StreamString& operator=(const char* cstr)
{
String::operator=(cstr);
resetpp();
return *this;
}
StreamString& operator= (const __FlashStringHelper* str)
StreamString& operator=(const __FlashStringHelper* str)
{
String::operator=(str);
resetpp();
return *this;
}
StreamString& operator= (String&& rval)
StreamString& operator=(String&& rval)
{
String::operator=(rval);
resetpp();
@ -284,4 +287,4 @@ public:
}
};
#endif // __STREAMSTRING_H
#endif // __STREAMSTRING_H

View File

@ -24,9 +24,8 @@
#include "wiring_private.h"
#include "PolledTimeout.h"
extern "C" {
extern "C"
{
#include "twi_util.h"
#include "ets_sys.h"
};
@ -57,78 +56,113 @@ static inline __attribute__((always_inline)) bool SCL_READ(const int twi_scl)
return (GPI & (1 << twi_scl)) != 0;
}
// Implement as a class to reduce code size by allowing access to many global variables with a single base pointer
// Implement as a class to reduce code size by allowing access to many global variables with a
// single base pointer
class Twi
{
private:
unsigned int preferred_si2c_clock = 100000;
uint32_t twi_dcount = 18;
unsigned char twi_sda = 0;
unsigned char twi_scl = 0;
unsigned char twi_addr = 0;
uint32_t twi_clockStretchLimit = 0;
unsigned int preferred_si2c_clock = 100000;
uint32_t twi_dcount = 18;
unsigned char twi_sda = 0;
unsigned char twi_scl = 0;
unsigned char twi_addr = 0;
uint32_t twi_clockStretchLimit = 0;
// These are int-wide, even though they could all fit in a byte, to reduce code size and avoid any potential
// issues about RmW on packed bytes. The int-wide variations of asm instructions are smaller than the equivalent
// byte-wide ones, and since these emums are used everywhere, the difference adds up fast. There is only a single
// instance of the class, though, so the extra 12 bytes of RAM used here saves a lot more IRAM.
volatile enum { TWIPM_UNKNOWN = 0, TWIPM_IDLE, TWIPM_ADDRESSED, TWIPM_WAIT} twip_mode = TWIPM_IDLE;
volatile enum { TWIP_UNKNOWN = 0, TWIP_IDLE, TWIP_START, TWIP_SEND_ACK, TWIP_WAIT_ACK, TWIP_WAIT_STOP, TWIP_SLA_W, TWIP_SLA_R, TWIP_REP_START, TWIP_READ, TWIP_STOP, TWIP_REC_ACK, TWIP_READ_ACK, TWIP_RWAIT_ACK, TWIP_WRITE, TWIP_BUS_ERR } twip_state = TWIP_IDLE;
// These are int-wide, even though they could all fit in a byte, to reduce code size and avoid
// any potential issues about RmW on packed bytes. The int-wide variations of asm instructions
// are smaller than the equivalent byte-wide ones, and since these emums are used everywhere,
// the difference adds up fast. There is only a single instance of the class, though, so the
// extra 12 bytes of RAM used here saves a lot more IRAM.
volatile enum {
TWIPM_UNKNOWN = 0,
TWIPM_IDLE,
TWIPM_ADDRESSED,
TWIPM_WAIT
} twip_mode
= TWIPM_IDLE;
volatile enum {
TWIP_UNKNOWN = 0,
TWIP_IDLE,
TWIP_START,
TWIP_SEND_ACK,
TWIP_WAIT_ACK,
TWIP_WAIT_STOP,
TWIP_SLA_W,
TWIP_SLA_R,
TWIP_REP_START,
TWIP_READ,
TWIP_STOP,
TWIP_REC_ACK,
TWIP_READ_ACK,
TWIP_RWAIT_ACK,
TWIP_WRITE,
TWIP_BUS_ERR
} twip_state
= TWIP_IDLE;
volatile int twip_status = TW_NO_INFO;
volatile int bitCount = 0;
volatile int bitCount = 0;
volatile uint8_t twi_data = 0x00;
volatile int twi_ack = 0;
volatile int twi_ack_rec = 0;
volatile int twi_timeout_ms = 10;
volatile uint8_t twi_data = 0x00;
volatile int twi_ack = 0;
volatile int twi_ack_rec = 0;
volatile int twi_timeout_ms = 10;
volatile enum { TWI_READY = 0, TWI_MRX, TWI_MTX, TWI_SRX, TWI_STX } twi_state = TWI_READY;
volatile uint8_t twi_error = 0xFF;
volatile uint8_t twi_error = 0xFF;
uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
volatile int twi_txBufferIndex = 0;
uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
volatile int twi_txBufferIndex = 0;
volatile int twi_txBufferLength = 0;
uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
volatile int twi_rxBufferIndex = 0;
void (*twi_onSlaveTransmit)(void);
void (*twi_onSlaveReceive)(uint8_t*, size_t);
// ETS queue/timer interfaces
enum { EVENTTASK_QUEUE_SIZE = 1, EVENTTASK_QUEUE_PRIO = 2 };
enum { TWI_SIG_RANGE = 0x00000100, TWI_SIG_RX = 0x00000101, TWI_SIG_TX = 0x00000102 };
enum
{
EVENTTASK_QUEUE_SIZE = 1,
EVENTTASK_QUEUE_PRIO = 2
};
enum
{
TWI_SIG_RANGE = 0x00000100,
TWI_SIG_RX = 0x00000101,
TWI_SIG_TX = 0x00000102
};
ETSEvent eventTaskQueue[EVENTTASK_QUEUE_SIZE];
ETSTimer timer;
// Event/IRQ callbacks, so they can't use "this" and need to be static
static void IRAM_ATTR onSclChange(void);
static void IRAM_ATTR onSdaChange(void);
static void eventTask(ETSEvent *e);
static void IRAM_ATTR onTimer(void *unused);
static void eventTask(ETSEvent* e);
static void IRAM_ATTR onTimer(void* unused);
// Allow not linking in the slave code if there is no call to setAddress
bool _slaveEnabled = false;
// Internal use functions
void IRAM_ATTR busywait(unsigned int v);
bool write_start(void);
bool write_stop(void);
bool write_bit(bool bit);
bool read_bit(void);
bool write_byte(unsigned char byte);
unsigned char read_byte(bool nack);
bool write_start(void);
bool write_stop(void);
bool write_bit(bool bit);
bool read_bit(void);
bool write_byte(unsigned char byte);
unsigned char read_byte(bool nack);
void IRAM_ATTR onTwipEvent(uint8_t status);
// Handle the case where a slave needs to stretch the clock with a time-limited busy wait
inline void WAIT_CLOCK_STRETCH()
{
esp8266::polledTimeout::oneShotFastUs timeout(twi_clockStretchLimit);
esp8266::polledTimeout::oneShotFastUs timeout(twi_clockStretchLimit);
esp8266::polledTimeout::periodicFastUs yieldTimeout(5000);
while (!timeout && !SCL_READ(twi_scl)) // outer loop is stretch duration up to stretch limit
while (!timeout
&& !SCL_READ(twi_scl)) // outer loop is stretch duration up to stretch limit
{
if (yieldTimeout) // inner loop yields every 5ms
if (yieldTimeout) // inner loop yields every 5ms
{
yield();
}
@ -139,19 +173,21 @@ private:
void twi_scl_valley(void);
public:
void setClock(unsigned int freq);
void setClockStretchLimit(uint32_t limit);
void init(unsigned char sda, unsigned char scl);
void setAddress(uint8_t address);
unsigned char writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop);
unsigned char readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop);
uint8_t status();
uint8_t transmit(const uint8_t* data, uint8_t length);
void attachSlaveRxEvent(void (*function)(uint8_t*, size_t));
void attachSlaveTxEvent(void (*function)(void));
void setClock(unsigned int freq);
void setClockStretchLimit(uint32_t limit);
void init(unsigned char sda, unsigned char scl);
void setAddress(uint8_t address);
unsigned char writeTo(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop);
unsigned char readFrom(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop);
uint8_t status();
uint8_t transmit(const uint8_t* data, uint8_t length);
void attachSlaveRxEvent(void (*function)(uint8_t*, size_t));
void attachSlaveTxEvent(void (*function)(void));
void IRAM_ATTR reply(uint8_t ack);
void IRAM_ATTR releaseBus(void);
void enableSlave();
void enableSlave();
};
static Twi twi;
@ -176,7 +212,8 @@ void Twi::setClock(unsigned int freq)
freq = 400000;
}
twi_dcount = (500000000 / freq); // half-cycle period in ns
twi_dcount = (1000 * (twi_dcount - 1120)) / 62500; // (half cycle - overhead) / busywait loop time
twi_dcount
= (1000 * (twi_dcount - 1120)) / 62500; // (half cycle - overhead) / busywait loop time
#else
@ -185,7 +222,8 @@ void Twi::setClock(unsigned int freq)
freq = 800000;
}
twi_dcount = (500000000 / freq); // half-cycle period in ns
twi_dcount = (1000 * (twi_dcount - 560)) / 31250; // (half cycle - overhead) / busywait loop time
twi_dcount
= (1000 * (twi_dcount - 560)) / 31250; // (half cycle - overhead) / busywait loop time
#endif
}
@ -195,8 +233,6 @@ void Twi::setClockStretchLimit(uint32_t limit)
twi_clockStretchLimit = limit;
}
void Twi::init(unsigned char sda, unsigned char scl)
{
// set timer function
@ -210,7 +246,7 @@ void Twi::init(unsigned char sda, unsigned char scl)
pinMode(twi_sda, INPUT_PULLUP);
pinMode(twi_scl, INPUT_PULLUP);
twi_setClock(preferred_si2c_clock);
twi_setClockStretchLimit(150000L); // default value is 150 mS
twi_setClockStretchLimit(150000L); // default value is 150 mS
}
void Twi::setAddress(uint8_t address)
@ -234,7 +270,8 @@ void IRAM_ATTR Twi::busywait(unsigned int v)
unsigned int i;
for (i = 0; i < v; i++) // loop time is 5 machine cycles: 31.25ns @ 160MHz, 62.5ns @ 80MHz
{
__asm__ __volatile__("nop"); // minimum element to keep GCC from optimizing this function out.
__asm__ __volatile__(
"nop"); // minimum element to keep GCC from optimizing this function out.
}
}
@ -250,7 +287,8 @@ bool Twi::write_start(void)
// A high-to-low transition on the SDA line while the SCL is high defines a START condition.
SDA_LOW(twi_sda);
busywait(twi_dcount);
// An additional delay between the SCL line high-to-low transition and setting up the SDA line to prevent a STOP condition execute.
// An additional delay between the SCL line high-to-low transition and setting up the SDA line
// to prevent a STOP condition execute.
SCL_LOW(twi_scl);
busywait(twi_dcount);
return true;
@ -308,7 +346,7 @@ bool Twi::write_byte(unsigned char byte)
write_bit(byte & 0x80);
byte <<= 1;
}
return !read_bit();//NACK/ACK
return !read_bit(); // NACK/ACK
}
unsigned char Twi::read_byte(bool nack)
@ -323,12 +361,13 @@ unsigned char Twi::read_byte(bool nack)
return byte;
}
unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop)
unsigned char Twi::writeTo(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop)
{
unsigned int i;
if (!write_start())
{
return 4; //line busy
return 4; // line busy
}
if (!write_byte(((address << 1) | 0) & 0xFF))
{
@ -336,7 +375,7 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
{
write_stop();
}
return 2; //received NACK on transmit of address
return 2; // received NACK on transmit of address
}
for (i = 0; i < len; i++)
{
@ -346,7 +385,7 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
{
write_stop();
}
return 3;//received NACK on transmit of data
return 3; // received NACK on transmit of data
}
}
if (sendStop)
@ -368,12 +407,13 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
return 0;
}
unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop)
unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop)
{
unsigned int i;
if (!write_start())
{
return 4; //line busy
return 4; // line busy
}
if (!write_byte(((address << 1) | 1) & 0xFF))
{
@ -381,7 +421,7 @@ unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned
{
write_stop();
}
return 2;//received NACK on transmit of address
return 2; // received NACK on transmit of address
}
for (i = 0; i < (len - 1); i++)
{
@ -420,21 +460,25 @@ uint8_t Twi::status()
WAIT_CLOCK_STRETCH(); // wait for a slow slave to finish
if (!SCL_READ(twi_scl))
{
return I2C_SCL_HELD_LOW; // SCL held low by another device, no procedure available to recover
return I2C_SCL_HELD_LOW; // SCL held low by another device, no procedure available to
// recover
}
int clockCount = 20;
while (!SDA_READ(twi_sda) && clockCount-- > 0) // if SDA low, read the bits slaves have to sent to a max
while (!SDA_READ(twi_sda)
&& clockCount-- > 0) // if SDA low, read the bits slaves have to sent to a max
{
read_bit();
if (!SCL_READ(twi_scl))
{
return I2C_SCL_HELD_LOW_AFTER_READ; // I2C bus error. SCL held low beyond slave clock stretch time
return I2C_SCL_HELD_LOW_AFTER_READ; // I2C bus error. SCL held low beyond slave clock
// stretch time
}
}
if (!SDA_READ(twi_sda))
{
return I2C_SDA_HELD_LOW; // I2C bus error. SDA line held low by slave/another_master after n bits.
return I2C_SDA_HELD_LOW; // I2C bus error. SDA line held low by slave/another_master after
// n bits.
}
return I2C_OK;
@ -476,58 +520,57 @@ void Twi::attachSlaveTxEvent(void (*function)(void))
twi_onSlaveTransmit = function;
}
// DO NOT INLINE, inlining reply() in combination with compiler optimizations causes function breakup into
// parts and the IRAM_ATTR isn't propagated correctly to all parts, which of course causes crashes.
// DO NOT INLINE, inlining reply() in combination with compiler optimizations causes function
// breakup into parts and the IRAM_ATTR isn't propagated correctly to all parts, which of course
// causes crashes.
// TODO: test with gcc 9.x and if it still fails, disable optimization with -fdisable-ipa-fnsplit
void IRAM_ATTR Twi::reply(uint8_t ack)
{
// transmit master read ready signal, with or without ack
if (ack)
{
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA)
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA)
}
else
{
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 0; // ~_BV(TWEA)
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 0; // ~_BV(TWEA)
}
}
void IRAM_ATTR Twi::releaseBus(void)
{
// release bus
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA)
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA)
SDA_HIGH(twi.twi_sda);
// update twi state
twi_state = TWI_READY;
}
void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
{
twip_status = status;
switch (status)
{
// Slave Receiver
case TW_SR_SLA_ACK: // addressed, returned ack
case TW_SR_GCALL_ACK: // addressed generally, returned ack
case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
case TW_SR_SLA_ACK: // addressed, returned ack
case TW_SR_GCALL_ACK: // addressed generally, returned ack
case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
// enter slave receiver mode
twi_state = TWI_SRX;
// indicate that rx buffer can be overwritten and ack
twi_rxBufferIndex = 0;
reply(1);
break;
case TW_SR_DATA_ACK: // data received, returned ack
case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
case TW_SR_DATA_ACK: // data received, returned ack
case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
// if there is still room in the rx buffer
if (twi_rxBufferIndex < TWI_BUFFER_LENGTH)
{
@ -541,29 +584,29 @@ void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
reply(0);
}
break;
case TW_SR_STOP: // stop or repeated start condition received
case TW_SR_STOP: // stop or repeated start condition received
// put a null char after data if there's room
if (twi_rxBufferIndex < TWI_BUFFER_LENGTH)
{
twi_rxBuffer[twi_rxBufferIndex] = '\0';
}
// callback to user-defined callback over event task to allow for non-RAM-residing code
//twi_rxBufferLock = true; // This may be necessary
// twi_rxBufferLock = true; // This may be necessary
ets_post(EVENTTASK_QUEUE_PRIO, TWI_SIG_RX, twi_rxBufferIndex);
// since we submit rx buffer to "wire" library, we can reset it
twi_rxBufferIndex = 0;
break;
case TW_SR_DATA_NACK: // data received, returned nack
case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
case TW_SR_DATA_NACK: // data received, returned nack
case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
// nack back at master
reply(0);
break;
// Slave Transmitter
case TW_ST_SLA_ACK: // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
case TW_ST_SLA_ACK: // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
// enter slave transmitter mode
twi_state = TWI_STX;
// ready the tx buffer index for iteration
@ -576,7 +619,7 @@ void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
ets_post(EVENTTASK_QUEUE_PRIO, TWI_SIG_TX, 0);
break;
case TW_ST_DATA_ACK: // byte sent, ack returned
case TW_ST_DATA_ACK: // byte sent, ack returned
// copy data to output register
twi_data = twi_txBuffer[twi_txBufferIndex++];
@ -602,33 +645,32 @@ void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
reply(0);
}
break;
case TW_ST_DATA_NACK: // received nack, we are done
case TW_ST_LAST_DATA: // received ack, but we are done already!
case TW_ST_DATA_NACK: // received nack, we are done
case TW_ST_LAST_DATA: // received ack, but we are done already!
// leave slave receiver state
releaseBus();
break;
// All
case TW_NO_INFO: // no state information
case TW_NO_INFO: // no state information
break;
case TW_BUS_ERROR: // bus error, illegal stop/start
case TW_BUS_ERROR: // bus error, illegal stop/start
twi_error = TW_BUS_ERROR;
break;
}
}
void IRAM_ATTR Twi::onTimer(void *unused)
void IRAM_ATTR Twi::onTimer(void* unused)
{
(void)unused;
twi.releaseBus();
twi.onTwipEvent(TW_BUS_ERROR);
twi.twip_mode = TWIPM_WAIT;
twi.twip_mode = TWIPM_WAIT;
twi.twip_state = TWIP_BUS_ERR;
}
void Twi::eventTask(ETSEvent *e)
void Twi::eventTask(ETSEvent* e)
{
if (e == NULL)
{
return;
@ -643,7 +685,7 @@ void Twi::eventTask(ETSEvent *e)
if (twi.twi_txBufferLength == 0)
{
twi.twi_txBufferLength = 1;
twi.twi_txBuffer[0] = 0x00;
twi.twi_txBuffer[0] = 0x00;
}
// Initiate transmission
@ -663,7 +705,7 @@ void Twi::eventTask(ETSEvent *e)
// compared to the logical-or of all states with the same branch. This removes the need
// for a large series of straight-line compares. The biggest win is when multiple states
// all have the same branch (onSdaChange), but for others there is some benefit, still.
#define S2M(x) (1<<(x))
#define S2M(x) (1 << (x))
// Shorthand for if the state is any of the or'd bitmask x
#define IFSTATE(x) if (twip_state_mask & (x))
@ -677,7 +719,7 @@ void IRAM_ATTR Twi::onSclChange(void)
sda = SDA_READ(twi.twi_sda);
scl = SCL_READ(twi.twi_scl);
twi.twip_status = 0xF8; // reset TWI status
twi.twip_status = 0xF8; // reset TWI status
int twip_state_mask = S2M(twi.twip_state);
IFSTATE(S2M(TWIP_START) | S2M(TWIP_REP_START) | S2M(TWIP_SLA_W) | S2M(TWIP_READ))
@ -752,13 +794,13 @@ void IRAM_ATTR Twi::onSclChange(void)
}
else
{
SCL_LOW(twi.twi_scl); // clock stretching
SCL_LOW(twi.twi_scl); // clock stretching
SDA_HIGH(twi.twi_sda);
twi.twip_mode = TWIPM_ADDRESSED;
if (!(twi.twi_data & 0x01))
{
twi.onTwipEvent(TW_SR_SLA_ACK);
twi.bitCount = 8;
twi.bitCount = 8;
twi.twip_state = TWIP_SLA_W;
}
else
@ -770,18 +812,18 @@ void IRAM_ATTR Twi::onSclChange(void)
}
else
{
SCL_LOW(twi.twi_scl); // clock stretching
SCL_LOW(twi.twi_scl); // clock stretching
SDA_HIGH(twi.twi_sda);
if (!twi.twi_ack)
{
twi.onTwipEvent(TW_SR_DATA_NACK);
twi.twip_mode = TWIPM_WAIT;
twi.twip_mode = TWIPM_WAIT;
twi.twip_state = TWIP_WAIT_STOP;
}
else
{
twi.onTwipEvent(TW_SR_DATA_ACK);
twi.bitCount = 8;
twi.bitCount = 8;
twi.twip_state = TWIP_READ;
}
}
@ -837,7 +879,7 @@ void IRAM_ATTR Twi::onSclChange(void)
else
{
twi.twi_ack_rec = !sda;
twi.twip_state = TWIP_RWAIT_ACK;
twi.twip_state = TWIP_RWAIT_ACK;
}
}
else IFSTATE(S2M(TWIP_RWAIT_ACK))
@ -848,7 +890,7 @@ void IRAM_ATTR Twi::onSclChange(void)
}
else
{
SCL_LOW(twi.twi_scl); // clock stretching
SCL_LOW(twi.twi_scl); // clock stretching
if (twi.twi_ack && twi.twi_ack_rec)
{
twi.onTwipEvent(TW_ST_DATA_ACK);
@ -858,7 +900,7 @@ void IRAM_ATTR Twi::onSclChange(void)
{
// we have no more data to send and/or the master doesn't want anymore
twi.onTwipEvent(twi.twi_ack_rec ? TW_ST_LAST_DATA : TW_ST_DATA_NACK);
twi.twip_mode = TWIPM_WAIT;
twi.twip_mode = TWIPM_WAIT;
twi.twip_state = TWIP_WAIT_STOP;
}
}
@ -875,7 +917,7 @@ void IRAM_ATTR Twi::onSdaChange(void)
scl = SCL_READ(twi.twi_scl);
int twip_state_mask = S2M(twi.twip_state);
if (scl) /* !DATA */
if (scl) /* !DATA */
{
IFSTATE(S2M(TWIP_IDLE))
{
@ -886,17 +928,19 @@ void IRAM_ATTR Twi::onSdaChange(void)
else
{
// START
twi.bitCount = 8;
twi.bitCount = 8;
twi.twip_state = TWIP_START;
ets_timer_arm_new(&twi.timer, twi.twi_timeout_ms, false, true); // Once, ms
ets_timer_arm_new(&twi.timer, twi.twi_timeout_ms, false, true); // Once, ms
}
}
else IFSTATE(S2M(TWIP_START) | S2M(TWIP_REP_START) | S2M(TWIP_SEND_ACK) | S2M(TWIP_WAIT_ACK) | S2M(TWIP_SLA_R) | S2M(TWIP_REC_ACK) | S2M(TWIP_READ_ACK) | S2M(TWIP_RWAIT_ACK) | S2M(TWIP_WRITE))
else IFSTATE(S2M(TWIP_START) | S2M(TWIP_REP_START) | S2M(TWIP_SEND_ACK) | S2M(TWIP_WAIT_ACK)
| S2M(TWIP_SLA_R) | S2M(TWIP_REC_ACK) | S2M(TWIP_READ_ACK)
| S2M(TWIP_RWAIT_ACK) | S2M(TWIP_WRITE))
{
// START or STOP
SDA_HIGH(twi.twi_sda); // Should not be necessary
SDA_HIGH(twi.twi_sda); // Should not be necessary
twi.onTwipEvent(TW_BUS_ERROR);
twi.twip_mode = TWIPM_WAIT;
twi.twip_mode = TWIPM_WAIT;
twi.twip_state = TWIP_BUS_ERR;
}
else IFSTATE(S2M(TWIP_WAIT_STOP) | S2M(TWIP_BUS_ERR))
@ -904,10 +948,10 @@ void IRAM_ATTR Twi::onSdaChange(void)
if (sda)
{
// STOP
SCL_LOW(twi.twi_scl); // generates a low SCL pulse after STOP
SCL_LOW(twi.twi_scl); // generates a low SCL pulse after STOP
ets_timer_disarm(&twi.timer);
twi.twip_state = TWIP_IDLE;
twi.twip_mode = TWIPM_IDLE;
twi.twip_mode = TWIPM_IDLE;
SCL_HIGH(twi.twi_scl);
}
else
@ -919,9 +963,9 @@ void IRAM_ATTR Twi::onSdaChange(void)
}
else
{
twi.bitCount = 8;
twi.bitCount = 8;
twi.twip_state = TWIP_REP_START;
ets_timer_arm_new(&twi.timer, twi.twi_timeout_ms, false, true); // Once, ms
ets_timer_arm_new(&twi.timer, twi.twi_timeout_ms, false, true); // Once, ms
}
}
}
@ -932,28 +976,28 @@ void IRAM_ATTR Twi::onSdaChange(void)
{
// inside byte transfer - error
twi.onTwipEvent(TW_BUS_ERROR);
twi.twip_mode = TWIPM_WAIT;
twi.twip_mode = TWIPM_WAIT;
twi.twip_state = TWIP_BUS_ERR;
}
else
{
// during first bit in byte transfer - ok
SCL_LOW(twi.twi_scl); // clock stretching
SCL_LOW(twi.twi_scl); // clock stretching
twi.onTwipEvent(TW_SR_STOP);
if (sda)
{
// STOP
ets_timer_disarm(&twi.timer);
twi.twip_state = TWIP_IDLE;
twi.twip_mode = TWIPM_IDLE;
twi.twip_mode = TWIPM_IDLE;
}
else
{
// START
twi.bitCount = 8;
ets_timer_arm_new(&twi.timer, twi.twi_timeout_ms, false, true); // Once, ms
ets_timer_arm_new(&twi.timer, twi.twi_timeout_ms, false, true); // Once, ms
twi.twip_state = TWIP_REP_START;
twi.twip_mode = TWIPM_IDLE;
twi.twip_mode = TWIPM_IDLE;
}
}
}
@ -961,8 +1005,8 @@ void IRAM_ATTR Twi::onSdaChange(void)
}
// C wrappers for the object, since API is exposed only as C
extern "C" {
extern "C"
{
void twi_init(unsigned char sda, unsigned char scl)
{
return twi.init(sda, scl);
@ -983,12 +1027,14 @@ extern "C" {
twi.setClockStretchLimit(limit);
}
uint8_t twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop)
uint8_t twi_writeTo(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop)
{
return twi.writeTo(address, buf, len, sendStop);
}
uint8_t twi_readFrom(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop)
uint8_t twi_readFrom(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop)
{
return twi.readFrom(address, buf, len, sendStop);
}
@ -998,7 +1044,7 @@ extern "C" {
return twi.status();
}
uint8_t twi_transmit(const uint8_t * buf, uint8_t len)
uint8_t twi_transmit(const uint8_t* buf, uint8_t len)
{
return twi.transmit(buf, len);
}
@ -1027,5 +1073,4 @@ extern "C" {
{
twi.enableSlave();
}
};

View File

@ -30,7 +30,7 @@ void __iamslow(const char* what)
#endif
IRAM_ATTR
void hexdump(const void *mem, uint32_t len, uint8_t cols)
void hexdump(const void* mem, uint32_t len, uint8_t cols)
{
const char* src = (const char*)mem;
os_printf("\n[HEXDUMP] Address: %p len: 0x%X (%d)", src, len, len);

View File

@ -5,44 +5,54 @@
#include <stdint.h>
#ifdef DEBUG_ESP_CORE
#define DEBUGV(fmt, ...) ::printf((PGM_P)PSTR(fmt), ## __VA_ARGS__)
#define DEBUGV(fmt, ...) ::printf((PGM_P)PSTR(fmt), ##__VA_ARGS__)
#endif
#ifndef DEBUGV
#define DEBUGV(...) do { (void)0; } while (0)
#define DEBUGV(...) \
do \
{ \
(void)0; \
} while (0)
#endif
#ifdef __cplusplus
extern "C" void hexdump(const void *mem, uint32_t len, uint8_t cols = 16);
extern "C" void hexdump(const void* mem, uint32_t len, uint8_t cols = 16);
#else
void hexdump(const void *mem, uint32_t len, uint8_t cols);
void hexdump(const void* mem, uint32_t len, uint8_t cols);
#endif
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
void __unhandled_exception(const char *str) __attribute__((noreturn));
void __panic_func(const char* file, int line, const char* func) __attribute__((noreturn));
void __unhandled_exception(const char* str) __attribute__((noreturn));
void __panic_func(const char* file, int line, const char* func) __attribute__((noreturn));
#define panic() __panic_func(PSTR(__FILE__), __LINE__, __func__)
#ifdef DEBUG_ESP_CORE
extern void __iamslow(const char* what);
#define IAMSLOW() \
do { \
static bool once = false; \
if (!once) { \
once = true; \
__iamslow((PGM_P)FPSTR(__FUNCTION__)); \
} \
extern void __iamslow(const char* what);
#define IAMSLOW() \
do \
{ \
static bool once = false; \
if (!once) \
{ \
once = true; \
__iamslow((PGM_P)FPSTR(__FUNCTION__)); \
} \
} while (0)
#else
#define IAMSLOW() do { (void)0; } while (0)
#define IAMSLOW() \
do \
{ \
(void)0; \
} while (0)
#endif
#ifdef __cplusplus
}
#endif
#endif//ARD_DEBUG_H
#endif // ARD_DEBUG_H

View File

@ -5,7 +5,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -39,7 +39,7 @@ void setup() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
} else { // U_FS
type = "filesystem";
}

View File

@ -5,7 +5,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -14,7 +14,7 @@ const char* host = "OTA-LEDS";
int led_pin = 13;
#define N_DIMMERS 3
int dimmer_pin[] = {14, 5, 15};
int dimmer_pin[] = { 14, 5, 15 };
void setup() {
Serial.begin(115200);
@ -45,14 +45,14 @@ void setup() {
}
ArduinoOTA.setHostname(host);
ArduinoOTA.onStart([]() { // switch off all the PWMs during upgrade
ArduinoOTA.onStart([]() { // switch off all the PWMs during upgrade
for (int i = 0; i < N_DIMMERS; i++) {
analogWrite(dimmer_pin[i], 0);
}
analogWrite(led_pin, 0);
});
ArduinoOTA.onEnd([]() { // do a fancy thing with our board led at end
ArduinoOTA.onEnd([]() { // do a fancy thing with our board led at end
for (int i = 0; i < 30; i++) {
analogWrite(led_pin, (i * 100) % 1001);
delay(50);
@ -67,7 +67,6 @@ void setup() {
/* setup the OTA server */
ArduinoOTA.begin();
Serial.println("Ready");
}
void loop() {

View File

@ -20,7 +20,7 @@
/* Set these to your desired softAP credentials. They are not configurable at runtime */
#ifndef APSSID
#define APSSID "ESP_ap"
#define APPSK "12345678"
#define APPSK "12345678"
#endif
const char *softAP_ssid = APSSID;
@ -62,7 +62,7 @@ void setup() {
/* You can remove the password parameter if you want the AP to be open. */
WiFi.softAPConfig(apIP, apIP, netMsk);
WiFi.softAP(softAP_ssid, softAP_password);
delay(500); // Without delay I've seen the IP address blank
delay(500); // Without delay I've seen the IP address blank
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
@ -74,13 +74,13 @@ void setup() {
server.on("/", handleRoot);
server.on("/wifi", handleWifi);
server.on("/wifisave", handleWifiSave);
server.on("/generate_204", handleRoot); //Android captive portal. Maybe not needed. Might be handled by notFound handler.
server.on("/fwlink", handleRoot); //Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
server.on("/generate_204", handleRoot); // Android captive portal. Maybe not needed. Might be handled by notFound handler.
server.on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
server.onNotFound(handleNotFound);
server.begin(); // Web server start
server.begin(); // Web server start
Serial.println("HTTP server started");
loadCredentials(); // Load WLAN credentials from network
connect = strlen(ssid) > 0; // Request WLAN connect if there is a SSID
loadCredentials(); // Load WLAN credentials from network
connect = strlen(ssid) > 0; // Request WLAN connect if there is a SSID
}
void connectWifi() {
@ -106,7 +106,7 @@ void loop() {
/* Don't set retry time too low as retry interfere the softAP operation */
connect = true;
}
if (status != s) { // WLAN status change
if (status != s) { // WLAN status change
Serial.print("Status: ");
Serial.println(s);
status = s;
@ -130,13 +130,11 @@ void loop() {
WiFi.disconnect();
}
}
if (s == WL_CONNECTED) {
MDNS.update();
}
if (s == WL_CONNECTED) { MDNS.update(); }
}
// Do work:
//DNS
// DNS
dnsServer.processNextRequest();
//HTTP
// HTTP
server.handleClient();
}

View File

@ -1,6 +1,6 @@
/** Handle root or redirect to captive portal */
void handleRoot() {
if (captivePortal()) { // If caprive portal redirect instead of displaying the page.
if (captivePortal()) { // If caprive portal redirect instead of displaying the page.
return;
}
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
@ -8,8 +8,7 @@ void handleRoot() {
server.sendHeader("Expires", "-1");
String Page;
Page += F(
"<!DOCTYPE html><html lang='en'><head>"
Page += F("<!DOCTYPE html><html lang='en'><head>"
"<meta name='viewport' content='width=device-width'>"
"<title>CaptivePortal</title></head><body>"
"<h1>HELLO WORLD!!</h1>");
@ -18,8 +17,7 @@ void handleRoot() {
} else {
Page += String(F("<p>You are connected through the wifi network: ")) + ssid + F("</p>");
}
Page += F(
"<p>You may want to <a href='/wifi'>config the wifi connection</a>.</p>"
Page += F("<p>You may want to <a href='/wifi'>config the wifi connection</a>.</p>"
"</body></html>");
server.send(200, "text/html", Page);
@ -30,8 +28,8 @@ boolean captivePortal() {
if (!isIp(server.hostHeader()) && server.hostHeader() != (String(myHostname) + ".local")) {
Serial.println("Request redirected to captive portal");
server.sendHeader("Location", String("http://") + toStringIp(server.client().localIP()), true);
server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server.client().stop(); // Stop is needed because we sent no content length
server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server.client().stop(); // Stop is needed because we sent no content length
return true;
}
return false;
@ -44,8 +42,7 @@ void handleWifi() {
server.sendHeader("Expires", "-1");
String Page;
Page += F(
"<!DOCTYPE html><html lang='en'><head>"
Page += F("<!DOCTYPE html><html lang='en'><head>"
"<meta name='viewport' content='width=device-width'>"
"<title>CaptivePortal</title></head><body>"
"<h1>Wifi config</h1>");
@ -54,40 +51,31 @@ void handleWifi() {
} else {
Page += String(F("<p>You are connected through the wifi network: ")) + ssid + F("</p>");
}
Page +=
String(F(
"\r\n<br />"
"<table><tr><th align='left'>SoftAP config</th></tr>"
"<tr><td>SSID ")) +
String(softAP_ssid) +
F("</td></tr>"
"<tr><td>IP ") +
toStringIp(WiFi.softAPIP()) +
F("</td></tr>"
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN config</th></tr>"
"<tr><td>SSID ") +
String(ssid) +
F("</td></tr>"
"<tr><td>IP ") +
toStringIp(WiFi.localIP()) +
F("</td></tr>"
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN list (refresh if any missing)</th></tr>");
Page += String(F("\r\n<br />"
"<table><tr><th align='left'>SoftAP config</th></tr>"
"<tr><td>SSID "))
+ String(softAP_ssid) + F("</td></tr>"
"<tr><td>IP ")
+ toStringIp(WiFi.softAPIP()) + F("</td></tr>"
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN config</th></tr>"
"<tr><td>SSID ")
+ String(ssid) + F("</td></tr>"
"<tr><td>IP ")
+ toStringIp(WiFi.localIP()) + F("</td></tr>"
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN list (refresh if any missing)</th></tr>");
Serial.println("scan start");
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n > 0) {
for (int i = 0; i < n; i++) {
Page += String(F("\r\n<tr><td>SSID ")) + WiFi.SSID(i) + ((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? F(" ") : F(" *")) + F(" (") + WiFi.RSSI(i) + F(")</td></tr>");
}
for (int i = 0; i < n; i++) { Page += String(F("\r\n<tr><td>SSID ")) + WiFi.SSID(i) + ((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? F(" ") : F(" *")) + F(" (") + WiFi.RSSI(i) + F(")</td></tr>"); }
} else {
Page += F("<tr><td>No WLAN found</td></tr>");
}
Page += F(
"</table>"
Page += F("</table>"
"\r\n<br /><form method='POST' action='wifisave'><h4>Connect to network:</h4>"
"<input type='text' placeholder='network' name='n'/>"
"<br /><input type='password' placeholder='password' name='p'/>"
@ -95,7 +83,7 @@ void handleWifi() {
"<p>You may want to <a href='/'>return to the home page</a>.</p>"
"</body></html>");
server.send(200, "text/html", Page);
server.client().stop(); // Stop is needed because we sent no content length
server.client().stop(); // Stop is needed because we sent no content length
}
/** Handle the WLAN save form and redirect to WLAN config page again */
@ -107,14 +95,14 @@ void handleWifiSave() {
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server.client().stop(); // Stop is needed because we sent no content length
server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server.client().stop(); // Stop is needed because we sent no content length
saveCredentials();
connect = strlen(ssid) > 0; // Request WLAN connect with new credentials if there is a SSID
connect = strlen(ssid) > 0; // Request WLAN connect with new credentials if there is a SSID
}
void handleNotFound() {
if (captivePortal()) { // If caprive portal redirect instead of displaying the error page.
if (captivePortal()) { // If caprive portal redirect instead of displaying the error page.
return;
}
String message = F("File Not Found\n\n");
@ -126,9 +114,7 @@ void handleNotFound() {
message += server.args();
message += F("\n");
for (uint8_t i = 0; i < server.args(); i++) {
message += String(F(" ")) + server.argName(i) + F(": ") + server.arg(i) + F("\n");
}
for (uint8_t i = 0; i < server.args(); i++) { message += String(F(" ")) + server.argName(i) + F(": ") + server.arg(i) + F("\n"); }
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");

View File

@ -2,9 +2,7 @@
boolean isIp(String str) {
for (size_t i = 0; i < str.length(); i++) {
int c = str.charAt(i);
if (c != '.' && (c < '0' || c > '9')) {
return false;
}
if (c != '.' && (c < '0' || c > '9')) { return false; }
}
return true;
}
@ -12,10 +10,7 @@ boolean isIp(String str) {
/** IP to String? */
String toStringIp(IPAddress ip) {
String res = "";
for (int i = 0; i < 3; i++) {
res += String((ip >> (8 * i)) & 0xFF) + ".";
}
for (int i = 0; i < 3; i++) { res += String((ip >> (8 * i)) & 0xFF) + "."; }
res += String(((ip >> 8 * 3)) & 0xFF);
return res;
}

View File

@ -11,9 +11,7 @@
void setup() {
EEPROM.begin(512);
// write a 0 to all 512 bytes of the EEPROM
for (int i = 0; i < 512; i++) {
EEPROM.write(i, 0);
}
for (int i = 0; i < 512; i++) { EEPROM.write(i, 0); }
// turn the LED on when we're done
pinMode(13, OUTPUT);
@ -21,5 +19,4 @@ void setup() {
EEPROM.end();
}
void loop() {
}
void loop() {}

View File

@ -32,9 +32,7 @@ void loop() {
// there are only 512 bytes of EEPROM, from 0 to 511, so if we're
// on address 512, wrap around to address 0
if (address == 512) {
address = 0;
}
if (address == 512) { address = 0; }
delay(500);
}

View File

@ -5,7 +5,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* host = "esp8266-avrisp";
@ -20,7 +20,7 @@ void setup() {
Serial.begin(115200);
Serial.println("");
Serial.println("Arduino AVR-ISP over TCP");
avrprog.setReset(false); // let the AVR run
avrprog.setReset(false); // let the AVR run
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
@ -51,17 +51,20 @@ void loop() {
AVRISPState_t new_state = avrprog.update();
if (last_state != new_state) {
switch (new_state) {
case AVRISP_STATE_IDLE: {
case AVRISP_STATE_IDLE:
{
Serial.printf("[AVRISP] now idle\r\n");
// Use the SPI bus for other purposes
break;
}
case AVRISP_STATE_PENDING: {
case AVRISP_STATE_PENDING:
{
Serial.printf("[AVRISP] connection pending\r\n");
// Clean up your other purposes and prepare for programming mode
break;
}
case AVRISP_STATE_ACTIVE: {
case AVRISP_STATE_ACTIVE:
{
Serial.printf("[AVRISP] programming mode\r\n");
// Stand by for completion
break;
@ -70,11 +73,7 @@ void loop() {
last_state = new_state;
}
// Serve the client
if (last_state != AVRISP_STATE_IDLE) {
avrprog.serve();
}
if (last_state != AVRISP_STATE_IDLE) { avrprog.serve(); }
if (WiFi.status() == WL_CONNECTED) {
MDNS.update();
}
if (WiFi.status() == WL_CONNECTED) { MDNS.update(); }
}

View File

@ -33,7 +33,6 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {

View File

@ -33,7 +33,6 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {

View File

@ -14,7 +14,7 @@
#include <WiFiClientSecureBearSSL.h>
// Fingerprint for demo URL, expires on June 2, 2021, needs to be updated well before this date
const uint8_t fingerprint[20] = {0x40, 0xaf, 0x00, 0x6b, 0xec, 0x90, 0x22, 0x41, 0x8e, 0xa3, 0xad, 0xfa, 0x1a, 0xe8, 0x25, 0x41, 0x1d, 0x1a, 0x54, 0xb3};
const uint8_t fingerprint[20] = { 0x40, 0xaf, 0x00, 0x6b, 0xec, 0x90, 0x22, 0x41, 0x8e, 0xa3, 0xad, 0xfa, 0x1a, 0xe8, 0x25, 0x41, 0x1d, 0x1a, 0x54, 0xb3 };
ESP8266WiFiMulti WiFiMulti;
@ -41,7 +41,7 @@ void loop() {
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED)) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
std::unique_ptr<BearSSL::WiFiClientSecure> client(new BearSSL::WiFiClientSecure);
client->setFingerprint(fingerprint);
// Or, if you happy to ignore the SSL certificate, then use the following line instead:

View File

@ -13,36 +13,31 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* ssidPassword = STAPSK;
const char *username = "admin";
const char *password = "admin";
const char* username = "admin";
const char* password = "admin";
const char *server = "http://httpbin.org";
const char *uri = "/digest-auth/auth/admin/admin/MD5";
const char* server = "http://httpbin.org";
const char* uri = "/digest-auth/auth/admin/admin/MD5";
String exractParam(String& authReq, const String& param, const char delimit) {
int _begin = authReq.indexOf(param);
if (_begin == -1) {
return "";
}
if (_begin == -1) { return ""; }
return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length()));
}
String getCNonce(const int len) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
static const char alphanum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
String s = "";
for (int i = 0; i < len; ++i) {
s += alphanum[rand() % (sizeof(alphanum) - 1)];
}
for (int i = 0; i < len; ++i) { s += alphanum[rand() % (sizeof(alphanum) - 1)]; }
return s;
}
@ -73,8 +68,7 @@ String getDigestAuth(String& authReq, const String& username, const String& pass
md5.calculate();
String response = md5.toString();
String authorization = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce +
"\", uri=\"" + uri + "\", algorithm=\"MD5\", qop=auth, nc=" + String(nc) + ", cnonce=\"" + cNonce + "\", response=\"" + response + "\"";
String authorization = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + uri + "\", algorithm=\"MD5\", qop=auth, nc=" + String(nc) + ", cnonce=\"" + cNonce + "\", response=\"" + response + "\"";
Serial.println(authorization);
return authorization;
@ -100,7 +94,7 @@ void setup() {
void loop() {
WiFiClient client;
HTTPClient http; //must be declared after WiFiClient for correct destruction order, because used by http.begin(client,...)
HTTPClient http; // must be declared after WiFiClient for correct destruction order, because used by http.begin(client,...)
Serial.print("[HTTP] begin...\n");
@ -108,7 +102,7 @@ void loop() {
http.begin(client, String(server) + String(uri));
const char *keys[] = {"WWW-Authenticate"};
const char* keys[] = { "WWW-Authenticate" };
http.collectHeaders(keys, 1);
Serial.print("[HTTP] GET...\n");

View File

@ -20,7 +20,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
void setup() {
@ -40,7 +40,6 @@ void setup() {
Serial.println("");
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
@ -52,7 +51,7 @@ void loop() {
Serial.print("[HTTP] begin...\n");
// configure traged server and url
http.begin(client, "http://" SERVER_IP "/postplain/"); //HTTP
http.begin(client, "http://" SERVER_IP "/postplain/"); // HTTP
http.addHeader("Content-Type", "application/json");
Serial.print("[HTTP] POST...\n");

View File

@ -13,7 +13,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
ESP8266WiFiMulti WiFiMulti;
@ -45,7 +45,7 @@ void setup() {
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html");
//http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
// http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
}
int pass = 0;
@ -60,15 +60,13 @@ void loop() {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK) {
http.writeToStream(&Serial);
}
if (httpCode == HTTP_CODE_OK) { http.writeToStream(&Serial); }
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
// Something went wrong with the connection, try to reconnect
http.end();
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html");
//http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
// http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
}
if (pass == 10) {

View File

@ -31,7 +31,6 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {
@ -39,13 +38,13 @@ void loop() {
if ((WiFiMulti.run() == WL_CONNECTED)) {
WiFiClient client;
HTTPClient http; //must be declared after WiFiClient for correct destruction order, because used by http.begin(client,...)
HTTPClient http; // must be declared after WiFiClient for correct destruction order, because used by http.begin(client,...)
Serial.print("[HTTP] begin...\n");
// configure server and url
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html");
//http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
// http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
Serial.print("[HTTP] GET...\n");
// start connection and send HTTP header
@ -70,23 +69,19 @@ void loop() {
// or "by hand"
// get tcp stream
WiFiClient * stream = &client;
WiFiClient* stream = &client;
// read all data from server
while (http.connected() && (len > 0 || len == -1)) {
// read up to 128 byte
int c = stream->readBytes(buff, std::min((size_t)len, sizeof(buff)));
Serial.printf("readBytes: %d\n", c);
if (!c) {
Serial.println("read timeout");
}
if (!c) { Serial.println("read timeout"); }
// write it to Serial
Serial.write(buff, c);
if (len > 0) {
len -= c;
}
if (len > 0) { len -= c; }
}
#endif

View File

@ -31,7 +31,6 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {
@ -43,14 +42,12 @@ void loop() {
bool mfln = client->probeMaxFragmentLength("tls.mbed.org", 443, 1024);
Serial.printf("\nConnecting to https://tls.mbed.org\n");
Serial.printf("Maximum fragment Length negotiation supported: %s\n", mfln ? "yes" : "no");
if (mfln) {
client->setBufferSizes(1024, 1024);
}
if (mfln) { client->setBufferSizes(1024, 1024); }
Serial.print("[HTTPS] begin...\n");
// configure server and url
const uint8_t fingerprint[20] = {0x15, 0x77, 0xdc, 0x04, 0x7c, 0x00, 0xf8, 0x70, 0x09, 0x34, 0x24, 0xf4, 0xd3, 0xa1, 0x7a, 0x6c, 0x1e, 0xa3, 0xe0, 0x2a};
const uint8_t fingerprint[20] = { 0x15, 0x77, 0xdc, 0x04, 0x7c, 0x00, 0xf8, 0x70, 0x09, 0x34, 0x24, 0xf4, 0xd3, 0xa1, 0x7a, 0x6c, 0x1e, 0xa3, 0xe0, 0x2a };
client->setFingerprint(fingerprint);
@ -86,16 +83,13 @@ void loop() {
// write it to Serial
Serial.write(buff, c);
if (len > 0) {
len -= c;
}
if (len > 0) { len -= c; }
}
delay(1);
}
Serial.println();
Serial.print("[HTTPS] connection closed or file end.\n");
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());

View File

@ -21,7 +21,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* host = "esp8266-webupdate";
@ -57,7 +57,7 @@ JfUvYadSYxh3nblvA4OL+iEZiW8NE3hbW6WPXxvS7Euge0uWMPc4uEcnsE0ZVG3m
-----END CERTIFICATE-----
)EOF";
static const char serverKey[] PROGMEM = R"EOF(
static const char serverKey[] PROGMEM = R"EOF(
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA9UoHBtn4oNKXjRgIOQ/rLxK/iI0a8Q5mDxhfuwa9//FkftSI
IFY8UhGk2YNJpnfKOyYWqbqwuJhIZJ2sEIWp2301OnavuGBrpKOgBJJljgH2l/4Z
@ -88,8 +88,7 @@ gz5JWYhbD6c38khSzJb0pNXCo3EuYAVa36kDM96k1BtWuhRS10Q1VXk=
)EOF";
void setup()
{
void setup() {
Serial.begin(115200);
Serial.println();
@ -97,7 +96,7 @@ void setup()
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
while(WiFi.waitForConnectResult() != WL_CONNECTED){
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
Serial.println("WiFi failed, retrying.");
}
@ -111,13 +110,13 @@ void setup()
httpServer.begin();
MDNS.addService("https", "tcp", 443);
Serial.printf("BearSSLUpdateServer ready!\nOpen https://%s.local%s in "\
"your browser and login with username '%s' and password "\
"'%s'\n", host, update_path, update_username, update_password);
Serial.printf("BearSSLUpdateServer ready!\nOpen https://%s.local%s in "
"your browser and login with username '%s' and password "
"'%s'\n",
host, update_path, update_username, update_password);
}
void loop()
{
void loop() {
httpServer.handleClient();
MDNS.update();
}

View File

@ -10,7 +10,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* host = "esp8266-webupdate";

View File

@ -10,7 +10,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* host = "esp8266-webupdate";

View File

@ -62,7 +62,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;

View File

@ -4,7 +4,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;

View File

@ -4,7 +4,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -46,9 +46,7 @@ void setup() {
Serial.printf("Ready!\n");
} else {
Serial.printf("WiFi Failed\n");
while (1) {
delay(100);
}
while (1) { delay(100); }
}
}

View File

@ -35,7 +35,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -69,8 +69,7 @@ void handleRoot() {
</body>\
</html>",
hr, min % 60, sec % 60
);
hr, min % 60, sec % 60);
server.send(200, "text/html", temp);
digitalWrite(led, 0);
}
@ -86,9 +85,7 @@ void handleNotFound() {
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
digitalWrite(led, 0);
@ -133,9 +130,7 @@ void setup(void) {
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
@ -151,4 +146,3 @@ void loop(void) {
server.handleClient();
MDNS.update();
}

View File

@ -72,7 +72,7 @@ SDFSConfig fileSystemConfig = SDFSConfig();
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -122,15 +122,9 @@ void replyServerError(String msg) {
*/
String checkForUnsupportedPath(String filename) {
String error = String();
if (!filename.startsWith("/")) {
error += F("!NO_LEADING_SLASH! ");
}
if (filename.indexOf("//") != -1) {
error += F("!DOUBLE_SLASH! ");
}
if (filename.endsWith("/")) {
error += F("!TRAILING_SLASH! ");
}
if (!filename.startsWith("/")) { error += F("!NO_LEADING_SLASH! "); }
if (filename.indexOf("//") != -1) { error += F("!DOUBLE_SLASH! "); }
if (filename.endsWith("/")) { error += F("!TRAILING_SLASH! "); }
return error;
}
#endif
@ -174,18 +168,12 @@ void handleStatus() {
Also demonstrates the use of chunked responses.
*/
void handleFileList() {
if (!fsOK) {
return replyServerError(FPSTR(FS_INIT_ERROR));
}
if (!fsOK) { return replyServerError(FPSTR(FS_INIT_ERROR)); }
if (!server.hasArg("dir")) {
return replyBadRequest(F("DIR ARG MISSING"));
}
if (!server.hasArg("dir")) { return replyBadRequest(F("DIR ARG MISSING")); }
String path = server.arg("dir");
if (path != "/" && !fileSystem->exists(path)) {
return replyBadRequest("BAD PATH");
}
if (path != "/" && !fileSystem->exists(path)) { return replyBadRequest("BAD PATH"); }
DBG_OUTPUT_PORT.println(String("handleFileList: ") + path);
Dir dir = fileSystem->openDir(path);
@ -253,9 +241,7 @@ bool handleFileRead(String path) {
return true;
}
if (path.endsWith("/")) {
path += "index.htm";
}
if (path.endsWith("/")) { path += "index.htm"; }
String contentType;
if (server.hasArg("download")) {
@ -270,9 +256,7 @@ bool handleFileRead(String path) {
}
if (fileSystem->exists(path)) {
File file = fileSystem->open(path, "r");
if (server.streamFile(file, contentType) != file.size()) {
DBG_OUTPUT_PORT.println("Sent less data than expected!");
}
if (server.streamFile(file, contentType) != file.size()) { DBG_OUTPUT_PORT.println("Sent less data than expected!"); }
file.close();
return true;
}
@ -309,27 +293,17 @@ String lastExistingParent(String path) {
Move folder | parent of source folder, or remaining ancestor
*/
void handleFileCreate() {
if (!fsOK) {
return replyServerError(FPSTR(FS_INIT_ERROR));
}
if (!fsOK) { return replyServerError(FPSTR(FS_INIT_ERROR)); }
String path = server.arg("path");
if (path.isEmpty()) {
return replyBadRequest(F("PATH ARG MISSING"));
}
if (path.isEmpty()) { return replyBadRequest(F("PATH ARG MISSING")); }
#ifdef USE_SPIFFS
if (checkForUnsupportedPath(path).length() > 0) {
return replyServerError(F("INVALID FILENAME"));
}
if (checkForUnsupportedPath(path).length() > 0) { return replyServerError(F("INVALID FILENAME")); }
#endif
if (path == "/") {
return replyBadRequest("BAD PATH");
}
if (fileSystem->exists(path)) {
return replyBadRequest(F("PATH FILE EXISTS"));
}
if (path == "/") { return replyBadRequest("BAD PATH"); }
if (fileSystem->exists(path)) { return replyBadRequest(F("PATH FILE EXISTS")); }
String src = server.arg("src");
if (src.isEmpty()) {
@ -338,43 +312,29 @@ void handleFileCreate() {
if (path.endsWith("/")) {
// Create a folder
path.remove(path.length() - 1);
if (!fileSystem->mkdir(path)) {
return replyServerError(F("MKDIR FAILED"));
}
if (!fileSystem->mkdir(path)) { return replyServerError(F("MKDIR FAILED")); }
} else {
// Create a file
File file = fileSystem->open(path, "w");
if (file) {
file.write((const char *)0);
file.write((const char*)0);
file.close();
} else {
return replyServerError(F("CREATE FAILED"));
}
}
if (path.lastIndexOf('/') > -1) {
path = path.substring(0, path.lastIndexOf('/'));
}
if (path.lastIndexOf('/') > -1) { path = path.substring(0, path.lastIndexOf('/')); }
replyOKWithMsg(path);
} else {
// Source specified: rename
if (src == "/") {
return replyBadRequest("BAD SRC");
}
if (!fileSystem->exists(src)) {
return replyBadRequest(F("SRC FILE NOT FOUND"));
}
if (src == "/") { return replyBadRequest("BAD SRC"); }
if (!fileSystem->exists(src)) { return replyBadRequest(F("SRC FILE NOT FOUND")); }
DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path + " from " + src);
if (path.endsWith("/")) {
path.remove(path.length() - 1);
}
if (src.endsWith("/")) {
src.remove(src.length() - 1);
}
if (!fileSystem->rename(src, path)) {
return replyServerError(F("RENAME FAILED"));
}
if (path.endsWith("/")) { path.remove(path.length() - 1); }
if (src.endsWith("/")) { src.remove(src.length() - 1); }
if (!fileSystem->rename(src, path)) { return replyServerError(F("RENAME FAILED")); }
replyOKWithMsg(lastExistingParent(src));
}
}
@ -403,9 +363,7 @@ void deleteRecursive(String path) {
// Otherwise delete its contents first
Dir dir = fileSystem->openDir(path);
while (dir.next()) {
deleteRecursive(path + '/' + dir.fileName());
}
while (dir.next()) { deleteRecursive(path + '/' + dir.fileName()); }
// Then delete the folder itself
fileSystem->rmdir(path);
@ -420,19 +378,13 @@ void deleteRecursive(String path) {
Delete folder | parent of deleted folder, or remaining ancestor
*/
void handleFileDelete() {
if (!fsOK) {
return replyServerError(FPSTR(FS_INIT_ERROR));
}
if (!fsOK) { return replyServerError(FPSTR(FS_INIT_ERROR)); }
String path = server.arg(0);
if (path.isEmpty() || path == "/") {
return replyBadRequest("BAD PATH");
}
if (path.isEmpty() || path == "/") { return replyBadRequest("BAD PATH"); }
DBG_OUTPUT_PORT.println(String("handleFileDelete: ") + path);
if (!fileSystem->exists(path)) {
return replyNotFound(FPSTR(FILE_NOT_FOUND));
}
if (!fileSystem->exists(path)) { return replyNotFound(FPSTR(FILE_NOT_FOUND)); }
deleteRecursive(path);
replyOKWithMsg(lastExistingParent(path));
@ -442,37 +394,25 @@ void handleFileDelete() {
Handle a file upload request
*/
void handleFileUpload() {
if (!fsOK) {
return replyServerError(FPSTR(FS_INIT_ERROR));
}
if (server.uri() != "/edit") {
return;
}
if (!fsOK) { return replyServerError(FPSTR(FS_INIT_ERROR)); }
if (server.uri() != "/edit") { return; }
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
String filename = upload.filename;
// Make sure paths always start with "/"
if (!filename.startsWith("/")) {
filename = "/" + filename;
}
if (!filename.startsWith("/")) { filename = "/" + filename; }
DBG_OUTPUT_PORT.println(String("handleFileUpload Name: ") + filename);
uploadFile = fileSystem->open(filename, "w");
if (!uploadFile) {
return replyServerError(F("CREATE FAILED"));
}
if (!uploadFile) { return replyServerError(F("CREATE FAILED")); }
DBG_OUTPUT_PORT.println(String("Upload: START, filename: ") + filename);
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (uploadFile) {
size_t bytesWritten = uploadFile.write(upload.buf, upload.currentSize);
if (bytesWritten != upload.currentSize) {
return replyServerError(F("WRITE FAILED"));
}
if (bytesWritten != upload.currentSize) { return replyServerError(F("WRITE FAILED")); }
}
DBG_OUTPUT_PORT.println(String("Upload: WRITE, Bytes: ") + upload.currentSize);
} else if (upload.status == UPLOAD_FILE_END) {
if (uploadFile) {
uploadFile.close();
}
if (uploadFile) { uploadFile.close(); }
DBG_OUTPUT_PORT.println(String("Upload: END, Size: ") + upload.totalSize);
}
}
@ -484,15 +424,11 @@ void handleFileUpload() {
and if it fails, return a 404 page with debug information
*/
void handleNotFound() {
if (!fsOK) {
return replyServerError(FPSTR(FS_INIT_ERROR));
}
if (!fsOK) { return replyServerError(FPSTR(FS_INIT_ERROR)); }
String uri = ESP8266WebServer::urlDecode(server.uri()); // required to read paths with blanks
String uri = ESP8266WebServer::urlDecode(server.uri()); // required to read paths with blanks
if (handleFileRead(uri)) {
return;
}
if (handleFileRead(uri)) { return; }
// Dump debug data
String message;
@ -526,9 +462,7 @@ void handleNotFound() {
Otherwise, fails with a 404 page with debug information
*/
void handleGetEdit() {
if (handleFileRead(F("/edit/index.htm"))) {
return;
}
if (handleFileRead(F("/edit/index.htm"))) { return; }
#ifdef INCLUDE_FALLBACK_INDEX_HTM
server.sendHeader(F("Content-Encoding"), "gzip");
@ -536,7 +470,6 @@ void handleGetEdit() {
#else
replyNotFound(FPSTR(FILE_NOT_FOUND));
#endif
}
void setup(void) {
@ -562,9 +495,7 @@ void setup(void) {
String error = checkForUnsupportedPath(dir.fileName());
String fileInfo = dir.fileName() + (dir.isDirectory() ? " [DIR]" : String(" (") + dir.fileSize() + "b)");
DBG_OUTPUT_PORT.println(error + fileInfo);
if (error.length() > 0) {
unsupportedFiles += error + fileInfo + '\n';
}
if (error.length() > 0) { unsupportedFiles += error + fileInfo + '\n'; }
}
DBG_OUTPUT_PORT.println();
@ -609,15 +540,15 @@ void setup(void) {
server.on("/edit", HTTP_GET, handleGetEdit);
// Create file
server.on("/edit", HTTP_PUT, handleFileCreate);
server.on("/edit", HTTP_PUT, handleFileCreate);
// Delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
server.on("/edit", HTTP_DELETE, handleFileDelete);
// Upload file
// - first callback is called after the request has ended with all parsed arguments
// - second callback handles file upload at that location
server.on("/edit", HTTP_POST, replyOK, handleFileUpload);
server.on("/edit", HTTP_POST, replyOK, handleFileUpload);
// Default handler for all URIs not defined above
// Use it to read files from filesystem

View File

@ -58,7 +58,7 @@ SDFSConfig fileSystemConfig = SDFSConfig();
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
// Indicate which digital I/Os should be displayed on the chart.
@ -110,9 +110,7 @@ void replyServerError(String msg) {
bool handleFileRead(String path) {
DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path);
if (path.endsWith("/")) {
path += "index.htm";
}
if (path.endsWith("/")) { path += "index.htm"; }
String contentType = mime::getContentType(path);
@ -122,9 +120,7 @@ bool handleFileRead(String path) {
}
if (fileSystem->exists(path)) {
File file = fileSystem->open(path, "r");
if (server.streamFile(file, contentType) != file.size()) {
DBG_OUTPUT_PORT.println("Sent less data than expected!");
}
if (server.streamFile(file, contentType) != file.size()) { DBG_OUTPUT_PORT.println("Sent less data than expected!"); }
file.close();
return true;
}
@ -139,11 +135,9 @@ bool handleFileRead(String path) {
and if it fails, return a 404 page with debug information
*/
void handleNotFound() {
String uri = ESP8266WebServer::urlDecode(server.uri()); // required to read paths with blanks
String uri = ESP8266WebServer::urlDecode(server.uri()); // required to read paths with blanks
if (handleFileRead(uri)) {
return;
}
if (handleFileRead(uri)) { return; }
// Dump debug data
String message;
@ -218,7 +212,7 @@ void setup(void) {
////////////////////////////////
// WEB SERVER INIT
//get heap status, analog input value and all GPIO statuses in one json call
// get heap status, analog input value and all GPIO statuses in one json call
server.on("/espData", HTTP_GET, []() {
String json;
json.reserve(88);
@ -249,21 +243,18 @@ void setup(void) {
DBG_OUTPUT_PORT.println(" 0 (OFF): outputs are off and hidden from chart");
DBG_OUTPUT_PORT.println(" 1 (AUTO): outputs are rotated automatically every second");
DBG_OUTPUT_PORT.println(" 2 (MANUAL): outputs can be toggled from the web page");
}
// Return default GPIO mask, that is all I/Os except SD card ones
unsigned int defaultMask() {
unsigned int mask = 0b11111111111111111;
for (auto pin = 0; pin <= 16; pin++) {
if (isFlashInterfacePin(pin)) {
mask &= ~(1 << pin);
}
if (isFlashInterfacePin(pin)) { mask &= ~(1 << pin); }
}
return mask;
}
int rgbMode = 1; // 0=off - 1=auto - 2=manual
int rgbMode = 1; // 0=off - 1=auto - 2=manual
int rgbValue = 0;
esp8266::polledTimeout::periodicMs timeToChange(1000);
bool modeChangeRequested = false;
@ -278,28 +269,24 @@ void loop(void) {
}
// see if one second has passed since last change, otherwise stop here
if (!timeToChange) {
return;
}
if (!timeToChange) { return; }
// see if a mode change was requested
if (modeChangeRequested) {
// increment mode (reset after 2)
rgbMode++;
if (rgbMode > 2) {
rgbMode = 0;
}
if (rgbMode > 2) { rgbMode = 0; }
modeChangeRequested = false;
}
// act according to mode
switch (rgbMode) {
case 0: // off
case 0: // off
gpioMask = defaultMask();
gpioMask &= ~(1 << 12); // Hide GPIO 12
gpioMask &= ~(1 << 13); // Hide GPIO 13
gpioMask &= ~(1 << 15); // Hide GPIO 15
gpioMask &= ~(1 << 12); // Hide GPIO 12
gpioMask &= ~(1 << 13); // Hide GPIO 13
gpioMask &= ~(1 << 15); // Hide GPIO 15
// reset outputs
digitalWrite(12, 0);
@ -307,14 +294,12 @@ void loop(void) {
digitalWrite(15, 0);
break;
case 1: // auto
case 1: // auto
gpioMask = defaultMask();
// increment value (reset after 7)
rgbValue++;
if (rgbValue > 7) {
rgbValue = 0;
}
if (rgbValue > 7) { rgbValue = 0; }
// output new values
digitalWrite(12, rgbValue & 0b001);
@ -322,11 +307,10 @@ void loop(void) {
digitalWrite(15, rgbValue & 0b100);
break;
case 2: // manual
case 2: // manual
gpioMask = defaultMask();
// keep outputs unchanged
break;
}
}

View File

@ -5,7 +5,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -31,9 +31,7 @@ void handleNotFound() {
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
@ -57,9 +55,7 @@ void setup(void) {
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
server.on("/", handleRoot);
@ -89,17 +85,17 @@ void setup(void) {
/////////////////////////////////////////////////////////
// Hook examples
server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) {
(void)method; // GET, PUT, ...
(void)url; // example: /root/myfile.html
(void)client; // the webserver tcp client connection
(void)contentType; // contentType(".html") => "text/html"
server.addHook([](const String& method, const String& url, WiFiClient* client, ESP8266WebServer::ContentTypeFunction contentType) {
(void)method; // GET, PUT, ...
(void)url; // example: /root/myfile.html
(void)client; // the webserver tcp client connection
(void)contentType; // contentType(".html") => "text/html"
Serial.printf("A useless web hook has passed\n");
Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter());
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
server.addHook([](const String&, const String & url, WiFiClient*, ESP8266WebServer::ContentTypeFunction) {
server.addHook([](const String&, const String& url, WiFiClient*, ESP8266WebServer::ContentTypeFunction) {
if (url.startsWith("/fail")) {
Serial.printf("An always failing web hook has been triggered\n");
return ESP8266WebServer::CLIENT_MUST_STOP;
@ -107,7 +103,7 @@ void setup(void) {
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
server.addHook([](const String&, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction) {
server.addHook([](const String&, const String& url, WiFiClient* client, ESP8266WebServer::ContentTypeFunction) {
if (url.startsWith("/dump")) {
Serial.printf("The dumper web hook is on the run\n");
@ -137,7 +133,7 @@ void setup(void) {
// check the client connection: it should not immediately be closed
// (make another '/dump' one to close the first)
Serial.printf("\nTelling server to forget this connection\n");
static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter
static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter
return ESP8266WebServer::CLIENT_IS_GIVEN;
}
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;

View File

@ -18,7 +18,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -50,7 +50,7 @@ JfUvYadSYxh3nblvA4OL+iEZiW8NE3hbW6WPXxvS7Euge0uWMPc4uEcnsE0ZVG3m
-----END CERTIFICATE-----
)EOF";
static const char serverKey[] PROGMEM = R"EOF(
static const char serverKey[] PROGMEM = R"EOF(
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA9UoHBtn4oNKXjRgIOQ/rLxK/iI0a8Q5mDxhfuwa9//FkftSI
IFY8UhGk2YNJpnfKOyYWqbqwuJhIZJ2sEIWp2301OnavuGBrpKOgBJJljgH2l/4Z
@ -89,24 +89,22 @@ void handleRoot() {
digitalWrite(led, 0);
}
void handleNotFound(){
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void setup(void){
void setup(void) {
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
@ -127,9 +125,7 @@ void setup(void){
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
server.getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));
@ -138,7 +134,7 @@ void setup(void){
server.on("/", handleRoot);
server.on("/inline", [](){
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
@ -152,17 +148,20 @@ extern "C" void stack_thunk_dump_stack();
void processKey(Print& out, int hotKey) {
switch (hotKey) {
case 'd': {
case 'd':
{
HeapSelectDram ephemeral;
umm_info(NULL, true);
break;
}
case 'i': {
case 'i':
{
HeapSelectIram ephemeral;
umm_info(NULL, true);
break;
}
case 'h': {
case 'h':
{
{
HeapSelectIram ephemeral;
Serial.printf(PSTR("IRAM ESP.getFreeHeap: %u\n"), ESP.getFreeHeap());
@ -185,10 +184,8 @@ void processKey(Print& out, int hotKey) {
out.printf_P(PSTR("Restart, ESP.restart(); ...\r\n"));
ESP.restart();
break;
case '\r':
out.println();
case '\n':
break;
case '\r': out.println();
case '\n': break;
case '?':
out.println();
out.println(F("Press a key + <enter>"));
@ -211,7 +208,7 @@ void processKey(Print& out, int hotKey) {
}
void loop(void){
void loop(void) {
server.handleClient();
MDNS.update();
if (Serial.available() > 0) {

View File

@ -11,7 +11,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -39,13 +39,13 @@ void setup() {
server.on("/", []() {
if (!server.authenticate(www_username, www_password))
//Basic Auth Method with Custom realm and Failure Response
//return server.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
//Digest Auth Method with realm="Login Required" and empty Failure Response
//return server.requestAuthentication(DIGEST_AUTH);
//Digest Auth Method with Custom realm and empty Failure Response
//return server.requestAuthentication(DIGEST_AUTH, www_realm);
//Digest Auth Method with Custom realm and Failure Response
// Basic Auth Method with Custom realm and Failure Response
// return server.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
// Digest Auth Method with realm="Login Required" and empty Failure Response
// return server.requestAuthentication(DIGEST_AUTH);
// Digest Auth Method with Custom realm and empty Failure Response
// return server.requestAuthentication(DIGEST_AUTH, www_realm);
// Digest Auth Method with Custom realm and Failure Response
{
return server.requestAuthentication(DIGEST_AUTH, www_realm, authFailResponse);
}

View File

@ -5,7 +5,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;

View File

@ -15,21 +15,21 @@
#include <ESP8266WiFi.h>
#include <ESP8266WebServerSecure.h>
//Unfortunately it is not possible to have persistent WiFi credentials stored as anything but plain text. Obfuscation would be the only feasible barrier.
// Unfortunately it is not possible to have persistent WiFi credentials stored as anything but plain text. Obfuscation would be the only feasible barrier.
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* wifi_pw = STAPSK;
const String file_credentials = R"(/credentials.txt)"; // LittleFS file name for the saved credentials
const String change_creds = "changecreds"; // Address for a credential change
const String file_credentials = R"(/credentials.txt)"; // LittleFS file name for the saved credentials
const String change_creds = "changecreds"; // Address for a credential change
//The ESP8266WebServerSecure requires an encryption certificate and matching key.
//These can generated with the bash script available in the ESP8266 Arduino repository.
//These values can be used for testing but are available publicly so should not be used in production.
// The ESP8266WebServerSecure requires an encryption certificate and matching key.
// These can generated with the bash script available in the ESP8266 Arduino repository.
// These values can be used for testing but are available publicly so should not be used in production.
static const char serverCert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDSzCCAjMCCQD2ahcfZAwXxDANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMC
@ -52,7 +52,7 @@ JfUvYadSYxh3nblvA4OL+iEZiW8NE3hbW6WPXxvS7Euge0uWMPc4uEcnsE0ZVG3m
5tAF1D5vAAwA8nfPysumlLsIjohJZo4lgnhB++AlOg==
-----END CERTIFICATE-----
)EOF";
static const char serverKey[] PROGMEM = R"EOF(
static const char serverKey[] PROGMEM = R"EOF(
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA9UoHBtn4oNKXjRgIOQ/rLxK/iI0a8Q5mDxhfuwa9//FkftSI
IFY8UhGk2YNJpnfKOyYWqbqwuJhIZJ2sEIWp2301OnavuGBrpKOgBJJljgH2l/4Z
@ -84,7 +84,7 @@ gz5JWYhbD6c38khSzJb0pNXCo3EuYAVa36kDM96k1BtWuhRS10Q1VXk=
ESP8266WebServerSecure server(443);
//These are temporary credentials that will only be used if none are found saved in LittleFS.
// These are temporary credentials that will only be used if none are found saved in LittleFS.
String login = "admin";
const String realm = "global";
String H1 = "";
@ -93,16 +93,16 @@ String authentication_failed = "User authentication has failed.";
void setup() {
Serial.begin(115200);
//Initialize LittleFS to save credentials
if(!LittleFS.begin()){
Serial.println("LittleFS initialization error, programmer flash configured?");
// Initialize LittleFS to save credentials
if (!LittleFS.begin()) {
Serial.println("LittleFS initialization error, programmer flash configured?");
ESP.restart();
}
}
//Attempt to load credentials. If the file does not yet exist, they will be set to the default values above
// Attempt to load credentials. If the file does not yet exist, they will be set to the default values above
loadcredentials();
//Initialize wifi
// Initialize wifi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, wifi_pw);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
@ -112,8 +112,8 @@ void setup() {
}
server.getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));
server.on("/",showcredentialpage); //for this simple example, just show a simple page for changing credentials at the root
server.on("/" + change_creds,handlecredentialchange); //handles submission of credentials from the client
server.on("/", showcredentialpage); // for this simple example, just show a simple page for changing credentials at the root
server.on("/" + change_creds, handlecredentialchange); // handles submission of credentials from the client
server.onNotFound(redirect);
server.begin();
@ -127,49 +127,48 @@ void loop() {
server.handleClient();
}
//This function redirects home
void redirect(){
// This function redirects home
void redirect() {
String url = "https://" + WiFi.localIP().toString();
Serial.println("Redirect called. Redirecting to " + url);
server.sendHeader("Location", url, true);
Serial.println("Header sent.");
server.send( 302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
Serial.println("Empty page sent.");
server.client().stop(); // Stop is needed because we sent no content length
server.client().stop(); // Stop is needed because we sent no content length
Serial.println("Client stopped.");
}
//This function checks whether the current session has been authenticated. If not, a request for credentials is sent.
// This function checks whether the current session has been authenticated. If not, a request for credentials is sent.
bool session_authenticated() {
Serial.println("Checking authentication.");
if (server.authenticateDigest(login,H1)) {
if (server.authenticateDigest(login, H1)) {
Serial.println("Authentication confirmed.");
return true;
} else {
} else {
Serial.println("Not authenticated. Requesting credentials.");
server.requestAuthentication(DIGEST_AUTH,realm.c_str(),authentication_failed);
server.requestAuthentication(DIGEST_AUTH, realm.c_str(), authentication_failed);
redirect();
return false;
}
}
//This function sends a simple webpage for changing login credentials to the client
void showcredentialpage(){
// This function sends a simple webpage for changing login credentials to the client
void showcredentialpage() {
Serial.println("Show credential page called.");
if(!session_authenticated()){
return;
}
if (!session_authenticated()) { return; }
Serial.println("Forming credential modification page.");
String page;
page = R"(<html>)";
page+=
R"(
page +=
R"(
<h2>Login Credentials</h2><br>
<form action=")" + change_creds + R"(" method="post">
<form action=")"
+ change_creds + R"(" method="post">
Login:<br>
<input type="text" name="login"><br>
Password:<br>
@ -178,8 +177,7 @@ void showcredentialpage(){
<input type="password" name="password_duplicate"><br>
<p><button type="submit" name="newcredentials">Change Credentials</button></p>
</form><br>
)"
;
)";
page += R"(</html>)";
@ -188,17 +186,16 @@ void showcredentialpage(){
server.send(200, "text/html", page);
}
//Saves credentials to LittleFS
void savecredentials(String new_login, String new_password)
{
//Set global variables to new values
login=new_login;
H1=ESP8266WebServer::credentialHash(new_login,realm,new_password);
// Saves credentials to LittleFS
void savecredentials(String new_login, String new_password) {
// Set global variables to new values
login = new_login;
H1 = ESP8266WebServer::credentialHash(new_login, realm, new_password);
//Save new values to LittleFS for loading on next reboot
// Save new values to LittleFS for loading on next reboot
Serial.println("Saving credentials.");
File f=LittleFS.open(file_credentials,"w"); //open as a brand new file, discard old contents
if(f){
File f = LittleFS.open(file_credentials, "w"); // open as a brand new file, discard old contents
if (f) {
Serial.println("Modifying credentials in file system.");
f.println(login);
f.println(H1);
@ -209,19 +206,18 @@ void savecredentials(String new_login, String new_password)
Serial.println("Credentials saved.");
}
//loads credentials from LittleFS
void loadcredentials()
{
// loads credentials from LittleFS
void loadcredentials() {
Serial.println("Searching for credentials.");
File f;
f=LittleFS.open(file_credentials,"r");
if(f){
f = LittleFS.open(file_credentials, "r");
if (f) {
Serial.println("Loading credentials from file system.");
String mod=f.readString(); //read the file to a String
int index_1=mod.indexOf('\n',0); //locate the first line break
int index_2=mod.indexOf('\n',index_1+1); //locate the second line break
login=mod.substring(0,index_1-1); //get the first line (excluding the line break)
H1=mod.substring(index_1+1,index_2-1); //get the second line (excluding the line break)
String mod = f.readString(); // read the file to a String
int index_1 = mod.indexOf('\n', 0); // locate the first line break
int index_2 = mod.indexOf('\n', index_1 + 1); // locate the second line break
login = mod.substring(0, index_1 - 1); // get the first line (excluding the line break)
H1 = mod.substring(index_1 + 1, index_2 - 1); // get the second line (excluding the line break)
f.close();
} else {
String default_login = "admin";
@ -229,17 +225,15 @@ void loadcredentials()
Serial.println("None found. Setting to default credentials.");
Serial.println("user:" + default_login);
Serial.println("password:" + default_password);
login=default_login;
H1=ESP8266WebServer::credentialHash(default_login,realm,default_password);
login = default_login;
H1 = ESP8266WebServer::credentialHash(default_login, realm, default_password);
}
}
//This function handles a credential change from a client.
// This function handles a credential change from a client.
void handlecredentialchange() {
Serial.println("Handle credential change called.");
if(!session_authenticated()){
return;
}
if (!session_authenticated()) { return; }
Serial.println("Handling credential change request from client.");
@ -247,9 +241,9 @@ void handlecredentialchange() {
String pw1 = server.arg("password");
String pw2 = server.arg("password_duplicate");
if(login != "" && pw1 != "" && pw1 == pw2){
if (login != "" && pw1 != "" && pw1 == pw2) {
savecredentials(login,pw1);
savecredentials(login, pw1);
server.send(200, "text/plain", "Credentials updated");
redirect();
} else {

View File

@ -8,7 +8,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -33,9 +33,7 @@ void setup(void) {
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
server.on(F("/"), []() {
server.send(200, "text/plain", "hello from esp8266!");

View File

@ -5,10 +5,10 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* ssid = STASSID;
const char* password = STAPSK;
ESP8266WebServer server(80);
@ -62,9 +62,7 @@ void handleForm() {
} else {
digitalWrite(led, 1);
String message = "POST form was:\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(200, "text/plain", message);
digitalWrite(led, 0);
}
@ -80,9 +78,7 @@ void handleNotFound() {
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
@ -105,9 +101,7 @@ void setup(void) {
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
server.on("/", handleRoot);

View File

@ -42,11 +42,11 @@ extern "C" {
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char *ssid = STASSID;
const char *password = STAPSK;
const unsigned int port = 80;
ESP8266WebServer server(port);
@ -76,20 +76,16 @@ void handleNotFound() {
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
}
void SSEKeepAlive() {
for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) {
if (!(subscription[i].clientIP)) {
continue;
}
if (!(subscription[i].clientIP)) { continue; }
if (subscription[i].client.connected()) {
Serial.printf_P(PSTR("SSEKeepAlive - client is still listening on channel %d\n"), i);
subscription[i].client.println(F("event: event\ndata: { \"TYPE\":\"KEEP-ALIVE\" }\n")); // Extra newline required by SSE standard
subscription[i].client.println(F("event: event\ndata: { \"TYPE\":\"KEEP-ALIVE\" }\n")); // Extra newline required by SSE standard
} else {
Serial.printf_P(PSTR("SSEKeepAlive - client not listening on channel %d, remove subscription\n"), i);
subscription[i].keepAliveTimer.detach();
@ -106,15 +102,15 @@ void SSEKeepAlive() {
void SSEHandler(uint8_t channel) {
WiFiClient client = server.client();
SSESubscription &s = subscription[channel];
if (s.clientIP != client.remoteIP()) { // IP addresses don't match, reject this client
if (s.clientIP != client.remoteIP()) { // IP addresses don't match, reject this client
Serial.printf_P(PSTR("SSEHandler - unregistered client with IP %s tries to listen\n"), server.client().remoteIP().toString().c_str());
return handleNotFound();
}
client.setNoDelay(true);
client.setSync(true);
Serial.printf_P(PSTR("SSEHandler - registered client with IP %s is listening\n"), IPAddress(s.clientIP).toString().c_str());
s.client = client; // capture SSE server client connection
server.setContentLength(CONTENT_LENGTH_UNKNOWN); // the payload can go on forever
s.client = client; // capture SSE server client connection
server.setContentLength(CONTENT_LENGTH_UNKNOWN); // the payload can go on forever
server.sendContent_P(PSTR("HTTP/1.1 200 OK\nContent-Type: text/event-stream;\nConnection: keep-alive\nCache-Control: no-cache\nAccess-Control-Allow-Origin: *\n\n"));
s.keepAliveTimer.attach_scheduled(30.0, SSEKeepAlive); // Refresh time every 30s for demo
}
@ -122,28 +118,20 @@ void SSEHandler(uint8_t channel) {
void handleAll() {
const char *uri = server.uri().c_str();
const char *restEvents = PSTR("/rest/events/");
if (strncmp_P(uri, restEvents, strlen_P(restEvents))) {
return handleNotFound();
}
uri += strlen_P(restEvents); // Skip the "/rest/events/" and get to the channel number
if (strncmp_P(uri, restEvents, strlen_P(restEvents))) { return handleNotFound(); }
uri += strlen_P(restEvents); // Skip the "/rest/events/" and get to the channel number
unsigned int channel = atoi(uri);
if (channel < SSE_MAX_CHANNELS) {
return SSEHandler(channel);
}
if (channel < SSE_MAX_CHANNELS) { return SSEHandler(channel); }
handleNotFound();
};
void SSEBroadcastState(const char *sensorName, unsigned short prevSensorValue, unsigned short sensorValue) {
for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) {
if (!(subscription[i].clientIP)) {
continue;
}
if (!(subscription[i].clientIP)) { continue; }
String IPaddrstr = IPAddress(subscription[i].clientIP).toString();
if (subscription[i].client.connected()) {
Serial.printf_P(PSTR("broadcast status change to client IP %s on channel %d for %s with new state %d\n"),
IPaddrstr.c_str(), i, sensorName, sensorValue);
subscription[i].client.printf_P(PSTR("event: event\ndata: {\"TYPE\":\"STATE\", \"%s\":{\"state\":%d, \"prevState\":%d}}\n\n"),
sensorName, sensorValue, prevSensorValue);
Serial.printf_P(PSTR("broadcast status change to client IP %s on channel %d for %s with new state %d\n"), IPaddrstr.c_str(), i, sensorName, sensorValue);
subscription[i].client.printf_P(PSTR("event: event\ndata: {\"TYPE\":\"STATE\", \"%s\":{\"state\":%d, \"prevState\":%d}}\n\n"), sensorName, sensorValue, prevSensorValue);
} else {
Serial.printf_P(PSTR("SSEBroadcastState - client %s registered on channel %d but not listening\n"), IPaddrstr.c_str(), i);
}
@ -152,7 +140,7 @@ void SSEBroadcastState(const char *sensorName, unsigned short prevSensorValue, u
// Simulate sensors
void updateSensor(sensorType &sensor) {
unsigned short newVal = (unsigned short)RANDOM_REG32; // (not so good) random value for the sensor
unsigned short newVal = (unsigned short)RANDOM_REG32; // (not so good) random value for the sensor
Serial.printf_P(PSTR("update sensor %s - previous state: %d, new state: %d\n"), sensor.name, sensor.value, newVal);
if (sensor.value != newVal) {
SSEBroadcastState(sensor.name, sensor.value, newVal); // only broadcast if state is different
@ -167,7 +155,7 @@ void handleSubscribe() {
}
uint8_t channel;
IPAddress clientIP = server.client().remoteIP(); // get IP address of client
IPAddress clientIP = server.client().remoteIP(); // get IP address of client
String SSEurl = F("http://");
SSEurl += WiFi.localIP().toString();
SSEurl += F(":");
@ -176,14 +164,12 @@ void handleSubscribe() {
SSEurl += F("/rest/events/");
++subscriptionCount;
for (channel = 0; channel < SSE_MAX_CHANNELS; channel++) // Find first free slot
if (!subscription[channel].clientIP) {
break;
}
subscription[channel] = {clientIP, server.client(), Ticker()};
for (channel = 0; channel < SSE_MAX_CHANNELS; channel++) // Find first free slot
if (!subscription[channel].clientIP) { break; }
subscription[channel] = { clientIP, server.client(), Ticker() };
SSEurl += channel;
Serial.printf_P(PSTR("Allocated channel %d, on uri %s\n"), channel, SSEurl.substring(offset).c_str());
//server.on(SSEurl.substring(offset), std::bind(SSEHandler, &(subscription[channel])));
// server.on(SSEurl.substring(offset), std::bind(SSEHandler, &(subscription[channel])));
Serial.printf_P(PSTR("subscription for client IP %s: event bus location: %s\n"), clientIP.toString().c_str(), SSEurl.c_str());
server.send_P(200, "text/plain", SSEurl.c_str());
}
@ -200,16 +186,14 @@ void setup(void) {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
while (WiFi.status() != WL_CONNECTED) { // Wait for connection
while (WiFi.status() != WL_CONNECTED) { // Wait for connection
delay(500);
Serial.print(".");
}
Serial.printf_P(PSTR("\nConnected to %s with IP address: %s\n"), ssid, WiFi.localIP().toString().c_str());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
startServers(); // start web and SSE servers
startServers(); // start web and SSE servers
sensor[0].name = "sensorA";
sensor[1].name = "sensorB";
updateSensor(sensor[0]);

View File

@ -4,7 +4,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -12,7 +12,7 @@ const char* password = STAPSK;
ESP8266WebServer server(80);
//Check if header is present and correct
// Check if header is present and correct
bool is_authenticated() {
Serial.println("Enter is_authenticated");
if (server.hasHeader("Cookie")) {
@ -28,7 +28,7 @@ bool is_authenticated() {
return false;
}
//login page, also called for disconnect
// login page, also called for disconnect
void handleLogin() {
String msg;
if (server.hasHeader("Cookie")) {
@ -45,7 +45,7 @@ void handleLogin() {
return;
}
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")) {
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "admin") {
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "admin") {
server.sendHeader("Location", "/");
server.sendHeader("Cache-Control", "no-cache");
server.sendHeader("Set-Cookie", "ESPSESSIONID=1");
@ -64,7 +64,7 @@ void handleLogin() {
server.send(200, "text/html", content);
}
//root page can be accessed only if authentication is ok
// root page can be accessed only if authentication is ok
void handleRoot() {
Serial.println("Enter handleRoot");
String header;
@ -75,14 +75,12 @@ void handleRoot() {
return;
}
String content = "<html><body><H2>hello, you successfully connected to esp8266!</H2><br>";
if (server.hasHeader("User-Agent")) {
content += "the user agent used is : " + server.header("User-Agent") + "<br><br>";
}
if (server.hasHeader("User-Agent")) { content += "the user agent used is : " + server.header("User-Agent") + "<br><br>"; }
content += "You can access this page until you <a href=\"/login?DISCONNECT=YES\">disconnect</a></body></html>";
server.send(200, "text/html", content);
}
//no need authentication
// no need authentication
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
@ -92,9 +90,7 @@ void handleNotFound() {
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
}
@ -123,7 +119,7 @@ void setup(void) {
});
server.onNotFound(handleNotFound);
//ask server to track these headers
// ask server to track these headers
server.collectHeaders("User-Agent", "Cookie");
server.begin();
Serial.println("HTTP server started");

View File

@ -9,10 +9,10 @@
#include <Arduino.h>
#include <ESP8266WebServer.h>
#include "secrets.h" // add WLAN Credentials in here.
#include "secrets.h" // add WLAN Credentials in here.
#include <FS.h> // File System for Web Server Files
#include <LittleFS.h> // This file system is used.
#include <FS.h> // File System for Web Server Files
#include <LittleFS.h> // This file system is used.
// mark parameters not used in example
#define UNUSED __attribute__((unused))
@ -41,13 +41,11 @@ void handleRedirect() {
TRACE("Redirect...");
String url = "/index.htm";
if (!LittleFS.exists(url)) {
url = "/$update.htm";
}
if (!LittleFS.exists(url)) { url = "/$update.htm"; }
server.sendHeader("Location", url, true);
server.send(302);
} // handleRedirect()
} // handleRedirect()
// This function is called when the WebServer was requested to list all existing files in the filesystem.
@ -58,20 +56,18 @@ void handleListFiles() {
result += "[\n";
while (dir.next()) {
if (result.length() > 4) {
result += ",";
}
if (result.length() > 4) { result += ","; }
result += " {";
result += " \"name\": \"" + dir.fileName() + "\", ";
result += " \"size\": " + String(dir.fileSize()) + ", ";
result += " \"time\": " + String(dir.fileTime());
result += " }\n";
// jc.addProperty("size", dir.fileSize());
} // while
} // while
result += "]";
server.sendHeader("Cache-Control", "no-cache");
server.send(200, "text/javascript; charset=utf-8", result);
} // handleListFiles()
} // handleListFiles()
// This function is called when the sysInfo service was requested.
@ -90,96 +86,84 @@ void handleSysInfo() {
server.sendHeader("Cache-Control", "no-cache");
server.send(200, "text/javascript; charset=utf-8", result);
} // handleSysInfo()
} // handleSysInfo()
// ===== Request Handler class used to answer more complex requests =====
// The FileServerHandler is registered to the web server to support DELETE and UPLOAD of files into the filesystem.
class FileServerHandler : public RequestHandler {
public:
// @brief Construct a new File Server Handler object
// @param fs The file system to be used.
// @param path Path to the root folder in the file system that is used for serving static data down and upload.
// @param cache_header Cache Header to be used in replies.
FileServerHandler() {
TRACE("FileServerHandler is registered\n");
}
public:
// @brief Construct a new File Server Handler object
// @param fs The file system to be used.
// @param path Path to the root folder in the file system that is used for serving static data down and upload.
// @param cache_header Cache Header to be used in replies.
FileServerHandler() {
TRACE("FileServerHandler is registered\n");
}
// @brief check incoming request. Can handle POST for uploads and DELETE.
// @param requestMethod method of the http request line.
// @param requestUri request ressource from the http request line.
// @return true when method can be handled.
bool canHandle(HTTPMethod requestMethod, const String UNUSED &_uri) override {
return ((requestMethod == HTTP_POST) || (requestMethod == HTTP_DELETE));
} // canHandle()
// @brief check incoming request. Can handle POST for uploads and DELETE.
// @param requestMethod method of the http request line.
// @param requestUri request ressource from the http request line.
// @return true when method can be handled.
bool canHandle(HTTPMethod requestMethod, const String UNUSED &_uri) override {
return ((requestMethod == HTTP_POST) || (requestMethod == HTTP_DELETE));
} // canHandle()
bool canUpload(const String &uri) override {
// only allow upload on root fs level.
return (uri == "/");
} // canUpload()
bool canUpload(const String &uri) override {
// only allow upload on root fs level.
return (uri == "/");
} // canUpload()
bool handle(ESP8266WebServer &server, HTTPMethod requestMethod, const String &requestUri) override {
// ensure that filename starts with '/'
String fName = requestUri;
if (!fName.startsWith("/")) {
fName = "/" + fName;
}
bool handle(ESP8266WebServer &server, HTTPMethod requestMethod, const String &requestUri) override {
// ensure that filename starts with '/'
String fName = requestUri;
if (!fName.startsWith("/")) { fName = "/" + fName; }
if (requestMethod == HTTP_POST) {
// all done in upload. no other forms.
if (requestMethod == HTTP_POST) {
// all done in upload. no other forms.
} else if (requestMethod == HTTP_DELETE) {
if (LittleFS.exists(fName)) {
LittleFS.remove(fName);
}
} // if
} else if (requestMethod == HTTP_DELETE) {
if (LittleFS.exists(fName)) { LittleFS.remove(fName); }
} // if
server.send(200); // all done.
return (true);
} // handle()
server.send(200); // all done.
return (true);
} // handle()
// uploading process
void upload(ESP8266WebServer UNUSED &server, const String UNUSED &_requestUri, HTTPUpload &upload) override {
// ensure that filename starts with '/'
String fName = upload.filename;
if (!fName.startsWith("/")) {
fName = "/" + fName;
}
// uploading process
void upload(ESP8266WebServer UNUSED &server, const String UNUSED &_requestUri, HTTPUpload &upload) override {
// ensure that filename starts with '/'
String fName = upload.filename;
if (!fName.startsWith("/")) { fName = "/" + fName; }
if (upload.status == UPLOAD_FILE_START) {
// Open the file
if (LittleFS.exists(fName)) {
LittleFS.remove(fName);
} // if
_fsUploadFile = LittleFS.open(fName, "w");
if (upload.status == UPLOAD_FILE_START) {
// Open the file
if (LittleFS.exists(fName)) { LittleFS.remove(fName); } // if
_fsUploadFile = LittleFS.open(fName, "w");
} else if (upload.status == UPLOAD_FILE_WRITE) {
// Write received bytes
if (_fsUploadFile) {
_fsUploadFile.write(upload.buf, upload.currentSize);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
// Write received bytes
if (_fsUploadFile) { _fsUploadFile.write(upload.buf, upload.currentSize); }
} else if (upload.status == UPLOAD_FILE_END) {
// Close the file
if (_fsUploadFile) {
_fsUploadFile.close();
}
} // if
} // upload()
} else if (upload.status == UPLOAD_FILE_END) {
// Close the file
if (_fsUploadFile) { _fsUploadFile.close(); }
} // if
} // upload()
protected:
File _fsUploadFile;
protected:
File _fsUploadFile;
};
// Setup everything to make the webserver work.
void setup(void) {
delay(3000); // wait for serial monitor to start completely.
delay(3000); // wait for serial monitor to start completely.
// Use Serial port for some trace information from the example
Serial.begin(115200);
@ -250,12 +234,12 @@ void setup(void) {
server.begin();
TRACE("hostname=%s\n", WiFi.getHostname());
} // setup
} // setup
// run the server...
void loop(void) {
server.handleClient();
} // loop()
} // loop()
// end.

View File

@ -9,7 +9,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* host = "esp8266-webupdate";
@ -31,34 +31,36 @@ void setup(void) {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.setDebugOutput(true);
WiFiUDP::stopAll();
Serial.printf("Update: %s\n", upload.filename.c_str());
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { //start with max available size
Update.printError(Serial);
server.on(
"/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
},
[]() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.setDebugOutput(true);
WiFiUDP::stopAll();
Serial.printf("Update: %s\n", upload.filename.c_str());
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { // start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { // true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
Serial.setDebugOutput(false);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
Serial.setDebugOutput(false);
}
yield();
});
yield();
});
server.begin();
MDNS.addService("http", "tcp", 80);

View File

@ -41,7 +41,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -72,9 +72,7 @@ void setClock() {
// Try and connect using a WiFiClientBearSSL to specified host:port and dump URL
void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) {
if (!path) {
path = "/";
}
if (!path) { path = "/"; }
Serial.printf("Trying: %s:443...", host);
client->connect(host, port);
@ -94,11 +92,9 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
do {
char tmp[32];
memset(tmp, 0, 32);
int rlen = client->read((uint8_t*)tmp, sizeof(tmp) - 1);
int rlen = client->read((uint8_t *)tmp, sizeof(tmp) - 1);
yield();
if (rlen < 0) {
break;
}
if (rlen < 0) { break; }
// Only print out first line up to \r, then abort connection
char *nl = strchr(tmp, '\r');
if (nl) {
@ -136,13 +132,13 @@ void setup() {
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
setClock(); // Required for X.509 validation
setClock(); // Required for X.509 validation
int numCerts = certStore.initCertStore(LittleFS, PSTR("/certs.idx"), PSTR("/certs.ar"));
Serial.printf("Number of CA certs read: %d\n", numCerts);
if (numCerts == 0) {
Serial.printf("No certs found. Did you run certs-from-mozilla.py and upload the LittleFS directory before running?\n");
return; // Can't connect to anything w/o certs!
return; // Can't connect to anything w/o certs!
}
BearSSL::WiFiClientSecure *bear = new BearSSL::WiFiClientSecure();
@ -156,9 +152,7 @@ void setup() {
void loop() {
Serial.printf("\nPlease enter a website address (www.blah.com) to connect to: ");
String site;
do {
site = Serial.readString();
} while (site == "");
do { site = Serial.readString(); } while (site == "");
// Strip newline if present
site.replace(String("\r"), emptyString);
site.replace(String("\n"), emptyString);
@ -170,4 +164,3 @@ void loop() {
fetchURL(bear, site.c_str(), 443, "/");
delete bear;
}

View File

@ -9,7 +9,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -22,13 +22,11 @@ void fetch(BearSSL::WiFiClientSecure *client) {
oneShot timeout(5000);
do {
char tmp[32];
int rlen = client->read((uint8_t*)tmp, sizeof(tmp) - 1);
int rlen = client->read((uint8_t *)tmp, sizeof(tmp) - 1);
yield();
if (rlen < 0) {
break;
}
if (rlen < 0) { break; }
if (rlen == 0) {
delay(10); // Give background processes some time
delay(10); // Give background processes some time
continue;
}
tmp[rlen] = '\0';
@ -82,9 +80,7 @@ int fetchMaxFragmentLength() {
bool mfln = client.probeMaxFragmentLength("tls.mbed.org", 443, 512);
Serial.printf("\nConnecting to https://tls.mbed.org\n");
Serial.printf("MFLN supported: %s\n", mfln ? "yes" : "no");
if (mfln) {
client.setBufferSizes(512, 512);
}
if (mfln) { client.setBufferSizes(512, 512); }
client.connect("tls.mbed.org", 443);
if (client.connected()) {
Serial.printf("MFLN status: %s\n", client.getMFLNStatus() ? "true" : "false");

View File

@ -39,7 +39,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -138,11 +138,11 @@ GBEnkz4KpKv7TkHoW+j7F5EMcLcSrUIpyw==
#endif
#define CACHE_SIZE 5 // Number of sessions to cache.
#define USE_CACHE // Enable SSL session caching.
// Caching SSL sessions shortens the length of the SSL handshake.
// You can see the performance improvement by looking at the
// Network tab of the developer tools of your browser.
#define CACHE_SIZE 5 // Number of sessions to cache.
#define USE_CACHE // Enable SSL session caching.
// Caching SSL sessions shortens the length of the SSL handshake.
// You can see the performance improvement by looking at the
// Network tab of the developer tools of your browser.
//#define DYNAMIC_CACHE // Whether to dynamically allocate the cache.
#if defined(USE_CACHE) && defined(DYNAMIC_CACHE)
@ -181,7 +181,7 @@ void setup() {
#ifndef USE_EC
server.setRSACert(serverCertList, serverPrivKey);
#else
server.setECCert(serverCertList, BR_KEYTYPE_KEYX|BR_KEYTYPE_SIGN, serverPrivKey);
server.setECCert(serverCertList, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, serverPrivKey);
#endif
// Set the server's cache
@ -193,31 +193,28 @@ void setup() {
server.begin();
}
static const char *HTTP_RES =
"HTTP/1.0 200 OK\r\n"
"Connection: close\r\n"
"Content-Length: 62\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n"
"\r\n"
"<html>\r\n"
"<body>\r\n"
"<p>Hello from ESP8266!</p>\r\n"
"</body>\r\n"
"</html>\r\n";
static const char *HTTP_RES = "HTTP/1.0 200 OK\r\n"
"Connection: close\r\n"
"Content-Length: 62\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n"
"\r\n"
"<html>\r\n"
"<body>\r\n"
"<p>Hello from ESP8266!</p>\r\n"
"</body>\r\n"
"</html>\r\n";
void loop() {
static int cnt;
BearSSL::WiFiClientSecure incoming = server.accept();
if (!incoming) {
return;
}
Serial.printf("Incoming connection...%d\n",cnt++);
if (!incoming) { return; }
Serial.printf("Incoming connection...%d\n", cnt++);
// Ugly way to wait for \r\n (i.e. end of HTTP request which we don't actually parse here)
uint32_t timeout=millis() + 1000;
uint32_t timeout = millis() + 1000;
int lcwn = 0;
for (;;) {
unsigned char x=0;
unsigned char x = 0;
if ((millis() > timeout) || (incoming.available() && incoming.read(&x, 1) < 0)) {
incoming.stop();
Serial.printf("Connection error, closed\n");
@ -228,14 +225,12 @@ void loop() {
} else if (x == 0x0D) {
continue;
} else if (x == 0x0A) {
if (lcwn) {
break;
}
if (lcwn) { break; }
lcwn = 1;
} else
lcwn = 0;
}
incoming.write((uint8_t*)HTTP_RES, strlen(HTTP_RES));
incoming.write((uint8_t *)HTTP_RES, strlen(HTTP_RES));
incoming.flush();
incoming.stop();
Serial.printf("Connection closed.\n");

View File

@ -67,7 +67,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -160,8 +160,7 @@ seoK24dHmt6tWmn/sbxX7Aa6TL/4mVlFoOgcaTJyVaY/BrY=
// head of the app.
// Set time via NTP, as required for x.509 validation
void setClock()
{
void setClock() {
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
Serial.print("Waiting for NTP time sync: ");
@ -199,7 +198,7 @@ void setup() {
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
setClock(); // Required for X.509 validation
setClock(); // Required for X.509 validation
// Attach the server private cert/key combo
BearSSL::X509List *serverCertList = new BearSSL::X509List(server_cert);
@ -214,30 +213,27 @@ void setup() {
server.begin();
}
static const char *HTTP_RES =
"HTTP/1.0 200 OK\r\n"
"Connection: close\r\n"
"Content-Length: 59\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n"
"\r\n"
"<html>\r\n"
"<body>\r\n"
"<p>Hello my friend!</p>\r\n"
"</body>\r\n"
"</html>\r\n";
static const char *HTTP_RES = "HTTP/1.0 200 OK\r\n"
"Connection: close\r\n"
"Content-Length: 59\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n"
"\r\n"
"<html>\r\n"
"<body>\r\n"
"<p>Hello my friend!</p>\r\n"
"</body>\r\n"
"</html>\r\n";
void loop() {
BearSSL::WiFiClientSecure incoming = server.accept();
if (!incoming) {
return;
}
if (!incoming) { return; }
Serial.println("Incoming connection...\n");
// Ugly way to wait for \r\n (i.e. end of HTTP request which we don't actually parse here)
uint32_t timeout=millis() + 1000;
uint32_t timeout = millis() + 1000;
int lcwn = 0;
for (;;) {
unsigned char x=0;
unsigned char x = 0;
if ((millis() > timeout) || (incoming.available() && incoming.read(&x, 1) < 0)) {
incoming.stop();
Serial.printf("Connection error, closed\n");
@ -248,14 +244,12 @@ void loop() {
} else if (x == 0x0D) {
continue;
} else if (x == 0x0A) {
if (lcwn) {
break;
}
if (lcwn) { break; }
lcwn = 1;
} else
lcwn = 0;
}
incoming.write((uint8_t*)HTTP_RES, strlen(HTTP_RES));
incoming.write((uint8_t *)HTTP_RES, strlen(HTTP_RES));
incoming.flush();
incoming.stop();
Serial.printf("Connection closed.\n");

View File

@ -9,13 +9,13 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
const char *pass = STAPSK;
const char * path = "/";
const char *path = "/";
void setup() {
Serial.begin(115200);
@ -53,9 +53,7 @@ void setup() {
// Try and connect using a WiFiClientBearSSL to specified host:port and dump HTTP response
void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) {
if (!path) {
path = "/";
}
if (!path) { path = "/"; }
Serial.printf("Trying: %s:443...", host);
client->connect(host, port);
@ -75,11 +73,9 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
do {
char tmp[32];
memset(tmp, 0, 32);
int rlen = client->read((uint8_t*)tmp, sizeof(tmp) - 1);
int rlen = client->read((uint8_t *)tmp, sizeof(tmp) - 1);
yield();
if (rlen < 0) {
break;
}
if (rlen < 0) { break; }
// Only print out first line up to \r, then abort connection
char *nl = strchr(tmp, '\r');
if (nl) {
@ -130,6 +126,5 @@ void loop() {
finish = millis();
Serial.printf("Total time: %dms\n", finish - start);
delay(10000); // Avoid DDOSing github
delay(10000); // Avoid DDOSing github
}

View File

@ -12,13 +12,13 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
const char *pass = STAPSK;
const char * path = "/";
const char *path = "/";
// Set time via NTP, as required for x.509 validation
void setClock() {
@ -40,9 +40,7 @@ void setClock() {
// Try and connect using a WiFiClientBearSSL to specified host:port and dump HTTP response
void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) {
if (!path) {
path = "/";
}
if (!path) { path = "/"; }
ESP.resetFreeContStack();
uint32_t freeStackStart = ESP.getFreeContStack();
@ -64,11 +62,9 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
do {
char tmp[32];
memset(tmp, 0, 32);
int rlen = client->read((uint8_t*)tmp, sizeof(tmp) - 1);
int rlen = client->read((uint8_t *)tmp, sizeof(tmp) - 1);
yield();
if (rlen < 0) {
break;
}
if (rlen < 0) { break; }
// Only print out first line up to \r, then abort connection
char *nl = strchr(tmp, '\r');
if (nl) {

View File

@ -17,7 +17,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -74,10 +74,7 @@ void setup() {
Serial.print("Requesting URL: ");
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + github_host + "\r\n" +
"User-Agent: BuildFailureDetectorESP8266\r\n" +
"Connection: close\r\n\r\n");
client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + github_host + "\r\n" + "User-Agent: BuildFailureDetectorESP8266\r\n" + "Connection: close\r\n\r\n");
Serial.println("Request sent");
while (client.connected()) {
@ -100,5 +97,4 @@ void setup() {
Serial.println("Closing connection");
}
void loop() {
}
void loop() {}

View File

@ -23,12 +23,12 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
#define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses
#define FQDN2 F("www.yahoo.com") // with both IPv4 & IPv6 addresses
#define FQDN6 F("ipv6.google.com") // does not resolve in IPv4
#define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses
#define FQDN2 F("www.yahoo.com") // with both IPv4 & IPv6 addresses
#define FQDN6 F("ipv6.google.com") // does not resolve in IPv4
#define STATUSDELAY_MS 10000
#define TCP_PORT 23
#define UDP_PORT 23
@ -71,29 +71,17 @@ void status(Print& out) {
for (int i = 0; i < DNS_MAX_SERVERS; i++) {
IPAddress dns = WiFi.dnsIP(i);
if (dns.isSet()) {
out.printf("dns%d: %s\n", i, dns.toString().c_str());
}
if (dns.isSet()) { out.printf("dns%d: %s\n", i, dns.toString().c_str()); }
}
out.println(F("Try me at these addresses:"));
out.println(F("(with 'telnet <addr> or 'nc -u <addr> 23')"));
for (auto a : addrList) {
out.printf("IF='%s' IPv6=%d local=%d hostname='%s' addr= %s",
a.ifname().c_str(),
a.isV6(),
a.isLocal(),
a.ifhostname(),
a.toString().c_str());
out.printf("IF='%s' IPv6=%d local=%d hostname='%s' addr= %s", a.ifname().c_str(), a.isV6(), a.isLocal(), a.ifhostname(), a.toString().c_str());
if (a.isLegacy()) {
out.printf(" / mask:%s / gw:%s",
a.netmask().toString().c_str(),
a.gw().toString().c_str());
}
if (a.isLegacy()) { out.printf(" / mask:%s / gw:%s", a.netmask().toString().c_str(), a.gw().toString().c_str()); }
out.println();
}
// lwIP's dns client will ask for IPv4 first (by default)
@ -101,8 +89,8 @@ void status(Print& out) {
fqdn(out, FQDN);
fqdn(out, FQDN6);
#if LWIP_IPV4 && LWIP_IPV6
fqdn_rt(out, FQDN, DNSResolveType::DNS_AddrType_IPv4_IPv6); // IPv4 before IPv6
fqdn_rt(out, FQDN2, DNSResolveType::DNS_AddrType_IPv6_IPv4); // IPv6 before IPv4
fqdn_rt(out, FQDN, DNSResolveType::DNS_AddrType_IPv4_IPv6); // IPv4 before IPv6
fqdn_rt(out, FQDN2, DNSResolveType::DNS_AddrType_IPv6_IPv4); // IPv6 before IPv4
#endif
out.println(F("------------------------------"));
}
@ -125,7 +113,7 @@ void setup() {
status(Serial);
#if 0 // 0: legacy connecting loop - 1: wait for IPv6
#if 0 // 0: legacy connecting loop - 1: wait for IPv6
// legacy loop (still valid with IPv4 only)
@ -146,11 +134,9 @@ void setup() {
for (bool configured = false; !configured;) {
for (auto addr : addrList)
if ((configured = !addr.isLocal()
// && addr.isV6() // uncomment when IPv6 is mandatory
// && addr.ifnumber() == STATION_IF
)) {
break;
}
// && addr.isV6() // uncomment when IPv6 is mandatory
// && addr.ifnumber() == STATION_IF
)) { break; }
Serial.print('.');
delay(500);
}
@ -188,10 +174,8 @@ void loop() {
udp.remoteIP().printTo(Serial);
Serial.print(F(" :"));
Serial.println(udp.remotePort());
int c;
while ((c = udp.read()) >= 0) {
Serial.write(c);
}
int c;
while ((c = udp.read()) >= 0) { Serial.write(c); }
// send a reply, to the IP address and port that sent us the packet we received
udp.beginPacket(udp.remoteIP(), udp.remotePort());
@ -200,8 +184,5 @@ void loop() {
}
if (showStatusOnSerialNow) {
status(Serial);
}
if (showStatusOnSerialNow) { status(Serial); }
}

View File

@ -23,24 +23,24 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char * ssid = STASSID; // your network SSID (name)
const char * pass = STAPSK; // your network password
const char* ssid = STASSID; // your network SSID (name)
const char* pass = STAPSK; // your network password
unsigned int localPort = 2390; // local port to listen for UDP packets
unsigned int localPort = 2390; // local port to listen for UDP packets
/* Don't hardwire the IP address or we won't get the benefits of the pool.
Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
// IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;
@ -73,10 +73,10 @@ void setup() {
}
void loop() {
//get a random server from the pool
// get a random server from the pool
WiFi.hostByName(ntpServerName, timeServerIP);
sendNTPpacket(timeServerIP); // send an NTP packet to a time server
sendNTPpacket(timeServerIP); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
@ -87,10 +87,10 @@ void loop() {
Serial.print("packet received, length=");
Serial.println(cb);
// We've received a packet, read the data from it
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
// the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
@ -112,19 +112,19 @@ void loop() {
// print the hour, minute and second:
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if (((epoch % 3600) / 60) < 10) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ((epoch % 60) < 10) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
Serial.println(epoch % 60); // print the second
}
// wait ten seconds before asking for the time again
delay(10000);
@ -137,19 +137,19 @@ void sendNTPpacket(IPAddress& address) {
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.beginPacket(address, 123); // NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
}

View File

@ -25,10 +25,10 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* ssid = STASSID;
const char* password = STAPSK;
ArduinoWiFiServer server(2323);
@ -60,13 +60,13 @@ void setup() {
void loop() {
WiFiClient client = server.available(); // returns first client which has data to read or a 'false' client
if (client) { // client is true only if it is connected and has data to read
String s = client.readStringUntil('\n'); // read the message incoming from one of the clients
s.trim(); // trim eventual \r
Serial.println(s); // print the message to Serial Monitor
client.print("echo: "); // this is only for the sending client
server.println(s); // send the message to all connected clients
server.flush(); // flush the buffers
WiFiClient client = server.available(); // returns first client which has data to read or a 'false' client
if (client) { // client is true only if it is connected and has data to read
String s = client.readStringUntil('\n'); // read the message incoming from one of the clients
s.trim(); // trim eventual \r
Serial.println(s); // print the message to Serial Monitor
client.print("echo: "); // this is only for the sending client
server.println(s); // send the message to all connected clients
server.flush(); // flush the buffers
}
}

View File

@ -7,7 +7,7 @@
#ifndef STASSID
#define STASSID "mynetwork"
#define STAPSK "mynetworkpassword"
#define STAPSK "mynetworkpassword"
#endif
#include <ESP8266WiFi.h>
@ -30,7 +30,7 @@ void dump(int netif_idx, const char* data, size_t len, int out, int success) {
// optional filter example: if (netDump_is_ARP(data))
{
netDump(Serial, data, len);
//netDumpHex(Serial, data, len);
// netDumpHex(Serial, data, len);
}
}
#endif
@ -51,19 +51,14 @@ void setup() {
Serial.print('.');
delay(500);
}
Serial.printf("\nSTA: %s (dns: %s / %s)\n",
WiFi.localIP().toString().c_str(),
WiFi.dnsIP(0).toString().c_str(),
WiFi.dnsIP(1).toString().c_str());
Serial.printf("\nSTA: %s (dns: %s / %s)\n", WiFi.localIP().toString().c_str(), WiFi.dnsIP(0).toString().c_str(), WiFi.dnsIP(1).toString().c_str());
// give DNS servers to AP side
dhcpSoftAP.dhcps_set_dns(0, WiFi.dnsIP(0));
dhcpSoftAP.dhcps_set_dns(1, WiFi.dnsIP(1));
WiFi.softAPConfig( // enable AP, with android-compatible google domain
IPAddress(172, 217, 28, 254),
IPAddress(172, 217, 28, 254),
IPAddress(255, 255, 255, 0));
IPAddress(172, 217, 28, 254), IPAddress(172, 217, 28, 254), IPAddress(255, 255, 255, 0));
WiFi.softAP(STASSID "extender", STAPSK);
Serial.printf("AP: %s\n", WiFi.softAPIP().toString().c_str());
@ -73,14 +68,10 @@ void setup() {
if (ret == ERR_OK) {
ret = ip_napt_enable_no(SOFTAP_IF, 1);
Serial.printf("ip_napt_enable_no(SOFTAP_IF): ret=%d (OK=%d)\n", (int)ret, (int)ERR_OK);
if (ret == ERR_OK) {
Serial.printf("WiFi Network '%s' with same password is now NATed behind '%s'\n", STASSID "extender", STASSID);
}
if (ret == ERR_OK) { Serial.printf("WiFi Network '%s' with same password is now NATed behind '%s'\n", STASSID "extender", STASSID); }
}
Serial.printf("Heap after napt init: %d\n", ESP.getFreeHeap());
if (ret != ERR_OK) {
Serial.printf("NAPT initialization failed\n");
}
if (ret != ERR_OK) { Serial.printf("NAPT initialization failed\n"); }
}
#else
@ -92,6 +83,4 @@ void setup() {
#endif
void loop() {
}
void loop() {}

View File

@ -20,14 +20,14 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
unsigned int localPort = 8888; // local port to listen on
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged\r\n"; // a string to send back
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged\r\n"; // a string to send back
WiFiUDP Udp;
@ -49,11 +49,7 @@ void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n",
packetSize,
Udp.remoteIP().toString().c_str(), Udp.remotePort(),
Udp.destinationIP().toString().c_str(), Udp.localPort(),
ESP.getFreeHeap());
Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort(), Udp.destinationIP().toString().c_str(), Udp.localPort(), ESP.getFreeHeap());
// read the packet into packetBufffer
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
@ -66,11 +62,10 @@ void loop() {
Udp.write(ReplyBuffer);
Udp.endPacket();
}
}
/*
test (shell/netcat):
--------------------
nc -u 192.168.esp.address 8888
nc -u 192.168.esp.address 8888
*/

View File

@ -36,7 +36,7 @@
#ifndef APSSID
#define APSSID "ESPap"
#define APPSK "thereisnospoon"
#define APPSK "thereisnospoon"
#endif
/* Set these to your desired credentials. */

View File

@ -7,10 +7,10 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "djxmmx.net";
@ -61,9 +61,7 @@ void loop() {
// This will send a string to the server
Serial.println("sending data to server");
if (client.connected()) {
client.println("hello from ESP8266");
}
if (client.connected()) { client.println("hello from ESP8266"); }
// wait for data to be available
unsigned long timeout = millis();
@ -90,7 +88,7 @@ void loop() {
client.stop();
if (wait) {
delay(300000); // execute once every 5 minutes, don't flood remote service
delay(300000); // execute once every 5 minutes, don't flood remote service
}
wait = true;
}

View File

@ -9,10 +9,10 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "192.168.1.1";
@ -64,7 +64,7 @@ void loop() {
// This will send the request to the server
client.println("hello from ESP8266");
//read back one line from server
// read back one line from server
Serial.println("receiving from remote server");
String line = client.readStringUntil('\r');
Serial.println(line);
@ -75,4 +75,3 @@ void loop() {
Serial.println("wait 5 sec...");
delay(5000);
}

View File

@ -7,11 +7,11 @@
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <PolledTimeout.h>
#include <algorithm> // std::min
#include <algorithm> // std::min
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
constexpr int port = 23;
@ -19,12 +19,12 @@ constexpr int port = 23;
WiFiServer server(port);
WiFiClient client;
constexpr size_t sizes [] = { 0, 512, 384, 256, 128, 64, 16, 8, 4 };
constexpr size_t sizes[] = { 0, 512, 384, 256, 128, 64, 16, 8, 4 };
constexpr uint32_t breathMs = 200;
esp8266::polledTimeout::oneShotFastMs enoughMs(breathMs);
esp8266::polledTimeout::periodicFastMs test(2000);
int t = 1; // test (1, 2 or 3, see below)
int s = 0; // sizes[] index
int t = 1; // test (1, 2 or 3, see below)
int s = 0; // sizes[] index
void setup() {
@ -63,19 +63,13 @@ void loop() {
static uint32_t cnt = 0;
if (test && cnt) {
Serial.printf("measured-block-size=%u min-free-stack=%u", tot / cnt, ESP.getFreeContStack());
if (t == 2 && sizes[s]) {
Serial.printf(" (blocks: at most %d bytes)", sizes[s]);
}
if (t == 3 && sizes[s]) {
Serial.printf(" (blocks: exactly %d bytes)", sizes[s]);
}
if (t == 3 && !sizes[s]) {
Serial.printf(" (blocks: any size)");
}
if (t == 2 && sizes[s]) { Serial.printf(" (blocks: at most %d bytes)", sizes[s]); }
if (t == 3 && sizes[s]) { Serial.printf(" (blocks: exactly %d bytes)", sizes[s]); }
if (t == 3 && !sizes[s]) { Serial.printf(" (blocks: any size)"); }
Serial.printf("\n");
}
//check if there are any new clients
// check if there are any new clients
if (server.hasClient()) {
client = server.accept();
Serial.println("New client");
@ -84,10 +78,25 @@ void loop() {
if (Serial.available()) {
s = (s + 1) % (sizeof(sizes) / sizeof(sizes[0]));
switch (Serial.read()) {
case '1': if (t != 1) s = 0; t = 1; Serial.println("byte-by-byte (watch then press 2, 3 or 4)"); break;
case '2': if (t != 2) s = 1; t = 2; Serial.printf("through buffer (watch then press 2 again, or 1, 3 or 4)\n"); break;
case '3': if (t != 3) s = 0; t = 3; Serial.printf("direct access (sendAvailable - watch then press 3 again, or 1, 2 or 4)\n"); break;
case '4': t = 4; Serial.printf("direct access (sendAll - close peer to stop, then press 1, 2 or 3 before restarting peer)\n"); break;
case '1':
if (t != 1) s = 0;
t = 1;
Serial.println("byte-by-byte (watch then press 2, 3 or 4)");
break;
case '2':
if (t != 2) s = 1;
t = 2;
Serial.printf("through buffer (watch then press 2 again, or 1, 3 or 4)\n");
break;
case '3':
if (t != 3) s = 0;
t = 3;
Serial.printf("direct access (sendAvailable - watch then press 3 again, or 1, 2 or 4)\n");
break;
case '4':
t = 4;
Serial.printf("direct access (sendAll - close peer to stop, then press 1, 2 or 3 before restarting peer)\n");
break;
}
tot = cnt = 0;
ESP.resetFreeContStack();
@ -113,9 +122,7 @@ void loop() {
uint8_t buf[maxTo];
size_t tcp_got = client.read(buf, maxTo);
size_t tcp_sent = client.write(buf, tcp_got);
if (tcp_sent != maxTo) {
Serial.printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxTo, tcp_got, tcp_sent);
}
if (tcp_sent != maxTo) { Serial.printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxTo, tcp_got, tcp_sent); }
tot += tcp_sent;
cnt++;
}
@ -141,7 +148,7 @@ void loop() {
else if (t == 4) {
// stream to print, possibly with only one copy
tot += client.sendAll(&client); // this one might not exit until peer close
tot += client.sendAll(&client); // this one might not exit until peer close
cnt++;
switch (client.getLastSendReport()) {
@ -152,5 +159,4 @@ void loop() {
case Stream::Report::ShortOperation: Serial.println("Stream::send: short transfer"); break;
}
}
}

View File

@ -18,10 +18,10 @@
#ifndef APSSID
#define APSSID "esp8266"
#define APPSK "esp8266"
#define APPSK "esp8266"
#endif
const char* ssid = APSSID;
const char* ssid = APSSID;
const char* password = APPSK;
WiFiEventHandler stationConnectedHandler;
@ -98,7 +98,6 @@ void loop() {
String macToString(const unsigned char* mac) {
char buf[20];
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(buf);
}

View File

@ -11,7 +11,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -55,12 +55,10 @@ void setup() {
void loop() {
// Check if a client has connected
WiFiClient client = server.accept();
if (!client) {
return;
}
if (!client) { return; }
Serial.println(F("new client"));
client.setTimeout(5000); // default is 1000
client.setTimeout(5000); // default is 1000
// Read the first line of the request
String req = client.readStringUntil('\r');

View File

@ -40,15 +40,7 @@ void loop() {
for (int8_t i = 0; i < scanResult; i++) {
WiFi.getNetworkInfo(i, ssid, encryptionType, rssi, bssid, channel, hidden);
Serial.printf(PSTR(" %02d: [CH %02d] [%02X:%02X:%02X:%02X:%02X:%02X] %ddBm %c %c %s\n"),
i,
channel,
bssid[0], bssid[1], bssid[2],
bssid[3], bssid[4], bssid[5],
rssi,
(encryptionType == ENC_TYPE_NONE) ? ' ' : '*',
hidden ? 'H' : 'V',
ssid.c_str());
Serial.printf(PSTR(" %02d: [CH %02d] [%02X:%02X:%02X:%02X:%02X:%02X] %ddBm %c %c %s\n"), i, channel, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], rssi, (encryptionType == ENC_TYPE_NONE) ? ' ' : '*', hidden ? 'H' : 'V', ssid.c_str());
yield();
}
} else {

View File

@ -17,7 +17,7 @@
#endif
#include <ESP8266WiFi.h>
#include <include/WiFiState.h> // WiFiState structure details
#include <include/WiFiState.h> // WiFiState structure details
WiFiState state;
@ -26,7 +26,7 @@ const char* password = STAPSK;
void setup() {
Serial.begin(74880);
//Serial.setDebugOutput(true); // If you need debug output
// Serial.setDebugOutput(true); // If you need debug output
Serial.println("Trying to resume WiFi connection...");
// May be necessary after deepSleep. Otherwise you may get "error: pll_cal exceeds 2ms!!!" when trying to connect
@ -36,17 +36,14 @@ void setup() {
// Here you can do whatever you need to do that doesn't need a WiFi connection.
// ---
ESP.rtcUserMemoryRead(RTC_USER_DATA_SLOT_WIFI_STATE, reinterpret_cast<uint32_t *>(&state), sizeof(state));
ESP.rtcUserMemoryRead(RTC_USER_DATA_SLOT_WIFI_STATE, reinterpret_cast<uint32_t*>(&state), sizeof(state));
unsigned long start = millis();
if (!WiFi.resumeFromShutdown(state)
|| (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
if (!WiFi.resumeFromShutdown(state) || (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
Serial.println("Cannot resume WiFi connection, connecting via begin...");
WiFi.persistent(false);
if (!WiFi.mode(WIFI_STA)
|| !WiFi.begin(ssid, password)
|| (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
if (!WiFi.mode(WIFI_STA) || !WiFi.begin(ssid, password) || (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
WiFi.mode(WIFI_OFF);
Serial.println("Cannot connect!");
Serial.flush();
@ -64,7 +61,7 @@ void setup() {
// ---
WiFi.shutdown(state);
ESP.rtcUserMemoryWrite(RTC_USER_DATA_SLOT_WIFI_STATE, reinterpret_cast<uint32_t *>(&state), sizeof(state));
ESP.rtcUserMemoryWrite(RTC_USER_DATA_SLOT_WIFI_STATE, reinterpret_cast<uint32_t*>(&state), sizeof(state));
// ---
// Here you can do whatever you need to do that doesn't need a WiFi connection anymore.

View File

@ -20,11 +20,11 @@
*/
#include <ESP8266WiFi.h>
#include <algorithm> // std::min
#include <algorithm> // std::min
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
/*
@ -64,9 +64,9 @@ SoftwareSerial* logger = nullptr;
#define logger (&Serial1)
#endif
#define STACK_PROTECTOR 512 // bytes
#define STACK_PROTECTOR 512 // bytes
//how many clients should be able to telnet to this ESP8266
// how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 2
const char* ssid = STASSID;
const char* password = STAPSK;
@ -98,7 +98,7 @@ void setup() {
logger->printf("Serial receive buffer size: %d bytes\n", RXBUFFERSIZE);
#if SERIAL_LOOPBACK
USC0(0) |= (1 << UCLBE); // incomplete HardwareSerial API
USC0(0) |= (1 << UCLBE); // incomplete HardwareSerial API
logger->println("Serial Internal Loopback enabled");
#endif
@ -114,7 +114,7 @@ void setup() {
logger->print("connected, address=");
logger->println(WiFi.localIP());
//start server
// start server
server.begin();
server.setNoDelay(true);
@ -124,19 +124,19 @@ void setup() {
}
void loop() {
//check if there are any new clients
// check if there are any new clients
if (server.hasClient()) {
//find free/disconnected spot
// find free/disconnected spot
int i;
for (i = 0; i < MAX_SRV_CLIENTS; i++)
if (!serverClients[i]) { // equivalent to !serverClients[i].connected()
if (!serverClients[i]) { // equivalent to !serverClients[i].connected()
serverClients[i] = server.accept();
logger->print("New client: index ");
logger->print(i);
break;
}
//no free/disconnected spot so reject
// no free/disconnected spot so reject
if (i == MAX_SRV_CLIENTS) {
server.accept().println("busy");
// hints: server.accept() is a WiFiClient with short-term scope
@ -147,7 +147,7 @@ void loop() {
}
}
//check TCP clients for data
// check TCP clients for data
#if 1
// Incredibly, this code is faster than the buffered one below - #4620 is needed
// loopback/3000000baud average 348KB/s
@ -165,9 +165,7 @@ void loop() {
uint8_t buf[maxToSerial];
size_t tcp_got = serverClients[i].read(buf, maxToSerial);
size_t serial_sent = Serial.write(buf, tcp_got);
if (serial_sent != maxToSerial) {
logger->printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxToSerial, tcp_got, serial_sent);
}
if (serial_sent != maxToSerial) { logger->printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxToSerial, tcp_got, serial_sent); }
}
#endif
@ -189,7 +187,7 @@ void loop() {
}
}
//check UART for data
// check UART for data
size_t len = std::min(Serial.available(), maxToTcp);
len = std::min(len, (size_t)STACK_PROTECTOR);
if (len) {
@ -202,9 +200,7 @@ void loop() {
// ensure write space is sufficient:
if (serverClients[i].availableForWrite() >= serial_got) {
size_t tcp_sent = serverClients[i].write(sbuf, serial_got);
if (tcp_sent != len) {
logger->printf("len mismatch: available:%zd serial-read:%zd tcp-write:%zd\n", len, serial_got, tcp_sent);
}
if (tcp_sent != len) { logger->printf("len mismatch: available:%zd serial-read:%zd tcp-write:%zd\n", len, serial_got, tcp_sent); }
}
}
}

View File

@ -1,4 +1,4 @@
#define ESP8266WIFIMESH_DISABLE_COMPATIBILITY // Excludes redundant compatibility code. TODO: Should be used for new code until the compatibility code is removed with release 3.0.0 of the Arduino core.
#define ESP8266WIFIMESH_DISABLE_COMPATIBILITY // Excludes redundant compatibility code. TODO: Should be used for new code until the compatibility code is removed with release 3.0.0 of the Arduino core.
#include <ESP8266WiFi.h>
#include <EspnowMeshBackend.h>
@ -19,26 +19,23 @@ namespace TypeCast = MeshTypeConversionFunctions;
https://github.com/esp8266/Arduino/issues/1143
https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html
*/
constexpr char exampleMeshName[] PROGMEM = "MeshNode_"; // The name of the mesh network. Used as prefix for the node SSID and to find other network nodes in the example networkFilter and broadcastFilter functions below.
constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; // Note: " is an illegal character. The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
constexpr char exampleMeshName[] PROGMEM = "MeshNode_"; // The name of the mesh network. Used as prefix for the node SSID and to find other network nodes in the example networkFilter and broadcastFilter functions below.
constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; // Note: " is an illegal character. The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
// A custom encryption key is required when using encrypted ESP-NOW transmissions. There is always a default Kok set, but it can be replaced if desired.
// All ESP-NOW keys below must match in an encrypted connection pair for encrypted communication to be possible.
// Note that it is also possible to use Strings as key seeds instead of arrays.
uint8_t espnowEncryptedConnectionKey[16] = {0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, // This is the key for encrypting transmissions of encrypted connections.
0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x32, 0x11
};
uint8_t espnowEncryptionKok[16] = {0x22, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, // This is the key for encrypting the encrypted connection key.
0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x32, 0x33
};
uint8_t espnowHashKey[16] = {0xEF, 0x44, 0x33, 0x0C, 0x33, 0x44, 0xFE, 0x44, // This is the secret key used for HMAC during encrypted connection requests.
0x33, 0x44, 0x33, 0xB0, 0x33, 0x44, 0x32, 0xAD
};
uint8_t espnowEncryptedConnectionKey[16] = { 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, // This is the key for encrypting transmissions of encrypted connections.
0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x32, 0x11 };
uint8_t espnowEncryptionKok[16] = { 0x22, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, // This is the key for encrypting the encrypted connection key.
0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x32, 0x33 };
uint8_t espnowHashKey[16] = { 0xEF, 0x44, 0x33, 0x0C, 0x33, 0x44, 0xFE, 0x44, // This is the secret key used for HMAC during encrypted connection requests.
0x33, 0x44, 0x33, 0xB0, 0x33, 0x44, 0x32, 0xAD };
unsigned int requestNumber = 0;
unsigned int responseNumber = 0;
const char broadcastMetadataDelimiter = 23; // 23 = End-of-Transmission-Block (ETB) control character in ASCII
const char broadcastMetadataDelimiter = 23; // 23 = End-of-Transmission-Block (ETB) control character in ASCII
String manageRequest(const String &request, MeshBackendBase &meshInstance);
TransmissionStatusType manageResponse(const String &response, MeshBackendBase &meshInstance);
@ -61,7 +58,7 @@ String manageRequest(const String &request, MeshBackendBase &meshInstance) {
String transmissionEncrypted = espnowInstance->receivedEncryptedTransmission() ? F(", Encrypted transmission") : F(", Unencrypted transmission");
Serial.print(String(F("ESP-NOW (")) + espnowInstance->getSenderMac() + transmissionEncrypted + F("): "));
} else if (TcpIpMeshBackend *tcpIpInstance = TypeCast::meshBackendCast<TcpIpMeshBackend *>(&meshInstance)) {
(void)tcpIpInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
(void)tcpIpInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
Serial.print(F("TCP/IP: "));
} else {
Serial.print(F("UNKNOWN!: "));
@ -174,7 +171,7 @@ bool broadcastFilter(String &firstTransmission, EspnowMeshBackend &meshInstance)
String targetMeshName = firstTransmission.substring(0, metadataEndIndex);
if (!targetMeshName.isEmpty() && meshInstance.getMeshName() != targetMeshName) {
return false; // Broadcast is for another mesh network
return false; // Broadcast is for another mesh network
} else {
// Remove metadata from message and mark as accepted broadcast.
// Note that when you modify firstTransmission it is best to avoid using substring or other String methods that rely on null values for String length determination.
@ -198,7 +195,7 @@ bool broadcastFilter(String &firstTransmission, EspnowMeshBackend &meshInstance)
bool exampleTransmissionOutcomesUpdateHook(MeshBackendBase &meshInstance) {
// Currently this is exactly the same as the default hook, but you can modify it to alter the behaviour of attemptTransmission.
(void)meshInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
(void)meshInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
return true;
}
@ -221,7 +218,7 @@ bool exampleTransmissionOutcomesUpdateHook(MeshBackendBase &meshInstance) {
bool exampleResponseTransmittedHook(bool transmissionSuccessful, const String &response, const uint8_t *recipientMac, uint32_t responseIndex, EspnowMeshBackend &meshInstance) {
// Currently this is exactly the same as the default hook, but you can modify it to alter the behaviour of sendEspnowResponses.
(void)transmissionSuccessful; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
(void)transmissionSuccessful; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
(void)response;
(void)recipientMac;
(void)responseIndex;
@ -281,8 +278,8 @@ void setup() {
// Uncomment the lines below to use automatic AEAD encryption/decryption of messages sent/received.
// All nodes this node wishes to communicate with must then also use encrypted messages with the same getEspnowMessageEncryptionKey(), or messages will not be accepted.
// Note that using AEAD encrypted messages will reduce the number of message bytes that can be transmitted.
//espnowNode.setEspnowMessageEncryptionKey(F("ChangeThisKeySeed_TODO")); // The message encryption key should always be set manually. Otherwise a default key (all zeroes) is used.
//espnowNode.setUseEncryptedMessages(true);
// espnowNode.setEspnowMessageEncryptionKey(F("ChangeThisKeySeed_TODO")); // The message encryption key should always be set manually. Otherwise a default key (all zeroes) is used.
// espnowNode.setUseEncryptedMessages(true);
}
int32_t timeOfLastScan = -10000;
@ -293,10 +290,10 @@ void loop() {
// Note that depending on the amount of responses to send and their length, this method can take tens or even hundreds of milliseconds to complete.
// More intense transmission activity and less frequent calls to performEspnowMaintenance will likely cause the method to take longer to complete, so plan accordingly.
//Should not be used inside responseHandler, requestHandler, networkFilter or broadcastFilter callbacks since performEspnowMaintenance() can alter the ESP-NOW state.
// Should not be used inside responseHandler, requestHandler, networkFilter or broadcastFilter callbacks since performEspnowMaintenance() can alter the ESP-NOW state.
EspnowMeshBackend::performEspnowMaintenance();
if (millis() - timeOfLastScan > 10000) { // Give other nodes some time to connect between data transfers.
if (millis() - timeOfLastScan > 10000) { // Give other nodes some time to connect between data transfers.
Serial.println(F("\nPerforming unencrypted ESP-NOW transmissions."));
uint32_t startTime = millis();
@ -310,9 +307,7 @@ void loop() {
espnowDelay(100);
// One way to check how attemptTransmission worked out
if (espnowNode.latestTransmissionSuccessful()) {
Serial.println(F("Transmission successful."));
}
if (espnowNode.latestTransmissionSuccessful()) { Serial.println(F("Transmission successful.")); }
// Another way to check how attemptTransmission worked out
if (espnowNode.latestTransmissionOutcomes().empty()) {
@ -343,20 +338,20 @@ void loop() {
espnowNode.broadcast(broadcastMetadata + broadcastMessage);
Serial.println(String(F("Broadcast to all mesh nodes done in ")) + String(millis() - startTime) + F(" ms."));
espnowDelay(100); // Wait for responses (broadcasts can receive an unlimited number of responses, other transmissions can only receive one response).
espnowDelay(100); // Wait for responses (broadcasts can receive an unlimited number of responses, other transmissions can only receive one response).
// If you have a data array containing null values it is possible to transmit the raw data by making the array into a multiString as shown below.
// You can use String::c_str() or String::begin() to retrieve the data array later.
// Note that certain String methods such as String::substring use null values to determine String length, which means they will not work as normal with multiStrings.
uint8_t dataArray[] = {0, '\'', 0, '\'', ' ', '(', 'n', 'u', 'l', 'l', ')', ' ', 'v', 'a', 'l', 'u', 'e'};
uint8_t dataArray[] = { 0, '\'', 0, '\'', ' ', '(', 'n', 'u', 'l', 'l', ')', ' ', 'v', 'a', 'l', 'u', 'e' };
String espnowMessage = TypeCast::uint8ArrayToMultiString(dataArray, sizeof dataArray) + F(" from ") + espnowNode.getMeshName() + espnowNode.getNodeID() + String('.');
Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, false);
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
Serial.println(F("\nPerforming encrypted ESP-NOW transmissions."));
uint8_t targetBSSID[6] {0};
uint8_t targetBSSID[6]{ 0 };
// We can create encrypted connections to individual nodes so that all ESP-NOW communication with the node will be encrypted.
if (espnowNode.constConnectionQueue()[0].getBSSID(targetBSSID) && espnowNode.requestEncryptedConnection(targetBSSID) == EncryptedConnectionStatus::CONNECTION_ESTABLISHED) {
@ -369,7 +364,7 @@ void loop() {
String espnowMessage = String(F("This message is encrypted only when received by node ")) + peerMac;
Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, false);
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
// A connection can be serialized and stored for later use.
// Note that this saves the current state only, so if encrypted communication between the nodes happen after this, the stored state is invalid.
@ -383,7 +378,7 @@ void loop() {
espnowMessage = String(F("This message is no longer encrypted when received by node ")) + peerMac;
Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, false);
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
Serial.println(F("Cannot read the encrypted response..."));
// Let's re-add our stored connection so we can communicate properly with targetBSSID again!
@ -392,7 +387,7 @@ void loop() {
espnowMessage = String(F("This message is once again encrypted when received by node ")) + peerMac;
Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, false);
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
Serial.println();
// If we want to remove the encrypted connection on both nodes, we can do it like this.
@ -403,7 +398,7 @@ void loop() {
espnowMessage = String(F("This message is only received by node ")) + peerMac + F(". Transmitting in this way will not change the transmission state of the sender.");
Serial.println(String(F("Transmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, EspnowNetworkInfo(targetBSSID));
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
Serial.println();
@ -423,7 +418,7 @@ void loop() {
espnowMessage = String(F("Due to encrypted connection expiration, this message is no longer encrypted when received by node ")) + peerMac;
Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, false);
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
}
// Or if we prefer we can just let the library automatically create brief encrypted connections which are long enough to transmit an encrypted message.
@ -432,9 +427,9 @@ void loop() {
espnowMessage = F("This message is always encrypted, regardless of receiver.");
Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptAutoEncryptingTransmission(espnowMessage);
espnowDelay(100); // Wait for response.
espnowDelay(100); // Wait for response.
} else {
Serial.println(String(F("Ooops! Encrypted connection removal failed. Status: ")) + String(static_cast<int>(removalOutcome)));
Serial.println(String(F("Ooops! Encrypted connection removal failed. Status: ")) + String(static_cast<int>(removalOutcome)));
}
// Finally, should you ever want to stop other parties from sending unencrypted messages to the node
@ -445,8 +440,7 @@ void loop() {
}
// Our last request was sent to all nodes found, so time to create a new request.
espnowNode.setMessage(String(F("Hello world request #")) + String(++requestNumber) + F(" from ")
+ espnowNode.getMeshName() + espnowNode.getNodeID() + String('.'));
espnowNode.setMessage(String(F("Hello world request #")) + String(++requestNumber) + F(" from ") + espnowNode.getMeshName() + espnowNode.getNodeID() + String('.'));
}
Serial.println();

View File

@ -8,7 +8,7 @@
Or "floodingMesh.getEspnowMeshBackend().setBroadcastTransmissionRedundancy(uint8_t redundancy)" (default 1) at the cost of longer transmission times.
*/
#define ESP8266WIFIMESH_DISABLE_COMPATIBILITY // Excludes redundant compatibility code. TODO: Should be used for new code until the compatibility code is removed with release 3.0.0 of the Arduino core.
#define ESP8266WIFIMESH_DISABLE_COMPATIBILITY // Excludes redundant compatibility code. TODO: Should be used for new code until the compatibility code is removed with release 3.0.0 of the Arduino core.
#include <ESP8266WiFi.h>
#include <TypeConversionFunctions.h>
@ -28,18 +28,16 @@ namespace TypeCast = MeshTypeConversionFunctions;
https://github.com/esp8266/Arduino/issues/1143
https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html
*/
constexpr char exampleMeshName[] PROGMEM = "MeshNode_"; // The name of the mesh network. Used as prefix for the node SSID and to find other network nodes in the example networkFilter and broadcastFilter functions below.
constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; // Note: " is an illegal character. The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
constexpr char exampleMeshName[] PROGMEM = "MeshNode_"; // The name of the mesh network. Used as prefix for the node SSID and to find other network nodes in the example networkFilter and broadcastFilter functions below.
constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; // Note: " is an illegal character. The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
// A custom encryption key is required when using encrypted ESP-NOW transmissions. There is always a default Kok set, but it can be replaced if desired.
// All ESP-NOW keys below must match in an encrypted connection pair for encrypted communication to be possible.
// Note that it is also possible to use Strings as key seeds instead of arrays.
uint8_t espnowEncryptedConnectionKey[16] = {0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, // This is the key for encrypting transmissions of encrypted connections.
0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x32, 0x11
};
uint8_t espnowHashKey[16] = {0xEF, 0x44, 0x33, 0x0C, 0x33, 0x44, 0xFE, 0x44, // This is the secret key used for HMAC during encrypted connection requests.
0x33, 0x44, 0x33, 0xB0, 0x33, 0x44, 0x32, 0xAD
};
uint8_t espnowEncryptedConnectionKey[16] = { 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, // This is the key for encrypting transmissions of encrypted connections.
0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x32, 0x11 };
uint8_t espnowHashKey[16] = { 0xEF, 0x44, 0x33, 0x0C, 0x33, 0x44, 0xFE, 0x44, // This is the secret key used for HMAC during encrypted connection requests.
0x33, 0x44, 0x33, 0xB0, 0x33, 0x44, 0x32, 0xAD };
bool meshMessageHandler(String &message, FloodingMesh &meshInstance);
@ -49,7 +47,7 @@ FloodingMesh floodingMesh = FloodingMesh(meshMessageHandler, FPSTR(exampleWiFiPa
bool theOne = true;
String theOneMac;
bool useLED = false; // Change this to true if you wish the onboard LED to mark The One.
bool useLED = false; // Change this to true if you wish the onboard LED to mark The One.
/**
Callback for when a message is received from the mesh network.
@ -78,7 +76,7 @@ bool meshMessageHandler(String &message, FloodingMesh &meshInstance) {
if (useLED && !theOne) {
bool ledState = message.charAt(1) == '1';
digitalWrite(LED_BUILTIN, ledState); // Turn LED on/off (LED_BUILTIN is active low)
digitalWrite(LED_BUILTIN, ledState); // Turn LED on/off (LED_BUILTIN is active low)
}
return true;
@ -87,26 +85,22 @@ bool meshMessageHandler(String &message, FloodingMesh &meshInstance) {
}
} else if (delimiterIndex > 0) {
if (meshInstance.getOriginMac() == theOneMac) {
uint32_t totalBroadcasts = strtoul(message.c_str(), nullptr, 0); // strtoul stops reading input when an invalid character is discovered.
uint32_t totalBroadcasts = strtoul(message.c_str(), nullptr, 0); // strtoul stops reading input when an invalid character is discovered.
// Static variables are only initialized once.
static uint32_t firstBroadcast = totalBroadcasts;
if (totalBroadcasts - firstBroadcast >= 100) { // Wait a little to avoid start-up glitches
static uint32_t missedBroadcasts = 1; // Starting at one to compensate for initial -1 below.
if (totalBroadcasts - firstBroadcast >= 100) { // Wait a little to avoid start-up glitches
static uint32_t missedBroadcasts = 1; // Starting at one to compensate for initial -1 below.
static uint32_t previousTotalBroadcasts = totalBroadcasts;
static uint32_t totalReceivedBroadcasts = 0;
totalReceivedBroadcasts++;
missedBroadcasts += totalBroadcasts - previousTotalBroadcasts - 1; // We expect an increment by 1.
missedBroadcasts += totalBroadcasts - previousTotalBroadcasts - 1; // We expect an increment by 1.
previousTotalBroadcasts = totalBroadcasts;
if (totalReceivedBroadcasts % 50 == 0) {
Serial.println(String(F("missed/total: ")) + String(missedBroadcasts) + '/' + String(totalReceivedBroadcasts));
}
if (totalReceivedBroadcasts % 500 == 0) {
Serial.println(String(F("Benchmark message: ")) + message.substring(0, 100));
}
if (totalReceivedBroadcasts % 50 == 0) { Serial.println(String(F("missed/total: ")) + String(missedBroadcasts) + '/' + String(totalReceivedBroadcasts)); }
if (totalReceivedBroadcasts % 500 == 0) { Serial.println(String(F("Benchmark message: ")) + message.substring(0, 100)); }
}
}
} else {
@ -136,24 +130,24 @@ void setup() {
Serial.println(F("Setting up mesh node..."));
floodingMesh.begin();
floodingMesh.activateAP(); // Required to receive messages
floodingMesh.activateAP(); // Required to receive messages
uint8_t apMacArray[6] {0};
uint8_t apMacArray[6]{ 0 };
theOneMac = TypeCast::macToString(WiFi.softAPmacAddress(apMacArray));
if (useLED) {
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
digitalWrite(LED_BUILTIN, LOW); // Turn LED on (LED_BUILTIN is active low)
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
digitalWrite(LED_BUILTIN, LOW); // Turn LED on (LED_BUILTIN is active low)
}
// Uncomment the lines below to use automatic AEAD encryption/decryption of messages sent/received via broadcast() and encryptedBroadcast().
// The main benefit of AEAD encryption is that it can be used with normal broadcasts (which are substantially faster than encryptedBroadcasts).
// The main drawbacks are that AEAD only encrypts the message data (not transmission metadata), transfers less data per message and lacks replay attack protection.
// When using AEAD, potential replay attacks must thus be handled manually.
//floodingMesh.getEspnowMeshBackend().setEspnowMessageEncryptionKey(F("ChangeThisKeySeed_TODO")); // The message encryption key should always be set manually. Otherwise a default key (all zeroes) is used.
//floodingMesh.getEspnowMeshBackend().setUseEncryptedMessages(true);
// floodingMesh.getEspnowMeshBackend().setEspnowMessageEncryptionKey(F("ChangeThisKeySeed_TODO")); // The message encryption key should always be set manually. Otherwise a default key (all zeroes) is used.
// floodingMesh.getEspnowMeshBackend().setUseEncryptedMessages(true);
floodingMeshDelay(5000); // Give some time for user to start the nodes
floodingMeshDelay(5000); // Give some time for user to start the nodes
}
int32_t timeOfLastProclamation = -10000;
@ -177,7 +171,7 @@ void loop() {
if (theOne) {
if (millis() - timeOfLastProclamation > 10000) {
uint32_t startTime = millis();
ledState = ledState ^ bool(benchmarkCount); // Make other nodes' LEDs alternate between on and off once benchmarking begins.
ledState = ledState ^ bool(benchmarkCount); // Make other nodes' LEDs alternate between on and off once benchmarking begins.
// Note: The maximum length of an unencrypted broadcast message is given by floodingMesh.maxUnencryptedMessageLength(). It is around 670 bytes by default.
floodingMesh.broadcast(String(floodingMesh.metadataDelimiter()) + String(ledState) + theOneMac + F(" is The One."));
@ -187,7 +181,7 @@ void loop() {
floodingMeshDelay(20);
}
if (millis() - loopStart > 23000) { // Start benchmarking the mesh once three proclamations have been made
if (millis() - loopStart > 23000) { // Start benchmarking the mesh once three proclamations have been made
uint32_t startTime = millis();
floodingMesh.broadcast(String(benchmarkCount++) + String(floodingMesh.metadataDelimiter()) + F(": Not a spoon in sight."));
Serial.println(String(F("Benchmark broadcast done in ")) + String(millis() - startTime) + F(" ms."));

View File

@ -1,4 +1,4 @@
#define ESP8266WIFIMESH_DISABLE_COMPATIBILITY // Excludes redundant compatibility code. TODO: Should be used for new code until the compatibility code is removed with release 3.0.0 of the Arduino core.
#define ESP8266WIFIMESH_DISABLE_COMPATIBILITY // Excludes redundant compatibility code. TODO: Should be used for new code until the compatibility code is removed with release 3.0.0 of the Arduino core.
#include <ESP8266WiFi.h>
#include <TcpIpMeshBackend.h>
@ -20,7 +20,7 @@ namespace TypeCast = MeshTypeConversionFunctions;
https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html
*/
constexpr char exampleMeshName[] PROGMEM = "MeshNode_";
constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; // Note: " is an illegal character. The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; // Note: " is an illegal character. The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
unsigned int requestNumber = 0;
unsigned int responseNumber = 0;
@ -45,7 +45,7 @@ String manageRequest(const String &request, MeshBackendBase &meshInstance) {
String transmissionEncrypted = espnowInstance->receivedEncryptedTransmission() ? F(", Encrypted transmission") : F(", Unencrypted transmission");
Serial.print(String(F("ESP-NOW (")) + espnowInstance->getSenderMac() + transmissionEncrypted + F("): "));
} else if (TcpIpMeshBackend *tcpIpInstance = TypeCast::meshBackendCast<TcpIpMeshBackend *>(&meshInstance)) {
(void)tcpIpInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
(void)tcpIpInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
Serial.print(F("TCP/IP: "));
} else {
Serial.print(F("UNKNOWN!: "));
@ -145,8 +145,7 @@ bool exampleTransmissionOutcomesUpdateHook(MeshBackendBase &meshInstance) {
if (TcpIpMeshBackend *tcpIpInstance = TypeCast::meshBackendCast<TcpIpMeshBackend *>(&meshInstance)) {
if (tcpIpInstance->latestTransmissionOutcomes().back().transmissionStatus() == TransmissionStatusType::TRANSMISSION_COMPLETE) {
// Our last request got a response, so time to create a new request.
meshInstance.setMessage(String(F("Hello world request #")) + String(++requestNumber) + F(" from ")
+ meshInstance.getMeshName() + meshInstance.getNodeID() + String('.'));
meshInstance.setMessage(String(F("Hello world request #")) + String(++requestNumber) + F(" from ") + meshInstance.getMeshName() + meshInstance.getNodeID() + String('.'));
}
} else {
Serial.println(F("Invalid mesh backend!"));
@ -174,8 +173,8 @@ void setup() {
/* Initialise the mesh node */
tcpIpNode.begin();
tcpIpNode.activateAP(); // Each AP requires a separate server port.
tcpIpNode.setStaticIP(IPAddress(192, 168, 4, 22)); // Activate static IP mode to speed up connection times.
tcpIpNode.activateAP(); // Each AP requires a separate server port.
tcpIpNode.setStaticIP(IPAddress(192, 168, 4, 22)); // Activate static IP mode to speed up connection times.
// Storing our message in the TcpIpMeshBackend instance is not required, but can be useful for organizing code, especially when using many TcpIpMeshBackend instances.
// Note that calling the multi-recipient tcpIpNode.attemptTransmission will replace the stored message with whatever message is transmitted.
@ -186,17 +185,15 @@ void setup() {
int32_t timeOfLastScan = -10000;
void loop() {
if (millis() - timeOfLastScan > 3000 // Give other nodes some time to connect between data transfers.
|| (WiFi.status() != WL_CONNECTED && millis() - timeOfLastScan > 2000)) { // Scan for networks with two second intervals when not already connected.
if (millis() - timeOfLastScan > 3000 // Give other nodes some time to connect between data transfers.
|| (WiFi.status() != WL_CONNECTED && millis() - timeOfLastScan > 2000)) { // Scan for networks with two second intervals when not already connected.
// attemptTransmission(message, scan, scanAllWiFiChannels, concludingDisconnect, initialDisconnect = false)
tcpIpNode.attemptTransmission(tcpIpNode.getMessage(), true, false, false);
timeOfLastScan = millis();
// One way to check how attemptTransmission worked out
if (tcpIpNode.latestTransmissionSuccessful()) {
Serial.println(F("Transmission successful."));
}
if (tcpIpNode.latestTransmissionSuccessful()) { Serial.println(F("Transmission successful.")); }
// Another way to check how attemptTransmission worked out
if (tcpIpNode.latestTransmissionOutcomes().empty()) {

View File

@ -15,7 +15,7 @@
#ifndef APSSID
#define APSSID "APSSID"
#define APPSK "APPSK"
#define APPSK "APPSK"
#endif
ESP8266WiFiMulti WiFiMulti;
@ -37,8 +37,6 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(APSSID, APPSK);
}
void update_started() {
@ -80,21 +78,14 @@ void loop() {
t_httpUpdate_return ret = ESPhttpUpdate.update(client, "http://server/file.bin");
// Or:
//t_httpUpdate_return ret = ESPhttpUpdate.update(client, "server", 80, "file.bin");
// t_httpUpdate_return ret = ESPhttpUpdate.update(client, "server", 80, "file.bin");
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;
}
}
}

View File

@ -17,7 +17,7 @@ ESP8266WiFiMulti WiFiMulti;
#ifndef APSSID
#define APSSID "APSSID"
#define APPSK "APPSK"
#define APPSK "APPSK"
#endif
void setup() {
@ -37,7 +37,6 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(APSSID, APPSK);
}
void loop() {
@ -62,19 +61,12 @@ void loop() {
ret = ESPhttpUpdate.update(client, "http://server/file.bin");
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;
}
}
}
}

View File

@ -18,7 +18,7 @@
#ifndef APSSID
#define APSSID "APSSID"
#define APPSK "APPSK"
#define APPSK "APPSK"
#endif
ESP8266WiFiMulti WiFiMulti;
@ -74,7 +74,7 @@ void setup() {
Serial.println(numCerts);
if (numCerts == 0) {
Serial.println(F("No certs found. Did you run certs-from-mozill.py and upload the LittleFS directory before running?"));
return; // Can't connect to anything w/o certs!
return; // Can't connect to anything w/o certs!
}
}
@ -87,9 +87,7 @@ void loop() {
BearSSL::WiFiClientSecure client;
bool mfln = client.probeMaxFragmentLength("server", 443, 1024); // server must be the same as in ESPhttpUpdate.update()
Serial.printf("MFLN supported: %s\n", mfln ? "yes" : "no");
if (mfln) {
client.setBufferSizes(1024, 1024);
}
if (mfln) { client.setBufferSizes(1024, 1024); }
client.setCertStore(&certStore);
// The line below is optional. It can be used to blink the LED on the board during flashing
@ -102,21 +100,15 @@ void loop() {
t_httpUpdate_return ret = ESPhttpUpdate.update(client, "https://server/file.bin");
// Or:
//t_httpUpdate_return ret = ESPhttpUpdate.update(client, "server", 443, "file.bin");
// t_httpUpdate_return ret = ESPhttpUpdate.update(client, "server", 443, "file.bin");
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;
}
}
}

View File

@ -23,7 +23,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
ESP8266WiFiMulti WiFiMulti;
@ -73,11 +73,11 @@ void setup() {
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(STASSID, STAPSK);
#if MANUAL_SIGNING
#if MANUAL_SIGNING
signPubKey = new BearSSL::PublicKey(pubkey);
hash = new BearSSL::HashSHA256();
sign = new BearSSL::SigningVerifier(signPubKey);
#endif
#endif
}
@ -87,10 +87,10 @@ void loop() {
WiFiClient client;
#if MANUAL_SIGNING
#if MANUAL_SIGNING
// Ensure all updates are signed appropriately. W/o this call, all will be accepted.
Update.installSignature(hash, sign);
#endif
#endif
// If the key files are present in the build directory, signing will be
// enabled using them automatically
@ -99,19 +99,12 @@ void loop() {
t_httpUpdate_return ret = ESPhttpUpdate.update(client, "http://192.168.1.8/esp8266.bin");
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;
}
}
delay(10000);
}

View File

@ -43,39 +43,38 @@
Global defines and vars
*/
#define TIMEZONE_OFFSET 1 // CET
#define DST_OFFSET 1 // CEST
#define UPDATE_CYCLE (1 * 1000) // every second
#define TIMEZONE_OFFSET 1 // CET
#define DST_OFFSET 1 // CEST
#define UPDATE_CYCLE (1 * 1000) // every second
#define SERVICE_PORT 80 // HTTP port
#define SERVICE_PORT 80 // HTTP port
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* ssid = STASSID;
const char* password = STAPSK;
char* pcHostDomain = 0; // Negotiated host domain
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
MDNSResponder::hMDNSService hMDNSService = 0; // The handle of the clock service in the MDNS responder
char* pcHostDomain = 0; // Negotiated host domain
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
MDNSResponder::hMDNSService hMDNSService = 0; // The handle of the clock service in the MDNS responder
// HTTP server at port 'SERVICE_PORT' will respond to HTTP requests
ESP8266WebServer server(SERVICE_PORT);
ESP8266WebServer server(SERVICE_PORT);
/*
getTimeString
*/
const char* getTimeString(void) {
static char acTimeString[32];
static char acTimeString[32];
time_t now = time(nullptr);
ctime_r(&now, acTimeString);
size_t stLength;
while (((stLength = strlen(acTimeString))) &&
('\n' == acTimeString[stLength - 1])) {
acTimeString[stLength - 1] = 0; // Remove trailing line break...
size_t stLength;
while (((stLength = strlen(acTimeString))) && ('\n' == acTimeString[stLength - 1])) {
acTimeString[stLength - 1] = 0; // Remove trailing line break...
}
return acTimeString;
}
@ -186,7 +185,8 @@ void handleHTTPRequest() {
Serial.println("HTTP Request");
// Get current time
time_t now = time(nullptr);;
time_t now = time(nullptr);
;
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
@ -231,10 +231,9 @@ void setup(void) {
// Setup MDNS responder
MDNS.setHostProbeResultCallback(hostProbeResult);
// Init the (currently empty) host domain string with 'esp8266'
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) ||
(!MDNS.begin(pcHostDomain))) {
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) || (!MDNS.begin(pcHostDomain))) {
Serial.println("Error setting up MDNS responder!");
while (1) { // STOP
while (1) { // STOP
delay(1000);
}
}

View File

@ -39,26 +39,26 @@
Global defines and vars
*/
#define SERVICE_PORT 80 // HTTP port
#define SERVICE_PORT 80 // HTTP port
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* ssid = STASSID;
const char* password = STAPSK;
char* pcHostDomain = 0; // Negotiated host domain
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
MDNSResponder::hMDNSService hMDNSService = 0; // The handle of the http service in the MDNS responder
MDNSResponder::hMDNSServiceQuery hMDNSServiceQuery = 0; // The handle of the 'http.tcp' service query in the MDNS responder
char* pcHostDomain = 0; // Negotiated host domain
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
MDNSResponder::hMDNSService hMDNSService = 0; // The handle of the http service in the MDNS responder
MDNSResponder::hMDNSServiceQuery hMDNSServiceQuery = 0; // The handle of the 'http.tcp' service query in the MDNS responder
const String cstrNoHTTPServices = "Currently no 'http.tcp' services in the local network!<br/>";
String strHTTPServices = cstrNoHTTPServices;
const String cstrNoHTTPServices = "Currently no 'http.tcp' services in the local network!<br/>";
String strHTTPServices = cstrNoHTTPServices;
// HTTP server at port 'SERVICE_PORT' will respond to HTTP requests
ESP8266WebServer server(SERVICE_PORT);
ESP8266WebServer server(SERVICE_PORT);
/*
@ -80,26 +80,17 @@ bool setStationHostname(const char* p_pcHostname) {
void MDNSServiceQueryCallback(MDNSResponder::MDNSServiceInfo serviceInfo, MDNSResponder::AnswerType answerType, bool p_bSetContent) {
String answerInfo;
switch (answerType) {
case MDNSResponder::AnswerType::ServiceDomain :
answerInfo = "ServiceDomain " + String(serviceInfo.serviceDomain());
break;
case MDNSResponder::AnswerType::HostDomainAndPort :
answerInfo = "HostDomainAndPort " + String(serviceInfo.hostDomain()) + ":" + String(serviceInfo.hostPort());
break;
case MDNSResponder::AnswerType::IP4Address :
case MDNSResponder::AnswerType::ServiceDomain: answerInfo = "ServiceDomain " + String(serviceInfo.serviceDomain()); break;
case MDNSResponder::AnswerType::HostDomainAndPort: answerInfo = "HostDomainAndPort " + String(serviceInfo.hostDomain()) + ":" + String(serviceInfo.hostPort()); break;
case MDNSResponder::AnswerType::IP4Address:
answerInfo = "IP4Address ";
for (IPAddress ip : serviceInfo.IP4Adresses()) {
answerInfo += "- " + ip.toString();
};
for (IPAddress ip : serviceInfo.IP4Adresses()) { answerInfo += "- " + ip.toString(); };
break;
case MDNSResponder::AnswerType::Txt :
case MDNSResponder::AnswerType::Txt:
answerInfo = "TXT " + String(serviceInfo.strKeyValue());
for (auto kv : serviceInfo.keyValues()) {
answerInfo += "\nkv : " + String(kv.first) + " : " + String(kv.second);
}
for (auto kv : serviceInfo.keyValues()) { answerInfo += "\nkv : " + String(kv.first) + " : " + String(kv.second); }
break;
default :
answerInfo = "Unknown Answertype";
default: answerInfo = "Unknown Answertype";
}
Serial.printf("Answer %s %s\n", answerInfo.c_str(), p_bSetContent ? "Modified" : "Deleted");
}
@ -109,10 +100,8 @@ void MDNSServiceQueryCallback(MDNSResponder::MDNSServiceInfo serviceInfo, MDNSRe
Probe result callback for Services
*/
void serviceProbeResult(String p_pcServiceName,
const MDNSResponder::hMDNSService p_hMDNSService,
bool p_bProbeResult) {
(void) p_hMDNSService;
void serviceProbeResult(String p_pcServiceName, const MDNSResponder::hMDNSService p_hMDNSService, bool p_bProbeResult) {
(void)p_hMDNSService;
Serial.printf("MDNSServiceProbeResultCallback: Service %s probe %s\n", p_pcServiceName.c_str(), (p_bProbeResult ? "succeeded." : "failed!"));
}
@ -186,7 +175,7 @@ void handleHTTPRequest() {
s += WiFi.hostname() + ".local at " + WiFi.localIP().toString() + "</h3></head>";
s += "<br/><h4>Local HTTP services are :</h4>";
s += "<ol>";
for (auto info : MDNS.answerInfo(hMDNSServiceQuery)) {
for (auto info : MDNS.answerInfo(hMDNSServiceQuery)) {
s += "<li>";
s += info.serviceDomain();
if (info.hostDomainAvailable()) {
@ -196,15 +185,11 @@ void handleHTTPRequest() {
}
if (info.IP4AddressAvailable()) {
s += "<br/>IP4:";
for (auto ip : info.IP4Adresses()) {
s += " " + ip.toString();
}
for (auto ip : info.IP4Adresses()) { s += " " + ip.toString(); }
}
if (info.txtAvailable()) {
s += "<br/>TXT:<br/>";
for (auto kv : info.keyValues()) {
s += "\t" + String(kv.first) + " : " + String(kv.second) + "<br/>";
}
for (auto kv : info.keyValues()) { s += "\t" + String(kv.first) + " : " + String(kv.second) + "<br/>"; }
}
s += "</li>";
}
@ -245,10 +230,9 @@ void setup(void) {
MDNS.setHostProbeResultCallback(hostProbeResult);
// Init the (currently empty) host domain string with 'esp8266'
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) ||
(!MDNS.begin(pcHostDomain))) {
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) || (!MDNS.begin(pcHostDomain))) {
Serial.println(" Error setting up MDNS responder!");
while (1) { // STOP
while (1) { // STOP
delay(1000);
}
}
@ -265,6 +249,3 @@ void loop(void) {
// Allow MDNS processing
MDNS.update();
}

View File

@ -14,12 +14,12 @@
#ifndef APSSID
#define APSSID "your-apssid"
#define APPSK "your-password"
#define APPSK "your-password"
#endif
#ifndef STASSID
#define STASSID "your-sta"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
// includes
@ -35,15 +35,15 @@
@brief mDNS and OTA Constants
@{
*/
#define HOSTNAME "ESP8266-OTA-" ///< Hostname. The setup function adds the Chip ID at the end.
#define HOSTNAME "ESP8266-OTA-" ///< Hostname. The setup function adds the Chip ID at the end.
/// @}
/**
@brief Default WiFi connection information.
@{
*/
const char* ap_default_ssid = APSSID; ///< Default SSID.
const char* ap_default_psk = APPSK; ///< Default PSK.
const char *ap_default_ssid = APSSID; ///< Default SSID.
const char *ap_default_psk = APPSK; ///< Default PSK.
/// @}
/// Uncomment the next line for verbose output over UART.
@ -81,9 +81,7 @@ bool loadConfig(String *ssid, String *pass) {
if (pos == -1) {
le = 1;
pos = content.indexOf("\n");
if (pos == -1) {
pos = content.indexOf("\r");
}
if (pos == -1) { pos = content.indexOf("\r"); }
}
// If there is no second line: Some information is missing.
@ -110,7 +108,7 @@ bool loadConfig(String *ssid, String *pass) {
#endif
return true;
} // loadConfig
} // loadConfig
/**
@ -135,7 +133,7 @@ bool saveConfig(String *ssid, String *pass) {
configFile.close();
return true;
} // saveConfig
} // saveConfig
/**
@ -160,7 +158,7 @@ void setup() {
// Print hostname.
Serial.println("Hostname: " + hostname);
//Serial.println(WiFi.hostname());
// Serial.println(WiFi.hostname());
// Initialize file system.
@ -170,7 +168,7 @@ void setup() {
}
// Load wifi connection information.
if (! loadConfig(&station_ssid, &station_psk)) {
if (!loadConfig(&station_ssid, &station_psk)) {
station_ssid = STASSID;
station_psk = STAPSK;
@ -196,7 +194,7 @@ void setup() {
Serial.println(WiFi.SSID());
// ... Uncomment this for debugging output.
//WiFi.printDiag(Serial);
// WiFi.printDiag(Serial);
} else {
// ... Begin with sdk config.
WiFi.begin();
@ -208,7 +206,7 @@ void setup() {
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
Serial.write('.');
//Serial.print(WiFi.status());
// Serial.print(WiFi.status());
delay(500);
}
Serial.println();
@ -245,4 +243,3 @@ void loop() {
// Handle OTA server.
ArduinoOTA.handle();
}

View File

@ -14,12 +14,12 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* ssid = STASSID;
const char* password = STAPSK;
char hostString[16] = {0};
char hostString[16] = { 0 };
void setup() {
Serial.begin(115200);
@ -43,14 +43,12 @@ void setup() {
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (!MDNS.begin(hostString)) {
Serial.println("Error setting up MDNS responder!");
}
if (!MDNS.begin(hostString)) { Serial.println("Error setting up MDNS responder!"); }
Serial.println("mDNS responder started");
MDNS.addService("esp", "tcp", 8080); // Announce esp tcp service on port 8080
MDNS.addService("esp", "tcp", 8080); // Announce esp tcp service on port 8080
Serial.println("Sending mDNS query");
int n = MDNS.queryService("esp", "tcp"); // Send out query for esp tcp services
int n = MDNS.queryService("esp", "tcp"); // Send out query for esp tcp services
Serial.println("mDNS query done");
if (n == 0) {
Serial.println("no services found");

View File

@ -22,7 +22,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -57,9 +57,7 @@ void setup(void) {
// we send our IP address on the WiFi network
if (!MDNS.begin("esp8266")) {
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
while (1) { delay(1000); }
}
Serial.println("mDNS responder started");
@ -77,16 +75,12 @@ void loop(void) {
// Check if a client has connected
WiFiClient client = server.accept();
if (!client) {
return;
}
if (!client) { return; }
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while (client.connected() && !client.available()) {
delay(1);
}
while (client.connected() && !client.available()) { delay(1); }
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
@ -121,4 +115,3 @@ void loop(void) {
Serial.println("Done with client");
}

View File

@ -30,4 +30,3 @@
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
MDNSResponder MDNS;
#endif

View File

@ -3,15 +3,19 @@
This file is part of the esp8266 core for Arduino environment.
mDNS implementation, that supports many mDNS features like:
- Presenting a DNS-SD service to interested observers, eg. a http server by presenting _http._tcp service
- Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented
- Presenting a DNS-SD service to interested observers, eg. a http server by presenting
_http._tcp service
- Support for multi-level compressed names in input; in output only a very simple one-leven
full-name compression is implemented
- Probing host and service domains for uniqueness in the local network
- Tiebreaking while probing is supported in a very minimalistic way (the 'higher' IP address wins the tiebreak)
- Tiebreaking while probing is supported in a very minimalistic way (the 'higher' IP address
wins the tiebreak)
- Announcing available services after successful probing
- Using fixed service TXT items or
- Using dynamic service TXT items for presented services (via callback)
- Remove services (and un-announcing them to the observers by sending goodbye-messages)
- Static queries for DNS-SD services (creating a fixed answer set after a certain timeout period)
- Static queries for DNS-SD services (creating a fixed answer set after a certain timeout
period)
- Dynamic queries for DNS-SD services with cached and updated answers and user notifications
- Support for multi-homed client host domains
@ -41,13 +45,13 @@
#ifndef __ESP8266MDNS_H
#define __ESP8266MDNS_H
#include "LEAmDNS.h" // LEA
#include "LEAmDNS.h" // LEA
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
// Maps the implementation to use to the global namespace type
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; // LEA
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; // LEA
extern MDNSResponder MDNS;
#endif
#endif // __ESP8266MDNS_H
#endif // __ESP8266MDNS_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ namespace MDNSImplementation
// Enable class debug functions
#define ESP_8266_MDNS_INCLUDE
//#define DEBUG_ESP_MDNS_RESPONDER
//#define DEBUG_ESP_MDNS_RESPONDER
#if !defined(DEBUG_ESP_MDNS_RESPONDER) && defined(DEBUG_ESP_MDNS)
#define DEBUG_ESP_MDNS_RESPONDER
@ -48,8 +48,9 @@ namespace MDNSImplementation
#endif
//
// If ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE is defined, the mDNS responder ignores a successful probing
// This allows to drive the responder in a environment, where 'update()' isn't called in the loop
// If ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE is defined, the mDNS responder ignores a successful
// probing This allows to drive the responder in a environment, where 'update()' isn't called in the
// loop
//#define ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
// Enable/disable debug trace macros
@ -62,7 +63,7 @@ namespace MDNSImplementation
#ifdef DEBUG_ESP_MDNS_RESPONDER
#ifdef DEBUG_ESP_MDNS_INFO
#define DEBUG_EX_INFO(A) A
#define DEBUG_EX_INFO(A) A
#else
#define DEBUG_EX_INFO(A)
#endif
@ -72,12 +73,12 @@ namespace MDNSImplementation
#define DEBUG_EX_ERR(A)
#endif
#ifdef DEBUG_ESP_MDNS_TX
#define DEBUG_EX_TX(A) A
#define DEBUG_EX_TX(A) A
#else
#define DEBUG_EX_TX(A)
#endif
#ifdef DEBUG_ESP_MDNS_RX
#define DEBUG_EX_RX(A) A
#define DEBUG_EX_RX(A) A
#else
#define DEBUG_EX_RX(A)
#endif
@ -88,19 +89,34 @@ namespace MDNSImplementation
#define DEBUG_OUTPUT Serial
#endif
#else
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
#define DEBUG_EX_INFO(A) \
do \
{ \
(void)0; \
} while (0)
#define DEBUG_EX_ERR(A) \
do \
{ \
(void)0; \
} while (0)
#define DEBUG_EX_TX(A) \
do \
{ \
(void)0; \
} while (0)
#define DEBUG_EX_RX(A) \
do \
{ \
(void)0; \
} while (0)
#endif
/* already defined in lwIP ('lwip/prot/dns.h')
#ifdef MDNS_IP4_SUPPORT
#define DNS_MQUERY_IPV4_GROUP_INIT (IPAddress(224, 0, 0, 251)) // ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT
#endif
#ifdef MDNS_IP6_SUPPORT
#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) // ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT
#endif*/
#define DNS_MQUERY_IPV4_GROUP_INIT (IPAddress(224, 0, 0, 251)) // ip_addr_t
v4group = DNS_MQUERY_IPV4_GROUP_INIT #endif #ifdef MDNS_IP6_SUPPORT #define
DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) // ip_addr_t v6group =
DNS_MQUERY_IPV6_GROUP_INIT #endif*/
//#define MDNS_MULTICAST_PORT 5353
/*
@ -111,44 +127,44 @@ namespace MDNSImplementation
However, RFC 3171 seems to force 255 instead
*/
#define MDNS_MULTICAST_TTL 255/*1*/
#define MDNS_MULTICAST_TTL 255 /*1*/
/*
This is the MDNS record TTL
Host level records are set to 2min (120s)
service level records are set to 75min (4500s)
*/
#define MDNS_HOST_TTL 120
#define MDNS_SERVICE_TTL 4500
#define MDNS_HOST_TTL 120
#define MDNS_SERVICE_TTL 4500
/*
Compressed labels are flagged by the two topmost bits of the length byte being set
*/
#define MDNS_DOMAIN_COMPRESS_MARK 0xC0
#define MDNS_DOMAIN_COMPRESS_MARK 0xC0
/*
Avoid endless recursion because of malformed compressed labels
*/
#define MDNS_DOMAIN_MAX_REDIRCTION 6
#define MDNS_DOMAIN_MAX_REDIRCTION 6
/*
Default service priority and weight in SRV answers
*/
#define MDNS_SRV_PRIORITY 0
#define MDNS_SRV_WEIGHT 0
#define MDNS_SRV_PRIORITY 0
#define MDNS_SRV_WEIGHT 0
/*
Delay between and number of probes for host and service domains
Delay between and number of announces for host and service domains
Delay between and number of service queries; the delay is multiplied by the resent number in '_checkServiceQueryCache'
Delay between and number of service queries; the delay is multiplied by the resent number in
'_checkServiceQueryCache'
*/
#define MDNS_PROBE_DELAY 250
#define MDNS_PROBE_COUNT 3
#define MDNS_ANNOUNCE_DELAY 1000
#define MDNS_ANNOUNCE_COUNT 8
#define MDNS_PROBE_DELAY 250
#define MDNS_PROBE_COUNT 3
#define MDNS_ANNOUNCE_DELAY 1000
#define MDNS_ANNOUNCE_COUNT 8
#define MDNS_DYNAMIC_QUERY_RESEND_COUNT 5
#define MDNS_DYNAMIC_QUERY_RESEND_DELAY 5000
/*
Force host domain to use only lowercase letters
*/
@ -167,15 +183,14 @@ namespace MDNSImplementation
#ifdef F
#undef F
#endif
#define F(A) A
#define F(A) A
#endif
} // namespace MDNSImplementation
} // namespace MDNSImplementation
} // namespace esp8266
} // namespace esp8266
// Include the main header, so the submodlues only need to include this header
#include "LEAmDNS.h"
#endif // MDNS_PRIV_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,4 +27,4 @@
#include <lwip/prot/dns.h> // DNS_RRTYPE_xxx, DNS_MQUERY_PORT
#endif // MDNS_LWIPDEFS_H
#endif // MDNS_LWIPDEFS_H

View File

@ -22,9 +22,7 @@ void loop() {
sha1("test", &hash[0]);
Serial.print("SHA1:");
for (uint16_t i = 0; i < 20; i++) {
Serial.printf("%02x", hash[i]);
}
for (uint16_t i = 0; i < 20; i++) { Serial.printf("%02x", hash[i]); }
Serial.println();
delay(1000);

View File

@ -15,13 +15,14 @@ void setup() {
// on non-native USB ports
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
; // wait for serial port to connect. Needed for native USB port only
}
// start I2S at 8 kHz with 24-bits per sample
if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 24)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
while (1)
; // do nothing
}
}

View File

@ -10,13 +10,13 @@
#include <I2S.h>
const int frequency = 440; // frequency of square wave in Hz
const int amplitude = 500; // amplitude of square wave
const int sampleRate = 8000; // sample rate in Hz
const int frequency = 440; // frequency of square wave in Hz
const int amplitude = 500; // amplitude of square wave
const int sampleRate = 8000; // sample rate in Hz
const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave
const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave
short sample = amplitude; // current sample value
short sample = amplitude; // current sample value
int count = 0;
void setup() {
@ -26,7 +26,8 @@ void setup() {
// start I2S at the sample rate with 16-bits per sample
if (!I2S.begin(I2S_PHILIPS_MODE, sampleRate, 16)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
while (1)
; // do nothing
}
}
@ -43,4 +44,3 @@ void loop() {
// increment the counter for the next sample
count++;
}

View File

@ -9,7 +9,7 @@
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
@ -19,7 +19,7 @@ long timezone = 2;
byte daysavetime = 1;
void listDir(const char * dirname) {
void listDir(const char *dirname) {
Serial.printf("Listing directory: %s\n", dirname);
Dir root = LittleFS.openDir(dirname);
@ -33,7 +33,7 @@ void listDir(const char * dirname) {
time_t cr = file.getCreationTime();
time_t lw = file.getLastWrite();
file.close();
struct tm * tmstruct = localtime(&cr);
struct tm *tmstruct = localtime(&cr);
Serial.printf(" CREATION: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec);
tmstruct = localtime(&lw);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec);
@ -41,7 +41,7 @@ void listDir(const char * dirname) {
}
void readFile(const char * path) {
void readFile(const char *path) {
Serial.printf("Reading file: %s\n", path);
File file = LittleFS.open(path, "r");
@ -51,13 +51,11 @@ void readFile(const char * path) {
}
Serial.print("Read from file: ");
while (file.available()) {
Serial.write(file.read());
}
while (file.available()) { Serial.write(file.read()); }
file.close();
}
void writeFile(const char * path, const char * message) {
void writeFile(const char *path, const char *message) {
Serial.printf("Writing file: %s\n", path);
File file = LittleFS.open(path, "w");
@ -70,11 +68,11 @@ void writeFile(const char * path, const char * message) {
} else {
Serial.println("Write failed");
}
delay(2000); // Make sure the CREATE and LASTWRITE times are different
delay(2000); // Make sure the CREATE and LASTWRITE times are different
file.close();
}
void appendFile(const char * path, const char * message) {
void appendFile(const char *path, const char *message) {
Serial.printf("Appending to file: %s\n", path);
File file = LittleFS.open(path, "a");
@ -90,7 +88,7 @@ void appendFile(const char * path, const char * message) {
file.close();
}
void renameFile(const char * path1, const char * path2) {
void renameFile(const char *path1, const char *path2) {
Serial.printf("Renaming file %s to %s\n", path1, path2);
if (LittleFS.rename(path1, path2)) {
Serial.println("File renamed");
@ -99,7 +97,7 @@ void renameFile(const char * path1, const char * path2) {
}
}
void deleteFile(const char * path) {
void deleteFile(const char *path) {
Serial.printf("Deleting file: %s\n", path);
if (LittleFS.remove(path)) {
Serial.println("File deleted");
@ -127,7 +125,7 @@ void setup() {
Serial.println(WiFi.localIP());
Serial.println("Contacting Time Server");
configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
struct tm tmstruct ;
struct tm tmstruct;
delay(2000);
tmstruct.tm_year = 0;
getLocalTime(&tmstruct, 5000);
@ -158,9 +156,6 @@ void setup() {
}
readFile("/hello.txt");
listDir("/");
}
void loop() { }
void loop() {}

View File

@ -44,9 +44,7 @@ void DoTest(FS *fs) {
}
uint8_t data[256];
for (int i = 0; i < 256; i++) {
data[i] = (uint8_t) i;
}
for (int i = 0; i < 256; i++) { data[i] = (uint8_t)i; }
Serial.printf("Creating %dKB file, may take a while...\n", TESTSIZEKB);
unsigned long start = millis();
@ -56,9 +54,7 @@ void DoTest(FS *fs) {
return;
}
for (int i = 0; i < TESTSIZEKB; i++) {
for (int j = 0; j < 4; j++) {
f.write(data, 256);
}
for (int j = 0; j < 4; j++) { f.write(data, 256); }
}
f.close();
unsigned long stop = millis();
@ -72,9 +68,7 @@ void DoTest(FS *fs) {
start = millis();
f = fs->open("/testwrite.bin", "r");
for (int i = 0; i < TESTSIZEKB; i++) {
for (int j = 0; j < 4; j++) {
f.read(data, 256);
}
for (int j = 0; j < 4; j++) { f.read(data, 256); }
}
f.close();
stop = millis();
@ -85,9 +79,7 @@ void DoTest(FS *fs) {
f = fs->open("/testwrite.bin", "r");
f.read();
for (int i = 0; i < TESTSIZEKB; i++) {
for (int j = 0; j < 4; j++) {
f.read(data + 1, 256);
}
for (int j = 0; j < 4; j++) { f.read(data + 1, 256); }
}
f.close();
stop = millis();
@ -115,9 +107,7 @@ void DoTest(FS *fs) {
Serial.printf("Writing 64K file in 1-byte chunks\n");
start = millis();
f = fs->open("/test1b.bin", "w");
for (int i = 0; i < 65536; i++) {
f.write((uint8_t*)&i, 1);
}
for (int i = 0; i < 65536; i++) { f.write((uint8_t *)&i, 1); }
f.close();
stop = millis();
Serial.printf("==> Time to write 64KB in 1b chunks = %lu milliseconds = %s\n", stop - start, rate(start, stop, 65536));
@ -127,7 +117,7 @@ void DoTest(FS *fs) {
f = fs->open("/test1b.bin", "r");
for (int i = 0; i < 65536; i++) {
char c;
f.read((uint8_t*)&c, 1);
f.read((uint8_t *)&c, 1);
}
f.close();
stop = millis();

View File

@ -12,7 +12,7 @@ using namespace NetCapture;
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
@ -20,43 +20,36 @@ const char* password = STAPSK;
Netdump nd;
//FS* filesystem = &SPIFFS;
// FS* filesystem = &SPIFFS;
FS* filesystem = &LittleFS;
ESP8266WebServer webServer(80); // Used for sending commands
WiFiServer tcpServer(8000); // Used to show netcat option.
File tracefile;
ESP8266WebServer webServer(80); // Used for sending commands
WiFiServer tcpServer(8000); // Used to show netcat option.
File tracefile;
std::map<PacketType, int> packetCount;
enum class SerialOption : uint8_t {
AllFull,
LocalNone,
HTTPChar
};
enum class SerialOption : uint8_t { AllFull,
LocalNone,
HTTPChar };
void startSerial(SerialOption option) {
switch (option) {
case SerialOption::AllFull : //All Packets, show packet summary.
case SerialOption::AllFull: // All Packets, show packet summary.
nd.printDump(Serial, Packet::PacketDetail::FULL);
break;
case SerialOption::LocalNone : // Only local IP traffic, full details
nd.printDump(Serial, Packet::PacketDetail::NONE,
[](Packet n) {
case SerialOption::LocalNone: // Only local IP traffic, full details
nd.printDump(Serial, Packet::PacketDetail::NONE, [](Packet n) {
return (n.hasIP(WiFi.localIP()));
}
);
});
break;
case SerialOption::HTTPChar : // Only HTTP traffic, show packet content as chars
nd.printDump(Serial, Packet::PacketDetail::CHAR,
[](Packet n) {
case SerialOption::HTTPChar: // Only HTTP traffic, show packet content as chars
nd.printDump(Serial, Packet::PacketDetail::CHAR, [](Packet n) {
return (n.isHTTP());
}
);
});
break;
default :
Serial.printf("No valid SerialOption provided\r\n");
default: Serial.printf("No valid SerialOption provided\r\n");
};
}
@ -80,49 +73,39 @@ void setup(void) {
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed, stopping sketch");
while (1) {
delay(1000);
}
while (1) { delay(1000); }
}
if (!MDNS.begin("netdumphost")) {
Serial.println("Error setting up MDNS responder!");
}
if (!MDNS.begin("netdumphost")) { Serial.println("Error setting up MDNS responder!"); }
filesystem->begin();
webServer.on("/list",
[]() {
webServer.on("/list", []() {
Dir dir = filesystem->openDir("/");
String d = "<h1>File list</h1>";
while (dir.next()) {
d.concat("<li>" + dir.fileName() + "</li>");
}
webServer.send(200, "text.html", d);
}
);
});
webServer.on("/req",
[]() {
webServer.on("/req", []() {
static int rq = 0;
String a = "<h1>You are connected, Number of requests = " + String(rq++) + "</h1>";
webServer.send(200, "text/html", a);
}
);
});
webServer.on("/reset",
[]() {
webServer.on("/reset", []() {
nd.reset();
tracefile.close();
tcpServer.close();
webServer.send(200, "text.html", "<h1>Netdump session reset</h1>");
}
);
});
webServer.serveStatic("/", *filesystem, "/");
webServer.begin();
startSerial(SerialOption::AllFull); // Serial output examples, use enum SerialOption for selection
startSerial(SerialOption::AllFull); // Serial output examples, use enum SerialOption for selection
// startTcpDump(); // tcpdump option
// startTracefile(); // output to SPIFFS or LittleFS
@ -132,18 +115,18 @@ void setup(void) {
nd.setCallback(
[](Packet p)
{
Serial.printf("PKT : %s : ",p.sourceIP().toString().c_str());
for ( auto pp : p.allPacketTypes())
{
Serial.printf("%s ",pp.toString().c_str());
packetCount[pp]++;
}
Serial.printf("\r\n CNT ");
for (auto pc : packetCount)
{
Serial.printf("%s %d ", pc.first.toString().c_str(),pc.second);
}
Serial.printf("\r\n");
Serial.printf("PKT : %s : ",p.sourceIP().toString().c_str());
for ( auto pp : p.allPacketTypes())
{
Serial.printf("%s ",pp.toString().c_str());
packetCount[pp]++;
}
Serial.printf("\r\n CNT ");
for (auto pc : packetCount)
{
Serial.printf("%s %d ", pc.first.toString().c_str(),pc.second);
}
Serial.printf("\r\n");
}
);
*/
@ -153,4 +136,3 @@ void loop(void) {
webServer.handleClient();
MDNS.update();
}

View File

@ -23,7 +23,6 @@
#include <lwip/init.h>
#include "Schedule.h"
namespace NetCapture
{
@ -69,24 +68,26 @@ void Netdump::reset()
void Netdump::printDump(Print& out, Packet::PacketDetail ndd, const Filter nf)
{
out.printf_P(PSTR("netDump starting\r\n"));
setCallback([&out, ndd, this](const Packet & ndp)
{
printDumpProcess(out, ndd, ndp);
}, nf);
setCallback(
[&out, ndd, this](const Packet& ndp)
{
printDumpProcess(out, ndd, ndp);
},
nf);
}
void Netdump::fileDump(File& outfile, const Filter nf)
{
writePcapHeader(outfile);
setCallback([&outfile, this](const Packet & ndp)
{
fileDumpProcess(outfile, ndp);
}, nf);
setCallback(
[&outfile, this](const Packet& ndp)
{
fileDumpProcess(outfile, ndp);
},
nf);
}
bool Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf)
bool Netdump::tcpDump(WiFiServer& tcpDumpServer, const Filter nf)
{
if (!packetBuffer)
{
packetBuffer = new (std::nothrow) char[tcpBufferSize];
@ -98,10 +99,11 @@ bool Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf)
}
bufferIndex = 0;
schedule_function([&tcpDumpServer, this, nf]()
{
tcpDumpLoop(tcpDumpServer, nf);
});
schedule_function(
[&tcpDumpServer, this, nf]()
{
tcpDumpLoop(tcpDumpServer, nf);
});
return true;
}
@ -109,7 +111,8 @@ void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int
{
if (lwipCallback.execute(netif_idx, data, len, out, success) == 0)
{
phy_capture = nullptr; // No active callback/netdump instances, will be set again by new object.
phy_capture
= nullptr; // No active callback/netdump instances, will be set again by new object.
}
}
@ -118,7 +121,7 @@ void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int ou
if (netDumpCallback)
{
Packet np(millis(), netif_idx, data, len, out, success);
if (netDumpFilter && !netDumpFilter(np))
if (netDumpFilter && !netDumpFilter(np))
{
return;
}
@ -131,8 +134,8 @@ void Netdump::writePcapHeader(Stream& s) const
uint32_t pcapHeader[6];
pcapHeader[0] = 0xa1b2c3d4; // pcap magic number
pcapHeader[1] = 0x00040002; // pcap major/minor version
pcapHeader[2] = 0; // pcap UTC correction in seconds
pcapHeader[3] = 0; // pcap time stamp accuracy
pcapHeader[2] = 0; // pcap UTC correction in seconds
pcapHeader[3] = 0; // pcap time stamp accuracy
pcapHeader[4] = maxPcapLength; // pcap max packet length per record
pcapHeader[5] = 1; // pacp data linkt type = ethernet
s.write(reinterpret_cast<char*>(pcapHeader), 24);
@ -145,7 +148,7 @@ void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packe
void Netdump::fileDumpProcess(File& outfile, const Packet& np) const
{
size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize();
size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize();
uint32_t pcapHeader[4];
struct timeval tv;
@ -154,7 +157,7 @@ void Netdump::fileDumpProcess(File& outfile, const Packet& np) const
pcapHeader[1] = tv.tv_usec;
pcapHeader[2] = incl_len;
pcapHeader[3] = np.getPacketSize();
outfile.write(reinterpret_cast<char*>(pcapHeader), 16); // pcap record header
outfile.write(reinterpret_cast<char*>(pcapHeader), 16); // pcap record header
outfile.write(np.rawData(), incl_len);
}
@ -168,16 +171,16 @@ void Netdump::tcpDumpProcess(const Packet& np)
}
size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize();
if (bufferIndex + 16 + incl_len < tcpBufferSize) // only add if enough space available
if (bufferIndex + 16 + incl_len < tcpBufferSize) // only add if enough space available
{
struct timeval tv;
gettimeofday(&tv, nullptr);
uint32_t* pcapHeader = reinterpret_cast<uint32_t*>(&packetBuffer[bufferIndex]);
pcapHeader[0] = tv.tv_sec; // add pcap record header
pcapHeader[1] = tv.tv_usec;
pcapHeader[2] = incl_len;
pcapHeader[3] = np.getPacketSize();
bufferIndex += 16; // pcap header size
pcapHeader[0] = tv.tv_sec; // add pcap record header
pcapHeader[1] = tv.tv_usec;
pcapHeader[2] = incl_len;
pcapHeader[3] = np.getPacketSize();
bufferIndex += 16; // pcap header size
memcpy(&packetBuffer[bufferIndex], np.rawData(), incl_len);
bufferIndex += incl_len;
}
@ -189,7 +192,7 @@ void Netdump::tcpDumpProcess(const Packet& np)
}
}
void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf)
void Netdump::tcpDumpLoop(WiFiServer& tcpDumpServer, const Filter nf)
{
if (tcpDumpServer.hasClient())
{
@ -199,10 +202,12 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf)
bufferIndex = 0;
writePcapHeader(tcpDumpClient);
setCallback([this](const Packet & ndp)
{
tcpDumpProcess(ndp);
}, nf);
setCallback(
[this](const Packet& ndp)
{
tcpDumpProcess(ndp);
},
nf);
}
if (!tcpDumpClient || !tcpDumpClient.connected())
{
@ -216,11 +221,12 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf)
if (tcpDumpServer.status() != CLOSED)
{
schedule_function([&tcpDumpServer, this, nf]()
{
tcpDumpLoop(tcpDumpServer, nf);
});
schedule_function(
[&tcpDumpServer, this, nf]()
{
tcpDumpLoop(tcpDumpServer, nf);
});
}
}
} // namespace NetCapture
} // namespace NetCapture

View File

@ -38,9 +38,8 @@ using namespace experimental::CBListImplentation;
class Netdump
{
public:
using Filter = std::function<bool(const Packet&)>;
using Callback = std::function<void(const Packet&)>;
using Filter = std::function<bool(const Packet&)>;
using Callback = std::function<void(const Packet&)>;
using LwipCallback = std::function<void(int, const char*, int, int, int)>;
Netdump();
@ -53,15 +52,14 @@ public:
void printDump(Print& out, Packet::PacketDetail ndd, const Filter nf = nullptr);
void fileDump(File& outfile, const Filter nf = nullptr);
bool tcpDump(WiFiServer &tcpDumpServer, const Filter nf = nullptr);
bool tcpDump(WiFiServer& tcpDumpServer, const Filter nf = nullptr);
private:
Callback netDumpCallback = nullptr;
Filter netDumpFilter = nullptr;
static void capture(int netif_idx, const char* data, size_t len, int out, int success);
static CallBackList<LwipCallback> lwipCallback;
static CallBackList<LwipCallback> lwipCallback;
CallBackList<LwipCallback>::CallBackHandler lwipHandler;
void netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success);
@ -69,19 +67,19 @@ private:
void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const;
void fileDumpProcess(File& outfile, const Packet& np) const;
void tcpDumpProcess(const Packet& np);
void tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf);
void tcpDumpLoop(WiFiServer& tcpDumpServer, const Filter nf);
void writePcapHeader(Stream& s) const;
WiFiClient tcpDumpClient;
char* packetBuffer = nullptr;
int bufferIndex = 0;
char* packetBuffer = nullptr;
int bufferIndex = 0;
static constexpr int tcpBufferSize = 2048;
static constexpr int maxPcapLength = 1024;
static constexpr uint32_t pcapMagic = 0xa1b2c3d4;
static constexpr int tcpBufferSize = 2048;
static constexpr int maxPcapLength = 1024;
static constexpr uint32_t pcapMagic = 0xa1b2c3d4;
};
} // namespace NetCapture
} // namespace NetCapture
#endif /* __NETDUMP_H */

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