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' python-version: '3.x'
- name: Style check - name: Style check
env: env:
LLVM_SNAPSHOT_KEY: "6084F3CF814B57C1CF12EFD515CF4D18AF4F7421"
TRAVIS_BUILD_DIR: ${{ github.workspace }} TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }} TRAVIS_TAG: ${{ github.ref }}
run: | 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 update
sudo apt install astyle sudo apt install clang-format-13
pip3 install pyyaml
bash ./tests/ci/style_check.sh bash ./tests/ci/style_check.sh

View File

@ -35,8 +35,7 @@ DhcpServer dhcpSoftAP(&netif_git[SOFTAP_IF]);
extern "C" 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 // apnetif is esp interface, replaced by lwip2's
// netif_git[SOFTAP_IF] interface in constructor // netif_git[SOFTAP_IF] interface in constructor

View File

@ -107,10 +107,9 @@ struct dhcps_pool
uint32 lease_timer; uint32 lease_timer;
dhcps_type_t type; dhcps_type_t type;
dhcps_state_t state; dhcps_state_t state;
}; };
#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 #define DHCPS_LEASE_TIMER dhcps_lease_time // 0x05A0
#define DHCPS_MAX_LEASE 0x64 #define DHCPS_MAX_LEASE 0x64
#define BOOTP_BROADCAST 0x8000 #define BOOTP_BROADCAST 0x8000
@ -162,9 +161,18 @@ const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
#endif #endif
#if DHCPS_DEBUG #if DHCPS_DEBUG
#define LWIP_IS_OK(what,err) ({ int ret = 1, errval = (err); if (errval != ERR_OK) { os_printf("DHCPS ERROR: %s (lwip:%d)\n", what, errval); ret = 0; } ret; }) #define LWIP_IS_OK(what, err) \
({ \
int ret = 1, errval = (err); \
if (errval != ERR_OK) \
{ \
os_printf("DHCPS ERROR: %s (lwip:%d)\n", what, errval); \
ret = 0; \
} \
ret; \
})
#else #else
#define LWIP_IS_OK(what,err) ((err) == ERR_OK) #define LWIP_IS_OK(what, err) ((err) == ERR_OK)
#endif #endif
const uint32 DhcpServer::magic_cookie = 0x63538263; // https://tools.ietf.org/html/rfc1497 const uint32 DhcpServer::magic_cookie = 0x63538263; // https://tools.ietf.org/html/rfc1497
@ -173,14 +181,14 @@ int fw_has_started_softap_dhcps = 0;
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
DhcpServer::DhcpServer(netif* netif): _netif(netif) DhcpServer::DhcpServer(netif* netif) : _netif(netif)
{ {
pcb_dhcps = nullptr; pcb_dhcps = nullptr;
dns_address.addr = 0; dns_address.addr = 0;
plist = nullptr; plist = nullptr;
offer = 0xFF; offer = 0xFF;
renew = false; renew = false;
dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute dhcps_lease_time = DHCPS_LEASE_TIME_DEF; // minute
if (netif->num == SOFTAP_IF && fw_has_started_softap_dhcps == 1) if (netif->num == SOFTAP_IF && fw_has_started_softap_dhcps == 1)
{ {
@ -188,8 +196,7 @@ DhcpServer::DhcpServer(netif* netif): _netif(netif)
// 1. `fw_has_started_softap_dhcps` is already initialized to 1 // 1. `fw_has_started_softap_dhcps` is already initialized to 1
// 2. global ctor DhcpServer's `dhcpSoftAP(&netif_git[SOFTAP_IF])` is called // 2. global ctor DhcpServer's `dhcpSoftAP(&netif_git[SOFTAP_IF])` is called
// 3. (that's here) => begin(legacy-values) is called // 3. (that's here) => begin(legacy-values) is called
ip_info ip = ip_info ip = {
{
{ 0x0104a8c0 }, // IP 192.168.4.1 { 0x0104a8c0 }, // IP 192.168.4.1
{ 0x00ffffff }, // netmask 255.255.255.0 { 0x00ffffff }, // netmask 255.255.255.0
{ 0 } // gateway 0.0.0.0 { 0 } // gateway 0.0.0.0
@ -217,11 +224,11 @@ void DhcpServer::dhcps_set_dns(int num, const ipv4_addr_t* dns)
Parameters : arg -- Additional argument to pass to the callback function Parameters : arg -- Additional argument to pass to the callback function
Returns : none Returns : none
*******************************************************************************/ *******************************************************************************/
void DhcpServer::node_insert_to_list(list_node **phead, list_node* pinsert) void DhcpServer::node_insert_to_list(list_node** phead, list_node* pinsert)
{ {
list_node *plist = nullptr; list_node* plist = nullptr;
struct dhcps_pool *pdhcps_pool = nullptr; struct dhcps_pool* pdhcps_pool = nullptr;
struct dhcps_pool *pdhcps_node = nullptr; struct dhcps_pool* pdhcps_node = nullptr;
if (*phead == nullptr) if (*phead == nullptr)
{ {
*phead = pinsert; *phead = pinsert;
@ -266,9 +273,9 @@ void DhcpServer::node_insert_to_list(list_node **phead, list_node* pinsert)
Parameters : arg -- Additional argument to pass to the callback function Parameters : arg -- Additional argument to pass to the callback function
Returns : none Returns : none
*******************************************************************************/ *******************************************************************************/
void DhcpServer::node_remove_from_list(list_node **phead, list_node* pdelete) void DhcpServer::node_remove_from_list(list_node** phead, list_node* pdelete)
{ {
list_node *plist = nullptr; list_node* plist = nullptr;
plist = *phead; plist = *phead;
if (plist == nullptr) if (plist == nullptr)
@ -303,10 +310,10 @@ void DhcpServer::node_remove_from_list(list_node **phead, list_node* pdelete)
Parameters : mac address Parameters : mac address
Returns : true if ok and false if this mac already exist or if all ip are already reserved Returns : true if ok and false if this mac already exist or if all ip are already reserved
*******************************************************************************/ *******************************************************************************/
bool DhcpServer::add_dhcps_lease(uint8 *macaddr) bool DhcpServer::add_dhcps_lease(uint8* macaddr)
{ {
struct dhcps_pool *pdhcps_pool = nullptr; struct dhcps_pool* pdhcps_pool = nullptr;
list_node *pback_node = nullptr; list_node* pback_node = nullptr;
uint32 start_ip = dhcps_lease.start_ip.addr; uint32 start_ip = dhcps_lease.start_ip.addr;
uint32 end_ip = dhcps_lease.end_ip.addr; uint32 end_ip = dhcps_lease.end_ip.addr;
@ -335,13 +342,13 @@ bool DhcpServer::add_dhcps_lease(uint8 *macaddr)
return false; return false;
} }
pdhcps_pool = (struct dhcps_pool *)zalloc(sizeof(struct dhcps_pool)); pdhcps_pool = (struct dhcps_pool*)zalloc(sizeof(struct dhcps_pool));
pdhcps_pool->ip.addr = start_ip; pdhcps_pool->ip.addr = start_ip;
memcpy(pdhcps_pool->mac, macaddr, sizeof(pdhcps_pool->mac)); memcpy(pdhcps_pool->mac, macaddr, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = DHCPS_TYPE_STATIC; pdhcps_pool->type = DHCPS_TYPE_STATIC;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
pback_node = (list_node *)zalloc(sizeof(list_node)); pback_node = (list_node*)zalloc(sizeof(list_node));
pback_node->pnode = pdhcps_pool; pback_node->pnode = pdhcps_pool;
pback_node->pnext = nullptr; pback_node->pnext = nullptr;
node_insert_to_list(&plist, pback_node); node_insert_to_list(&plist, pback_node);
@ -359,9 +366,8 @@ bool DhcpServer::add_dhcps_lease(uint8 *macaddr)
@return uint8_t* DHCP msg @return uint8_t* DHCP msg
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
uint8_t* DhcpServer::add_msg_type(uint8_t *optptr, uint8_t type) uint8_t* DhcpServer::add_msg_type(uint8_t* optptr, uint8_t type)
{ {
*optptr++ = DHCP_OPTION_MSG_TYPE; *optptr++ = DHCP_OPTION_MSG_TYPE;
*optptr++ = 1; *optptr++ = 1;
*optptr++ = type; *optptr++ = type;
@ -376,15 +382,15 @@ uint8_t* DhcpServer::add_msg_type(uint8_t *optptr, uint8_t type)
@return uint8_t* DHCP msg @return uint8_t* DHCP msg
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
uint8_t* DhcpServer::add_offer_options(uint8_t *optptr) uint8_t* DhcpServer::add_offer_options(uint8_t* optptr)
{ {
//struct ipv4_addr ipadd; // struct ipv4_addr ipadd;
//ipadd.addr = server_address.addr; // ipadd.addr = server_address.addr;
#define ipadd (_netif->ip_addr) #define ipadd (_netif->ip_addr)
//struct ip_info if_ip; // struct ip_info if_ip;
//bzero(&if_ip, sizeof(struct ip_info)); // bzero(&if_ip, sizeof(struct ip_info));
//wifi_get_ip_info(SOFTAP_IF, &if_ip); // wifi_get_ip_info(SOFTAP_IF, &if_ip);
#define if_ip (*_netif) #define if_ip (*_netif)
*optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_SUBNET_MASK;
@ -483,15 +489,14 @@ uint8_t* DhcpServer::add_offer_options(uint8_t *optptr)
@return uint8_t* DHCP msg @return uint8_t* DHCP msg
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
uint8_t* DhcpServer::add_end(uint8_t *optptr) uint8_t* DhcpServer::add_end(uint8_t* optptr)
{ {
*optptr++ = DHCP_OPTION_END; *optptr++ = DHCP_OPTION_END;
return optptr; return optptr;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void DhcpServer::create_msg(struct dhcps_msg *m) void DhcpServer::create_msg(struct dhcps_msg* m)
{ {
struct ipv4_addr client; struct ipv4_addr client;
@ -504,14 +509,14 @@ void DhcpServer::create_msg(struct dhcps_msg *m)
m->secs = 0; m->secs = 0;
m->flags = htons(BOOTP_BROADCAST); m->flags = htons(BOOTP_BROADCAST);
memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr)); memcpy((char*)m->yiaddr, (char*)&client.addr, sizeof(m->yiaddr));
memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); memset((char*)m->ciaddr, 0, sizeof(m->ciaddr));
memset((char *) m->siaddr, 0, sizeof(m->siaddr)); memset((char*)m->siaddr, 0, sizeof(m->siaddr));
memset((char *) m->giaddr, 0, sizeof(m->giaddr)); memset((char*)m->giaddr, 0, sizeof(m->giaddr));
memset((char *) m->sname, 0, sizeof(m->sname)); memset((char*)m->sname, 0, sizeof(m->sname));
memset((char *) m->file, 0, sizeof(m->file)); memset((char*)m->file, 0, sizeof(m->file));
memset((char *) m->options, 0, sizeof(m->options)); memset((char*)m->options, 0, sizeof(m->options));
memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie)); memcpy((char*)m->options, &magic_cookie, sizeof(magic_cookie));
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
@ -520,11 +525,11 @@ void DhcpServer::create_msg(struct dhcps_msg *m)
@param -- m DHCP msg @param -- m DHCP msg
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void DhcpServer::send_offer(struct dhcps_msg *m) void DhcpServer::send_offer(struct dhcps_msg* m)
{ {
uint8_t *end; uint8_t* end;
struct pbuf *p, *q; struct pbuf *p, *q;
u8_t *data; u8_t* data;
u16_t cnt = 0; u16_t cnt = 0;
u16_t i; u16_t i;
create_msg(m); create_msg(m);
@ -539,7 +544,6 @@ void DhcpServer::send_offer(struct dhcps_msg *m)
#endif #endif
if (p != nullptr) if (p != nullptr)
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_offer>>pbuf_alloc succeed\n"); os_printf("dhcps: send_offer>>pbuf_alloc succeed\n");
os_printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); os_printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len);
@ -548,10 +552,10 @@ void DhcpServer::send_offer(struct dhcps_msg *m)
q = p; q = p;
while (q != nullptr) while (q != nullptr)
{ {
data = (u8_t *)q->payload; data = (u8_t*)q->payload;
for (i = 0; i < q->len; i++) for (i = 0; i < q->len; i++)
{ {
data[i] = ((u8_t *) m)[cnt++]; data[i] = ((u8_t*)m)[cnt++];
} }
q = q->next; q = q->next;
@ -559,7 +563,6 @@ void DhcpServer::send_offer(struct dhcps_msg *m)
} }
else else
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_offer>>pbuf_alloc failed\n"); os_printf("dhcps: send_offer>>pbuf_alloc failed\n");
#endif #endif
@ -586,12 +589,11 @@ void DhcpServer::send_offer(struct dhcps_msg *m)
@param m DHCP msg @param m DHCP msg
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void DhcpServer::send_nak(struct dhcps_msg *m) void DhcpServer::send_nak(struct dhcps_msg* m)
{ {
u8_t* end;
u8_t *end;
struct pbuf *p, *q; struct pbuf *p, *q;
u8_t *data; u8_t* data;
u16_t cnt = 0; u16_t cnt = 0;
u16_t i; u16_t i;
create_msg(m); create_msg(m);
@ -605,7 +607,6 @@ void DhcpServer::send_nak(struct dhcps_msg *m)
#endif #endif
if (p != nullptr) if (p != nullptr)
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_nak>>pbuf_alloc succeed\n"); os_printf("dhcps: send_nak>>pbuf_alloc succeed\n");
os_printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); os_printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len);
@ -614,10 +615,10 @@ void DhcpServer::send_nak(struct dhcps_msg *m)
q = p; q = p;
while (q != nullptr) while (q != nullptr)
{ {
data = (u8_t *)q->payload; data = (u8_t*)q->payload;
for (i = 0; i < q->len; i++) for (i = 0; i < q->len; i++)
{ {
data[i] = ((u8_t *) m)[cnt++]; data[i] = ((u8_t*)m)[cnt++];
} }
q = q->next; q = q->next;
@ -625,7 +626,6 @@ void DhcpServer::send_nak(struct dhcps_msg *m)
} }
else else
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_nak>>pbuf_alloc failed\n"); os_printf("dhcps: send_nak>>pbuf_alloc failed\n");
#endif #endif
@ -647,12 +647,11 @@ void DhcpServer::send_nak(struct dhcps_msg *m)
@param m DHCP msg @param m DHCP msg
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void DhcpServer::send_ack(struct dhcps_msg *m) void DhcpServer::send_ack(struct dhcps_msg* m)
{ {
u8_t* end;
u8_t *end;
struct pbuf *p, *q; struct pbuf *p, *q;
u8_t *data; u8_t* data;
u16_t cnt = 0; u16_t cnt = 0;
u16_t i; u16_t i;
create_msg(m); create_msg(m);
@ -667,7 +666,6 @@ void DhcpServer::send_ack(struct dhcps_msg *m)
#endif #endif
if (p != nullptr) if (p != nullptr)
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_ack>>pbuf_alloc succeed\n"); os_printf("dhcps: send_ack>>pbuf_alloc succeed\n");
os_printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); os_printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len);
@ -676,10 +674,10 @@ void DhcpServer::send_ack(struct dhcps_msg *m)
q = p; q = p;
while (q != nullptr) while (q != nullptr)
{ {
data = (u8_t *)q->payload; data = (u8_t*)q->payload;
for (i = 0; i < q->len; i++) for (i = 0; i < q->len; i++)
{ {
data[i] = ((u8_t *) m)[cnt++]; data[i] = ((u8_t*)m)[cnt++];
} }
q = q->next; q = q->next;
@ -687,13 +685,13 @@ void DhcpServer::send_ack(struct dhcps_msg *m)
} }
else else
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_ack>>pbuf_alloc failed\n"); os_printf("dhcps: send_ack>>pbuf_alloc failed\n");
#endif #endif
return; return;
} }
if (!LWIP_IS_OK("dhcps send ack", udp_sendto(pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT))) if (!LWIP_IS_OK("dhcps send ack",
udp_sendto(pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT)))
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_ack>>udp_sendto\n"); os_printf("dhcps: send_ack>>udp_sendto\n");
@ -718,7 +716,7 @@ void DhcpServer::send_ack(struct dhcps_msg *m)
@return uint8_t* DHCP Server @return uint8_t* DHCP Server
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
uint8_t DhcpServer::parse_options(uint8_t *optptr, sint16_t len) uint8_t DhcpServer::parse_options(uint8_t* optptr, sint16_t len)
{ {
struct ipv4_addr client; struct ipv4_addr client;
bool is_dhcp_parse_end = false; bool is_dhcp_parse_end = false;
@ -726,7 +724,7 @@ uint8_t DhcpServer::parse_options(uint8_t *optptr, sint16_t len)
client.addr = client_address.addr; client.addr = client_address.addr;
u8_t *end = optptr + len; u8_t* end = optptr + len;
u16_t type = 0; u16_t type = 0;
s.state = DHCPS_STATE_IDLE; s.state = DHCPS_STATE_IDLE;
@ -736,16 +734,15 @@ uint8_t DhcpServer::parse_options(uint8_t *optptr, sint16_t len)
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr);
#endif #endif
switch ((sint16_t) *optptr) switch ((sint16_t)*optptr)
{ {
case DHCP_OPTION_MSG_TYPE: // 53
case DHCP_OPTION_MSG_TYPE: //53
type = *(optptr + 2); type = *(optptr + 2);
break; break;
case DHCP_OPTION_REQ_IPADDR://50 case DHCP_OPTION_REQ_IPADDR: // 50
//os_printf("dhcps:0x%08x,0x%08x\n",client.addr,*(uint32*)(optptr+2)); // os_printf("dhcps:0x%08x,0x%08x\n",client.addr,*(uint32*)(optptr+2));
if (memcmp((char *) &client.addr, (char *) optptr + 2, 4) == 0) if (memcmp((char*)&client.addr, (char*)optptr + 2, 4) == 0)
{ {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n");
@ -777,14 +774,14 @@ uint8_t DhcpServer::parse_options(uint8_t *optptr, sint16_t len)
switch (type) switch (type)
{ {
case DHCPDISCOVER://1 case DHCPDISCOVER: // 1
s.state = DHCPS_STATE_OFFER; s.state = DHCPS_STATE_OFFER;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_OFFER\n"); os_printf("dhcps: DHCPD_STATE_OFFER\n");
#endif #endif
break; break;
case DHCPREQUEST://3 case DHCPREQUEST: // 3
if (!(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK)) if (!(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK))
{ {
if (renew == true) if (renew == true)
@ -801,14 +798,14 @@ uint8_t DhcpServer::parse_options(uint8_t *optptr, sint16_t len)
} }
break; break;
case DHCPDECLINE://4 case DHCPDECLINE: // 4
s.state = DHCPS_STATE_IDLE; s.state = DHCPS_STATE_IDLE;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_IDLE\n"); os_printf("dhcps: DHCPD_STATE_IDLE\n");
#endif #endif
break; break;
case DHCPRELEASE://7 case DHCPRELEASE: // 7
s.state = DHCPS_STATE_RELEASE; s.state = DHCPS_STATE_RELEASE;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_IDLE\n"); os_printf("dhcps: DHCPD_STATE_IDLE\n");
@ -822,11 +819,9 @@ uint8_t DhcpServer::parse_options(uint8_t *optptr, sint16_t len)
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
sint16_t DhcpServer::parse_msg(struct dhcps_msg *m, u16_t len) sint16_t DhcpServer::parse_msg(struct dhcps_msg* m, u16_t len)
{ {
if (memcmp((char *)m->options, if (memcmp((char*)m->options, &magic_cookie, sizeof(magic_cookie)) == 0)
&magic_cookie,
sizeof(magic_cookie)) == 0)
{ {
struct ipv4_addr ip; struct ipv4_addr ip;
memcpy(&ip.addr, m->ciaddr, sizeof(ip.addr)); memcpy(&ip.addr, m->ciaddr, sizeof(ip.addr));
@ -857,32 +852,26 @@ sint16_t DhcpServer::parse_msg(struct dhcps_msg *m, u16_t len)
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void DhcpServer::S_handle_dhcp(void *arg, void DhcpServer::S_handle_dhcp(void* arg, struct udp_pcb* pcb, struct pbuf* p,
struct udp_pcb *pcb, const ip_addr_t* addr, uint16_t port)
struct pbuf *p,
const ip_addr_t *addr,
uint16_t port)
{ {
DhcpServer* instance = reinterpret_cast<DhcpServer*>(arg); DhcpServer* instance = reinterpret_cast<DhcpServer*>(arg);
instance->handle_dhcp(pcb, p, addr, port); instance->handle_dhcp(pcb, p, addr, port);
} }
void DhcpServer::handle_dhcp( void DhcpServer::handle_dhcp(struct udp_pcb* pcb, struct pbuf* p, const ip_addr_t* addr,
struct udp_pcb *pcb,
struct pbuf *p,
const ip_addr_t *addr,
uint16_t port) uint16_t port)
{ {
(void)pcb; (void)pcb;
(void)addr; (void)addr;
(void)port; (void)port;
struct dhcps_msg *pmsg_dhcps = nullptr; struct dhcps_msg* pmsg_dhcps = nullptr;
sint16_t tlen = 0; sint16_t tlen = 0;
u16_t i = 0; u16_t i = 0;
u16_t dhcps_msg_cnt = 0; u16_t dhcps_msg_cnt = 0;
u8_t *p_dhcps_msg = nullptr; u8_t* p_dhcps_msg = nullptr;
u8_t *data = nullptr; u8_t* data = nullptr;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> receive a packet\n"); os_printf("dhcps: handle_dhcp-> receive a packet\n");
@ -892,13 +881,13 @@ void DhcpServer::handle_dhcp(
return; return;
} }
pmsg_dhcps = (struct dhcps_msg *)zalloc(sizeof(struct dhcps_msg)); pmsg_dhcps = (struct dhcps_msg*)zalloc(sizeof(struct dhcps_msg));
if (nullptr == pmsg_dhcps) if (nullptr == pmsg_dhcps)
{ {
pbuf_free(p); pbuf_free(p);
return; return;
} }
p_dhcps_msg = (u8_t *)pmsg_dhcps; p_dhcps_msg = (u8_t*)pmsg_dhcps;
tlen = p->tot_len; tlen = p->tot_len;
data = (u8_t*)p->payload; data = (u8_t*)p->payload;
@ -933,14 +922,13 @@ void DhcpServer::handle_dhcp(
switch (parse_msg(pmsg_dhcps, tlen - 240)) switch (parse_msg(pmsg_dhcps, tlen - 240))
{ {
case DHCPS_STATE_OFFER: // 1
case DHCPS_STATE_OFFER://1
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n");
#endif #endif
send_offer(pmsg_dhcps); send_offer(pmsg_dhcps);
break; break;
case DHCPS_STATE_ACK://3 case DHCPS_STATE_ACK: // 3
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
#endif #endif
@ -950,13 +938,13 @@ void DhcpServer::handle_dhcp(
wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address); wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address);
} }
break; break;
case DHCPS_STATE_NAK://4 case DHCPS_STATE_NAK: // 4
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
#endif #endif
send_nak(pmsg_dhcps); send_nak(pmsg_dhcps);
break; break;
default : default:
break; break;
} }
#if DHCPS_DEBUG #if DHCPS_DEBUG
@ -1005,7 +993,7 @@ void DhcpServer::init_dhcps_lease(uint32 ip)
} }
else else
{ {
local_ip ++; local_ip++;
} }
bzero(&dhcps_lease, sizeof(dhcps_lease)); bzero(&dhcps_lease, sizeof(dhcps_lease));
@ -1020,7 +1008,7 @@ void DhcpServer::init_dhcps_lease(uint32 ip)
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
bool DhcpServer::begin(struct ip_info *info) bool DhcpServer::begin(struct ip_info* info)
{ {
if (pcb_dhcps != nullptr) if (pcb_dhcps != nullptr)
{ {
@ -1040,7 +1028,7 @@ bool DhcpServer::begin(struct ip_info *info)
broadcast_dhcps = _netif->ip_addr; broadcast_dhcps = _netif->ip_addr;
ip_2_ip4(&broadcast_dhcps)->addr &= ip_2_ip4(&_netif->netmask)->addr; ip_2_ip4(&broadcast_dhcps)->addr &= ip_2_ip4(&_netif->netmask)->addr;
ip_2_ip4(&broadcast_dhcps)->addr |= ~ip_2_ip4(&_netif->netmask)->addr; ip_2_ip4(&broadcast_dhcps)->addr |= ~ip_2_ip4(&_netif->netmask)->addr;
//XXXFIXMEIPV6 broadcast address? // XXXFIXMEIPV6 broadcast address?
server_address = info->ip; server_address = info->ip;
init_dhcps_lease(server_address.addr); init_dhcps_lease(server_address.addr);
@ -1048,7 +1036,8 @@ bool DhcpServer::begin(struct ip_info *info)
udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT);
udp_recv(pcb_dhcps, S_handle_dhcp, this); udp_recv(pcb_dhcps, S_handle_dhcp, this);
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB "
"pcb_dhcps\n");
#endif #endif
if (_netif->num == SOFTAP_IF) if (_netif->num == SOFTAP_IF)
@ -1076,9 +1065,9 @@ void DhcpServer::end()
udp_remove(pcb_dhcps); udp_remove(pcb_dhcps);
pcb_dhcps = nullptr; pcb_dhcps = nullptr;
//udp_remove(pcb_dhcps); // udp_remove(pcb_dhcps);
list_node *pnode = nullptr; list_node* pnode = nullptr;
list_node *pback_node = nullptr; list_node* pback_node = nullptr;
struct dhcps_pool* dhcp_node = nullptr; struct dhcps_pool* dhcp_node = nullptr;
struct ipv4_addr ip_zero; struct ipv4_addr ip_zero;
@ -1090,7 +1079,7 @@ void DhcpServer::end()
pnode = pback_node->pnext; pnode = pback_node->pnext;
node_remove_from_list(&plist, pback_node); node_remove_from_list(&plist, pback_node);
dhcp_node = (struct dhcps_pool*)pback_node->pnode; dhcp_node = (struct dhcps_pool*)pback_node->pnode;
//dhcps_client_leave(dhcp_node->mac,&dhcp_node->ip,true); // force to delete // dhcps_client_leave(dhcp_node->mac,&dhcp_node->ip,true); // force to delete
if (_netif->num == SOFTAP_IF) if (_netif->num == SOFTAP_IF)
{ {
wifi_softap_set_station_info(dhcp_node->mac, &ip_zero); wifi_softap_set_station_info(dhcp_node->mac, &ip_zero);
@ -1107,7 +1096,6 @@ bool DhcpServer::isRunning()
return !!_netif->state; return !!_netif->state;
} }
/****************************************************************************** /******************************************************************************
FunctionName : set_dhcps_lease FunctionName : set_dhcps_lease
Description : set the lease information of DHCP server Description : set the lease information of DHCP server
@ -1115,7 +1103,7 @@ bool DhcpServer::isRunning()
Little-Endian. Little-Endian.
Returns : true or false Returns : true or false
*******************************************************************************/ *******************************************************************************/
bool DhcpServer::set_dhcps_lease(struct dhcps_lease *please) bool DhcpServer::set_dhcps_lease(struct dhcps_lease* please)
{ {
uint32 softap_ip = 0; uint32 softap_ip = 0;
uint32 start_ip = 0; uint32 start_ip = 0;
@ -1151,8 +1139,7 @@ bool DhcpServer::set_dhcps_lease(struct dhcps_lease *please)
/*config ip information must be in the same segment as the local ip*/ /*config ip information must be in the same segment as the local ip*/
softap_ip >>= 8; softap_ip >>= 8;
if ((start_ip >> 8 != softap_ip) if ((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip))
|| (end_ip >> 8 != softap_ip))
{ {
return false; return false;
} }
@ -1180,7 +1167,7 @@ bool DhcpServer::set_dhcps_lease(struct dhcps_lease *please)
Little-Endian. Little-Endian.
Returns : true or false Returns : true or false
*******************************************************************************/ *******************************************************************************/
bool DhcpServer::get_dhcps_lease(struct dhcps_lease *please) bool DhcpServer::get_dhcps_lease(struct dhcps_lease* please)
{ {
if (_netif->num == SOFTAP_IF) if (_netif->num == SOFTAP_IF)
{ {
@ -1225,8 +1212,8 @@ bool DhcpServer::get_dhcps_lease(struct dhcps_lease *please)
void DhcpServer::kill_oldest_dhcps_pool(void) void DhcpServer::kill_oldest_dhcps_pool(void)
{ {
list_node *pre = nullptr, *p = nullptr; list_node * pre = nullptr, *p = nullptr;
list_node *minpre = nullptr, *minp = nullptr; list_node * minpre = nullptr, *minp = nullptr;
struct dhcps_pool *pdhcps_pool = nullptr, *pmin_pool = nullptr; struct dhcps_pool *pdhcps_pool = nullptr, *pmin_pool = nullptr;
pre = plist; pre = plist;
p = pre->pnext; p = pre->pnext;
@ -1244,7 +1231,8 @@ void DhcpServer::kill_oldest_dhcps_pool(void)
pre = p; pre = p;
p = p->pnext; p = p->pnext;
} }
minpre->pnext = minp->pnext; pdhcps_pool->state = DHCPS_STATE_OFFLINE; minpre->pnext = minp->pnext;
pdhcps_pool->state = DHCPS_STATE_OFFLINE;
free(minp->pnode); free(minp->pnode);
minp->pnode = nullptr; minp->pnode = nullptr;
free(minp); free(minp);
@ -1254,16 +1242,16 @@ void DhcpServer::kill_oldest_dhcps_pool(void)
void DhcpServer::dhcps_coarse_tmr(void) void DhcpServer::dhcps_coarse_tmr(void)
{ {
uint8 num_dhcps_pool = 0; uint8 num_dhcps_pool = 0;
list_node *pback_node = nullptr; list_node* pback_node = nullptr;
list_node *pnode = nullptr; list_node* pnode = nullptr;
struct dhcps_pool *pdhcps_pool = nullptr; struct dhcps_pool* pdhcps_pool = nullptr;
pnode = plist; pnode = plist;
while (pnode != nullptr) while (pnode != nullptr)
{ {
pdhcps_pool = (struct dhcps_pool*)pnode->pnode; pdhcps_pool = (struct dhcps_pool*)pnode->pnode;
if (pdhcps_pool->type == DHCPS_TYPE_DYNAMIC) if (pdhcps_pool->type == DHCPS_TYPE_DYNAMIC)
{ {
pdhcps_pool->lease_timer --; pdhcps_pool->lease_timer--;
} }
if (pdhcps_pool->lease_timer == 0) if (pdhcps_pool->lease_timer == 0)
{ {
@ -1277,8 +1265,8 @@ void DhcpServer::dhcps_coarse_tmr(void)
} }
else else
{ {
pnode = pnode ->pnext; pnode = pnode->pnext;
num_dhcps_pool ++; num_dhcps_pool++;
} }
} }
@ -1291,7 +1279,7 @@ void DhcpServer::dhcps_coarse_tmr(void)
bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg) bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg)
{ {
bool offer_flag = true; bool offer_flag = true;
//uint8 option = 0; // uint8 option = 0;
if (optarg == nullptr && !isRunning()) if (optarg == nullptr && !isRunning())
{ {
return false; return false;
@ -1305,10 +1293,10 @@ bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg)
switch (level) switch (level)
{ {
case OFFER_ROUTER: case OFFER_ROUTER:
offer = (*(uint8 *)optarg) & 0x01; offer = (*(uint8*)optarg) & 0x01;
offer_flag = true; offer_flag = true;
break; break;
default : default:
offer_flag = false; offer_flag = false;
break; break;
} }
@ -1363,10 +1351,10 @@ uint32 DhcpServer::get_dhcps_lease_time(void) // minute
return dhcps_lease_time; return dhcps_lease_time;
} }
void DhcpServer::dhcps_client_leave(u8 *bssid, struct ipv4_addr *ip, bool force) void DhcpServer::dhcps_client_leave(u8* bssid, struct ipv4_addr* ip, bool force)
{ {
struct dhcps_pool *pdhcps_pool = nullptr; struct dhcps_pool* pdhcps_pool = nullptr;
list_node *pback_node = nullptr; list_node* pback_node = nullptr;
if ((bssid == nullptr) || (ip == nullptr)) if ((bssid == nullptr) || (ip == nullptr))
{ {
@ -1412,12 +1400,12 @@ void DhcpServer::dhcps_client_leave(u8 *bssid, struct ipv4_addr *ip, bool force)
} }
} }
uint32 DhcpServer::dhcps_client_update(u8 *bssid, struct ipv4_addr *ip) uint32 DhcpServer::dhcps_client_update(u8* bssid, struct ipv4_addr* ip)
{ {
struct dhcps_pool *pdhcps_pool = nullptr; struct dhcps_pool* pdhcps_pool = nullptr;
list_node *pback_node = nullptr; list_node* pback_node = nullptr;
list_node *pmac_node = nullptr; list_node* pmac_node = nullptr;
list_node *pip_node = nullptr; list_node* pip_node = nullptr;
bool flag = false; bool flag = false;
uint32 start_ip = dhcps_lease.start_ip.addr; uint32 start_ip = dhcps_lease.start_ip.addr;
uint32 end_ip = dhcps_lease.end_ip.addr; uint32 end_ip = dhcps_lease.end_ip.addr;
@ -1447,7 +1435,7 @@ uint32 DhcpServer::dhcps_client_update(u8 *bssid, struct ipv4_addr *ip)
for (pback_node = plist; pback_node != nullptr; pback_node = pback_node->pnext) for (pback_node = plist; pback_node != nullptr; pback_node = pback_node->pnext)
{ {
pdhcps_pool = (struct dhcps_pool*)pback_node->pnode; pdhcps_pool = (struct dhcps_pool*)pback_node->pnode;
//os_printf("mac:"MACSTR"bssid:"MACSTR"\r\n",MAC2STR(pdhcps_pool->mac),MAC2STR(bssid)); // os_printf("mac:"MACSTR"bssid:"MACSTR"\r\n",MAC2STR(pdhcps_pool->mac),MAC2STR(bssid));
if (memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0) if (memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0)
{ {
pmac_node = pback_node; pmac_node = pback_node;
@ -1496,7 +1484,7 @@ uint32 DhcpServer::dhcps_client_update(u8 *bssid, struct ipv4_addr *ip)
{ {
return IPADDR_ANY; return IPADDR_ANY;
} }
//start_ip = htonl((ntohl(start_ip) + 1)); // start_ip = htonl((ntohl(start_ip) + 1));
flag = true; flag = true;
} }
} }
@ -1531,7 +1519,6 @@ uint32 DhcpServer::dhcps_client_update(u8 *bssid, struct ipv4_addr *ip)
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type; pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
} }
else else
{ {
@ -1572,7 +1559,7 @@ uint32 DhcpServer::dhcps_client_update(u8 *bssid, struct ipv4_addr *ip)
} }
else else
{ {
pdhcps_pool = (struct dhcps_pool *)zalloc(sizeof(struct dhcps_pool)); pdhcps_pool = (struct dhcps_pool*)zalloc(sizeof(struct dhcps_pool));
if (ip != nullptr) if (ip != nullptr)
{ {
pdhcps_pool->ip.addr = ip->addr; pdhcps_pool->ip.addr = ip->addr;
@ -1595,7 +1582,7 @@ uint32 DhcpServer::dhcps_client_update(u8 *bssid, struct ipv4_addr *ip)
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type; pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
pback_node = (list_node *)zalloc(sizeof(list_node)); pback_node = (list_node*)zalloc(sizeof(list_node));
pback_node->pnode = pdhcps_pool; pback_node->pnode = pdhcps_pool;
pback_node->pnext = nullptr; pback_node->pnext = nullptr;
node_insert_to_list(&plist, pback_node); node_insert_to_list(&plist, pback_node);

View File

@ -36,7 +36,6 @@
class DhcpServer class DhcpServer
{ {
public: public:
DhcpServer(netif* netif); DhcpServer(netif* netif);
~DhcpServer(); ~DhcpServer();
@ -54,55 +53,47 @@ public:
// legacy public C structure and API to eventually turn into C++ // legacy public C structure and API to eventually turn into C++
void init_dhcps_lease(uint32 ip); void init_dhcps_lease(uint32 ip);
bool set_dhcps_lease(struct dhcps_lease *please); bool set_dhcps_lease(struct dhcps_lease* please);
bool get_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_offer_option(uint8 level, void* optarg);
bool set_dhcps_lease_time(uint32 minute); bool set_dhcps_lease_time(uint32 minute);
bool reset_dhcps_lease_time(void); bool reset_dhcps_lease_time(void);
uint32 get_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); void dhcps_set_dns(int num, const ipv4_addr_t* dns);
protected: protected:
// legacy C structure and API to eventually turn into C++ // legacy C structure and API to eventually turn into C++
typedef struct _list_node typedef struct _list_node
{ {
void *pnode; void* pnode;
struct _list_node *pnext; struct _list_node* pnext;
} list_node; } list_node;
void node_insert_to_list(list_node **phead, list_node* pinsert); void node_insert_to_list(list_node** phead, list_node* pinsert);
void node_remove_from_list(list_node **phead, list_node* pdelete); 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_msg_type(uint8_t* optptr, uint8_t type);
uint8_t* add_offer_options(uint8_t *optptr); uint8_t* add_offer_options(uint8_t* optptr);
uint8_t* add_end(uint8_t *optptr); uint8_t* add_end(uint8_t* optptr);
void create_msg(struct dhcps_msg *m); void create_msg(struct dhcps_msg* m);
void send_offer(struct dhcps_msg *m); void send_offer(struct dhcps_msg* m);
void send_nak(struct dhcps_msg *m); void send_nak(struct dhcps_msg* m);
void send_ack(struct dhcps_msg *m); void send_ack(struct dhcps_msg* m);
uint8_t parse_options(uint8_t *optptr, sint16_t len); uint8_t parse_options(uint8_t* optptr, sint16_t len);
sint16_t parse_msg(struct dhcps_msg *m, u16_t len); sint16_t parse_msg(struct dhcps_msg* m, u16_t len);
static void S_handle_dhcp(void *arg, static void S_handle_dhcp(void* arg, struct udp_pcb* pcb, struct pbuf* p, const ip_addr_t* addr,
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); 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 kill_oldest_dhcps_pool(void);
void dhcps_coarse_tmr(void); // CURRENTLY NOT CALLED void dhcps_coarse_tmr(void); // CURRENTLY NOT CALLED
void dhcps_client_leave(u8 *bssid, struct ipv4_addr *ip, bool force); void dhcps_client_leave(u8* bssid, struct ipv4_addr* ip, bool force);
uint32 dhcps_client_update(u8 *bssid, struct ipv4_addr *ip); uint32 dhcps_client_update(u8* bssid, struct ipv4_addr* ip);
netif* _netif; netif* _netif;
struct udp_pcb *pcb_dhcps; struct udp_pcb* pcb_dhcps;
ip_addr_t broadcast_dhcps; ip_addr_t broadcast_dhcps;
struct ipv4_addr server_address; struct ipv4_addr server_address;
struct ipv4_addr client_address; struct ipv4_addr client_address;
@ -110,7 +101,7 @@ protected:
uint32 dhcps_lease_time; uint32 dhcps_lease_time;
struct dhcps_lease dhcps_lease; struct dhcps_lease dhcps_lease;
list_node *plist; list_node* plist;
uint8 offer; uint8 offer;
bool renew; bool renew;

View File

@ -1,5 +1,6 @@
extern "C" { extern "C"
{
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "lwip/dns.h" #include "lwip/dns.h"
@ -24,19 +25,23 @@ extern "C" {
// //
// result stored into gateway/netmask/dns1 // result stored into gateway/netmask/dns1
bool LwipIntf::ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, const IPAddress& arg3, bool LwipIntf::ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1,
IPAddress& gateway, IPAddress& netmask, IPAddress& dns1) 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; gateway = arg1;
netmask = arg2; netmask = arg2;
dns1 = arg3; dns1 = arg3;
if (netmask[0] != 255) if (netmask[0] != 255)
{ {
//octet is not 255 => interpret as Arduino order // octet is not 255 => interpret as Arduino order
gateway = arg2; 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; dns1 = arg1;
} }
@ -46,7 +51,7 @@ bool LwipIntf::ipAddressReorder(const IPAddress& local_ip, const IPAddress& arg1
return false; 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())) if (gateway.isSet() && (local_ip.v4() & netmask.v4()) != (gateway.v4() & netmask.v4()))
{ {
return false; return false;
@ -143,7 +148,6 @@ bool LwipIntf::hostname(const char* aHostname)
// harmless for AP, also compatible with ethernet adapters (to come) // harmless for AP, also compatible with ethernet adapters (to come)
for (netif* intf = netif_list; intf; intf = intf->next) for (netif* intf = netif_list; intf; intf = intf->next)
{ {
// unconditionally update all known interfaces // unconditionally update all known interfaces
intf->hostname = wifi_station_get_hostname(); intf->hostname = wifi_station_get_hostname();
@ -162,4 +166,3 @@ bool LwipIntf::hostname(const char* aHostname)
return ret && compliant; return ret && compliant;
} }

View File

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

View File

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

View File

@ -25,26 +25,21 @@
#define DEFAULT_MTU 1500 #define DEFAULT_MTU 1500
#endif #endif
template <class RawDev> template<class RawDev>
class LwipIntfDev: public LwipIntf, public RawDev class LwipIntfDev: public LwipIntf, public RawDev
{ {
public: public:
LwipIntfDev(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1) :
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)
RawDev(cs, spi, intr),
_mtu(DEFAULT_MTU),
_intrPin(intr),
_started(false),
_default(false)
{ {
memset(&_netif, 0, sizeof(_netif)); 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 // 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 const netif* getNetIf() const
{ {
@ -77,12 +72,11 @@ public:
wl_status_t status(); wl_status_t status();
protected: protected:
err_t netif_init(); err_t netif_init();
void netif_status_callback(); void netif_status_callback();
static err_t netif_init_s(netif* netif); 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); static void netif_status_callback_s(netif* netif);
// called on a regular basis or on interrupt // called on a regular basis or on interrupt
@ -97,11 +91,12 @@ protected:
uint8_t _macAddress[6]; uint8_t _macAddress[6];
bool _started; bool _started;
bool _default; bool _default;
}; };
template <class RawDev> template<class RawDev>
boolean LwipIntfDev<RawDev>::config(const IPAddress& localIP, const IPAddress& gateway, const IPAddress& netmask, const IPAddress& dns1, const IPAddress& dns2) boolean LwipIntfDev<RawDev>::config(const IPAddress& localIP, const IPAddress& gateway,
const IPAddress& netmask, const IPAddress& dns1,
const IPAddress& dns2)
{ {
if (_started) if (_started)
{ {
@ -132,7 +127,7 @@ boolean LwipIntfDev<RawDev>::config(const IPAddress& localIP, const IPAddress& g
return true; return true;
} }
template <class RawDev> template<class RawDev>
boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu) boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu)
{ {
if (mtu) if (mtu)
@ -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(netmask, _netif.netmask);
ip_addr_copy(gw, _netif.gw); 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; return false;
} }
@ -212,20 +208,24 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
{ {
if (RawDev::interruptIsPossible()) if (RawDev::interruptIsPossible())
{ {
//attachInterrupt(_intrPin, [&]() { this->handlePackets(); }, FALLING); // attachInterrupt(_intrPin, [&]() { this->handlePackets(); }, FALLING);
} }
else 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; _intrPin = -1;
} }
} }
if (_intrPin < 0 && !schedule_recurrent_function_us([&]() if (_intrPin < 0
{ && !schedule_recurrent_function_us(
[&]()
{
this->handlePackets(); this->handlePackets();
return true; return true;
}, 100)) },
100))
{ {
netif_remove(&_netif); netif_remove(&_netif);
return false; return false;
@ -234,14 +234,14 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
return true; return true;
} }
template <class RawDev> template<class RawDev>
wl_status_t LwipIntfDev<RawDev>::status() wl_status_t LwipIntfDev<RawDev>::status()
{ {
return _started ? (connected() ? WL_CONNECTED : WL_DISCONNECTED) : WL_NO_SHIELD; return _started ? (connected() ? WL_CONNECTED : WL_DISCONNECTED) : WL_NO_SHIELD;
} }
template <class RawDev> template<class RawDev>
err_t LwipIntfDev<RawDev>::linkoutput_s(netif *netif, struct pbuf *pbuf) err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf)
{ {
LwipIntfDev* ths = (LwipIntfDev*)netif->state; 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_HAS_CAPTURE
if (phy_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 #endif
return len == pbuf->len ? ERR_OK : ERR_MEM; return len == pbuf->len ? ERR_OK : ERR_MEM;
} }
template <class RawDev> template<class RawDev>
err_t LwipIntfDev<RawDev>::netif_init_s(struct netif* netif) err_t LwipIntfDev<RawDev>::netif_init_s(struct netif* netif)
{ {
return ((LwipIntfDev*)netif->state)->netif_init(); return ((LwipIntfDev*)netif->state)->netif_init();
} }
template <class RawDev> template<class RawDev>
void LwipIntfDev<RawDev>::netif_status_callback_s(struct netif* netif) void LwipIntfDev<RawDev>::netif_status_callback_s(struct netif* netif)
{ {
((LwipIntfDev*)netif->state)->netif_status_callback(); ((LwipIntfDev*)netif->state)->netif_status_callback();
} }
template <class RawDev> template<class RawDev>
err_t LwipIntfDev<RawDev>::netif_init() err_t LwipIntfDev<RawDev>::netif_init()
{ {
_netif.name[0] = 'e'; _netif.name[0] = 'e';
_netif.name[1] = '0' + _netif.num; _netif.name[1] = '0' + _netif.num;
_netif.mtu = _mtu; _netif.mtu = _mtu;
_netif.chksum_flags = NETIF_CHECKSUM_ENABLE_ALL; _netif.chksum_flags = NETIF_CHECKSUM_ENABLE_ALL;
_netif.flags = _netif.flags = NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP | NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP;
NETIF_FLAG_ETHARP
| NETIF_FLAG_IGMP
| NETIF_FLAG_BROADCAST
| NETIF_FLAG_LINK_UP;
// lwIP's doc: This function typically first resolves the hardware // lwIP's doc: This function typically first resolves the hardware
// address, then sends the packet. For ethernet physical layer, this is // address, then sends the packet. For ethernet physical layer, this is
@ -301,7 +298,7 @@ err_t LwipIntfDev<RawDev>::netif_init()
return ERR_OK; return ERR_OK;
} }
template <class RawDev> template<class RawDev>
void LwipIntfDev<RawDev>::netif_status_callback() void LwipIntfDev<RawDev>::netif_status_callback()
{ {
if (connected()) if (connected())
@ -321,7 +318,7 @@ void LwipIntfDev<RawDev>::netif_status_callback()
} }
} }
template <class RawDev> template<class RawDev>
err_t LwipIntfDev<RawDev>::handlePackets() err_t LwipIntfDev<RawDev>::handlePackets()
{ {
int pkt = 0; int pkt = 0;
@ -374,7 +371,8 @@ err_t LwipIntfDev<RawDev>::handlePackets()
#if PHY_HAS_CAPTURE #if PHY_HAS_CAPTURE
if (phy_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 #endif
@ -384,11 +382,10 @@ err_t LwipIntfDev<RawDev>::handlePackets()
return err; return err;
} }
// (else) allocated pbuf is now lwIP's responsibility // (else) allocated pbuf is now lwIP's responsibility
} }
} }
template <class RawDev> template<class RawDev>
void LwipIntfDev<RawDev>::setDefault() void LwipIntfDev<RawDev>::setDefault()
{ {
_default = true; _default = true;

View File

@ -19,13 +19,10 @@
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#include <Arduino.h> #include <Arduino.h>
#include <StreamDev.h> #include <StreamDev.h>
size_t Stream::sendGeneric(Print* to, size_t Stream::sendGeneric(Print* to, const ssize_t len, const int readUntilChar,
const ssize_t len,
const int readUntilChar,
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs) const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
{ {
setReport(Report::Success); setReport(Report::Success);
@ -57,11 +54,14 @@ size_t Stream::sendGeneric(Print* to,
return SendGenericRegular(to, len, timeoutMs); return SendGenericRegular(to, len, timeoutMs);
} }
size_t
size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int readUntilChar, const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs) 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 // "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 // len==-1 => maxLen=0 <=> until starvation
const size_t maxLen = std::max((ssize_t)0, len); const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0; size_t written = 0;
@ -145,13 +145,17 @@ size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int rea
return written; 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 // regular Stream API
// no other choice than reading byte by byte // no other choice than reading byte by byte
// "neverExpires (default, impossible)" is translated to default timeout // "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 // len==-1 => maxLen=0 <=> until starvation
const size_t maxLen = std::max((ssize_t)0, len); const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0; size_t written = 0;
@ -221,13 +225,16 @@ size_t Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int r
return written; 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 // regular Stream API
// use an intermediary buffer // use an intermediary buffer
// "neverExpires (default, impossible)" is translated to default timeout // "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 // len==-1 => maxLen=0 <=> until starvation
const size_t maxLen = std::max((ssize_t)0, len); const size_t maxLen = std::max((ssize_t)0, len);
size_t written = 0; size_t written = 0;
@ -305,19 +312,19 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p
return written; return written;
} }
Stream& operator << (Stream& out, String& string) Stream& operator<<(Stream& out, String& string)
{ {
StreamConstPtr(string).sendAll(out); StreamConstPtr(string).sendAll(out);
return out; return out;
} }
Stream& operator << (Stream& out, StreamString& stream) Stream& operator<<(Stream& out, StreamString& stream)
{ {
stream.sendAll(out); stream.sendAll(out);
return out; return out;
} }
Stream& operator << (Stream& out, Stream& stream) Stream& operator<<(Stream& out, Stream& stream)
{ {
if (stream.streamRemaining() < 0) if (stream.streamRemaining() < 0)
{ {
@ -339,13 +346,13 @@ Stream& operator << (Stream& out, Stream& stream)
return out; return out;
} }
Stream& operator << (Stream& out, const char* text) Stream& operator<<(Stream& out, const char* text)
{ {
StreamConstPtr(text, strlen_P(text)).sendAll(out); StreamConstPtr(text, strlen_P(text)).sendAll(out);
return out; return out;
} }
Stream& operator << (Stream& out, const __FlashStringHelper* text) Stream& operator<<(Stream& out, const __FlashStringHelper* text)
{ {
StreamConstPtr(text).sendAll(out); StreamConstPtr(text).sendAll(out);
return out; return out;

View File

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

View File

@ -24,9 +24,8 @@
#include "wiring_private.h" #include "wiring_private.h"
#include "PolledTimeout.h" #include "PolledTimeout.h"
extern "C"
{
extern "C" {
#include "twi_util.h" #include "twi_util.h"
#include "ets_sys.h" #include "ets_sys.h"
}; };
@ -57,8 +56,8 @@ static inline __attribute__((always_inline)) bool SCL_READ(const int twi_scl)
return (GPI & (1 << twi_scl)) != 0; return (GPI & (1 << twi_scl)) != 0;
} }
// Implement as a class to reduce code size by allowing access to many global variables with a
// Implement as a class to reduce code size by allowing access to many global variables with a single base pointer // single base pointer
class Twi class Twi
{ {
private: private:
@ -69,12 +68,37 @@ private:
unsigned char twi_addr = 0; unsigned char twi_addr = 0;
uint32_t twi_clockStretchLimit = 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 // These are int-wide, even though they could all fit in a byte, to reduce code size and avoid
// issues about RmW on packed bytes. The int-wide variations of asm instructions are smaller than the equivalent // any potential issues about RmW on packed bytes. The int-wide variations of asm instructions
// byte-wide ones, and since these emums are used everywhere, the difference adds up fast. There is only a single // are smaller than the equivalent byte-wide ones, and since these emums are used everywhere,
// instance of the class, though, so the extra 12 bytes of RAM used here saves a lot more IRAM. // the difference adds up fast. There is only a single instance of the class, though, so the
volatile enum { TWIPM_UNKNOWN = 0, TWIPM_IDLE, TWIPM_ADDRESSED, TWIPM_WAIT} twip_mode = TWIPM_IDLE; // extra 12 bytes of RAM used here saves a lot more IRAM.
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 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 twip_status = TW_NO_INFO;
volatile int bitCount = 0; volatile int bitCount = 0;
@ -97,16 +121,25 @@ private:
void (*twi_onSlaveReceive)(uint8_t*, size_t); void (*twi_onSlaveReceive)(uint8_t*, size_t);
// ETS queue/timer interfaces // ETS queue/timer interfaces
enum { EVENTTASK_QUEUE_SIZE = 1, EVENTTASK_QUEUE_PRIO = 2 }; enum
enum { TWI_SIG_RANGE = 0x00000100, TWI_SIG_RX = 0x00000101, TWI_SIG_TX = 0x00000102 }; {
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]; ETSEvent eventTaskQueue[EVENTTASK_QUEUE_SIZE];
ETSTimer timer; ETSTimer timer;
// Event/IRQ callbacks, so they can't use "this" and need to be static // Event/IRQ callbacks, so they can't use "this" and need to be static
static void IRAM_ATTR onSclChange(void); static void IRAM_ATTR onSclChange(void);
static void IRAM_ATTR onSdaChange(void); static void IRAM_ATTR onSdaChange(void);
static void eventTask(ETSEvent *e); static void eventTask(ETSEvent* e);
static void IRAM_ATTR onTimer(void *unused); static void IRAM_ATTR onTimer(void* unused);
// Allow not linking in the slave code if there is no call to setAddress // Allow not linking in the slave code if there is no call to setAddress
bool _slaveEnabled = false; bool _slaveEnabled = false;
@ -126,7 +159,8 @@ private:
{ {
esp8266::polledTimeout::oneShotFastUs timeout(twi_clockStretchLimit); esp8266::polledTimeout::oneShotFastUs timeout(twi_clockStretchLimit);
esp8266::polledTimeout::periodicFastUs yieldTimeout(5000); 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
{ {
@ -143,8 +177,10 @@ public:
void setClockStretchLimit(uint32_t limit); void setClockStretchLimit(uint32_t limit);
void init(unsigned char sda, unsigned char scl); void init(unsigned char sda, unsigned char scl);
void setAddress(uint8_t address); void setAddress(uint8_t address);
unsigned char writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop); unsigned char writeTo(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop); unsigned char sendStop);
unsigned char readFrom(unsigned char address, unsigned char* buf, unsigned int len,
unsigned char sendStop);
uint8_t status(); uint8_t status();
uint8_t transmit(const uint8_t* data, uint8_t length); uint8_t transmit(const uint8_t* data, uint8_t length);
void attachSlaveRxEvent(void (*function)(uint8_t*, size_t)); void attachSlaveRxEvent(void (*function)(uint8_t*, size_t));
@ -176,7 +212,8 @@ void Twi::setClock(unsigned int freq)
freq = 400000; freq = 400000;
} }
twi_dcount = (500000000 / freq); // half-cycle period in ns 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 #else
@ -185,7 +222,8 @@ void Twi::setClock(unsigned int freq)
freq = 800000; freq = 800000;
} }
twi_dcount = (500000000 / freq); // half-cycle period in ns 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 #endif
} }
@ -195,8 +233,6 @@ void Twi::setClockStretchLimit(uint32_t limit)
twi_clockStretchLimit = limit; twi_clockStretchLimit = limit;
} }
void Twi::init(unsigned char sda, unsigned char scl) void Twi::init(unsigned char sda, unsigned char scl)
{ {
// set timer function // set timer function
@ -234,7 +270,8 @@ void IRAM_ATTR Twi::busywait(unsigned int v)
unsigned int i; unsigned int i;
for (i = 0; i < v; i++) // loop time is 5 machine cycles: 31.25ns @ 160MHz, 62.5ns @ 80MHz 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. // A high-to-low transition on the SDA line while the SCL is high defines a START condition.
SDA_LOW(twi_sda); SDA_LOW(twi_sda);
busywait(twi_dcount); 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); SCL_LOW(twi_scl);
busywait(twi_dcount); busywait(twi_dcount);
return true; return true;
@ -308,7 +346,7 @@ bool Twi::write_byte(unsigned char byte)
write_bit(byte & 0x80); write_bit(byte & 0x80);
byte <<= 1; byte <<= 1;
} }
return !read_bit();//NACK/ACK return !read_bit(); // NACK/ACK
} }
unsigned char Twi::read_byte(bool nack) unsigned char Twi::read_byte(bool nack)
@ -323,12 +361,13 @@ unsigned char Twi::read_byte(bool nack)
return byte; 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; unsigned int i;
if (!write_start()) if (!write_start())
{ {
return 4; //line busy return 4; // line busy
} }
if (!write_byte(((address << 1) | 0) & 0xFF)) if (!write_byte(((address << 1) | 0) & 0xFF))
{ {
@ -336,7 +375,7 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
{ {
write_stop(); write_stop();
} }
return 2; //received NACK on transmit of address return 2; // received NACK on transmit of address
} }
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
@ -346,7 +385,7 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
{ {
write_stop(); write_stop();
} }
return 3;//received NACK on transmit of data return 3; // received NACK on transmit of data
} }
} }
if (sendStop) if (sendStop)
@ -368,12 +407,13 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
return 0; 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; unsigned int i;
if (!write_start()) if (!write_start())
{ {
return 4; //line busy return 4; // line busy
} }
if (!write_byte(((address << 1) | 1) & 0xFF)) if (!write_byte(((address << 1) | 1) & 0xFF))
{ {
@ -381,7 +421,7 @@ unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned
{ {
write_stop(); 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++) 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 WAIT_CLOCK_STRETCH(); // wait for a slow slave to finish
if (!SCL_READ(twi_scl)) 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; 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(); read_bit();
if (!SCL_READ(twi_scl)) 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)) 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; return I2C_OK;
@ -476,31 +520,31 @@ void Twi::attachSlaveTxEvent(void (*function)(void))
twi_onSlaveTransmit = function; twi_onSlaveTransmit = function;
} }
// DO NOT INLINE, inlining reply() in combination with compiler optimizations causes function breakup into // DO NOT INLINE, inlining reply() in combination with compiler optimizations causes function
// parts and the IRAM_ATTR isn't propagated correctly to all parts, which of course causes crashes. // 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 // 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) void IRAM_ATTR Twi::reply(uint8_t ack)
{ {
// transmit master read ready signal, with or without ack // transmit master read ready signal, with or without ack
if (ack) if (ack)
{ {
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); // TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
SCL_HIGH(twi.twi_scl); // _BV(TWINT) SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA) twi_ack = 1; // _BV(TWEA)
} }
else else
{ {
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); // TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
SCL_HIGH(twi.twi_scl); // _BV(TWINT) SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 0; // ~_BV(TWEA) twi_ack = 0; // ~_BV(TWEA)
} }
} }
void IRAM_ATTR Twi::releaseBus(void) void IRAM_ATTR Twi::releaseBus(void)
{ {
// release bus // release bus
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); // TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
SCL_HIGH(twi.twi_scl); // _BV(TWINT) SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA) twi_ack = 1; // _BV(TWEA)
SDA_HIGH(twi.twi_sda); SDA_HIGH(twi.twi_sda);
@ -509,7 +553,6 @@ void IRAM_ATTR Twi::releaseBus(void)
twi_state = TWI_READY; twi_state = TWI_READY;
} }
void IRAM_ATTR Twi::onTwipEvent(uint8_t status) void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
{ {
twip_status = status; twip_status = status;
@ -548,7 +591,7 @@ void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
twi_rxBuffer[twi_rxBufferIndex] = '\0'; twi_rxBuffer[twi_rxBufferIndex] = '\0';
} }
// callback to user-defined callback over event task to allow for non-RAM-residing code // 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); ets_post(EVENTTASK_QUEUE_PRIO, TWI_SIG_RX, twi_rxBufferIndex);
// since we submit rx buffer to "wire" library, we can reset it // since we submit rx buffer to "wire" library, we can reset it
@ -617,7 +660,7 @@ void IRAM_ATTR Twi::onTwipEvent(uint8_t status)
} }
} }
void IRAM_ATTR Twi::onTimer(void *unused) void IRAM_ATTR Twi::onTimer(void* unused)
{ {
(void)unused; (void)unused;
twi.releaseBus(); twi.releaseBus();
@ -626,9 +669,8 @@ void IRAM_ATTR Twi::onTimer(void *unused)
twi.twip_state = TWIP_BUS_ERR; twi.twip_state = TWIP_BUS_ERR;
} }
void Twi::eventTask(ETSEvent *e) void Twi::eventTask(ETSEvent* e)
{ {
if (e == NULL) if (e == NULL)
{ {
return; return;
@ -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 // 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 // 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. // 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 // Shorthand for if the state is any of the or'd bitmask x
#define IFSTATE(x) if (twip_state_mask & (x)) #define IFSTATE(x) if (twip_state_mask & (x))
@ -891,7 +933,9 @@ void IRAM_ATTR Twi::onSdaChange(void)
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 // START or STOP
SDA_HIGH(twi.twi_sda); // Should not be necessary SDA_HIGH(twi.twi_sda); // Should not be necessary
@ -961,8 +1005,8 @@ void IRAM_ATTR Twi::onSdaChange(void)
} }
// C wrappers for the object, since API is exposed only as C // 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) void twi_init(unsigned char sda, unsigned char scl)
{ {
return twi.init(sda, scl); return twi.init(sda, scl);
@ -983,12 +1027,14 @@ extern "C" {
twi.setClockStretchLimit(limit); 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); 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); return twi.readFrom(address, buf, len, sendStop);
} }
@ -998,7 +1044,7 @@ extern "C" {
return twi.status(); 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); return twi.transmit(buf, len);
} }
@ -1027,5 +1073,4 @@ extern "C" {
{ {
twi.enableSlave(); twi.enableSlave();
} }
}; };

View File

@ -30,7 +30,7 @@ void __iamslow(const char* what)
#endif #endif
IRAM_ATTR 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; const char* src = (const char*)mem;
os_printf("\n[HEXDUMP] Address: %p len: 0x%X (%d)", src, len, len); os_printf("\n[HEXDUMP] Address: %p len: 0x%X (%d)", src, len, len);

View File

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

View File

@ -14,7 +14,7 @@ const char* host = "OTA-LEDS";
int led_pin = 13; int led_pin = 13;
#define N_DIMMERS 3 #define N_DIMMERS 3
int dimmer_pin[] = {14, 5, 15}; int dimmer_pin[] = { 14, 5, 15 };
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
@ -67,7 +67,6 @@ void setup() {
/* setup the OTA server */ /* setup the OTA server */
ArduinoOTA.begin(); ArduinoOTA.begin();
Serial.println("Ready"); Serial.println("Ready");
} }
void loop() { void loop() {

View File

@ -74,8 +74,8 @@ void setup() {
server.on("/", handleRoot); server.on("/", handleRoot);
server.on("/wifi", handleWifi); server.on("/wifi", handleWifi);
server.on("/wifisave", handleWifiSave); server.on("/wifisave", handleWifiSave);
server.on("/generate_204", handleRoot); //Android 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.on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
server.onNotFound(handleNotFound); server.onNotFound(handleNotFound);
server.begin(); // Web server start server.begin(); // Web server start
Serial.println("HTTP server started"); Serial.println("HTTP server started");
@ -130,13 +130,11 @@ void loop() {
WiFi.disconnect(); WiFi.disconnect();
} }
} }
if (s == WL_CONNECTED) { if (s == WL_CONNECTED) { MDNS.update(); }
MDNS.update();
}
} }
// Do work: // Do work:
//DNS // DNS
dnsServer.processNextRequest(); dnsServer.processNextRequest();
//HTTP // HTTP
server.handleClient(); server.handleClient();
} }

View File

@ -8,8 +8,7 @@ void handleRoot() {
server.sendHeader("Expires", "-1"); server.sendHeader("Expires", "-1");
String Page; String Page;
Page += F( Page += F("<!DOCTYPE html><html lang='en'><head>"
"<!DOCTYPE html><html lang='en'><head>"
"<meta name='viewport' content='width=device-width'>" "<meta name='viewport' content='width=device-width'>"
"<title>CaptivePortal</title></head><body>" "<title>CaptivePortal</title></head><body>"
"<h1>HELLO WORLD!!</h1>"); "<h1>HELLO WORLD!!</h1>");
@ -18,8 +17,7 @@ void handleRoot() {
} else { } else {
Page += String(F("<p>You are connected through the wifi network: ")) + ssid + F("</p>"); Page += String(F("<p>You are connected through the wifi network: ")) + ssid + F("</p>");
} }
Page += F( Page += F("<p>You may want to <a href='/wifi'>config the wifi connection</a>.</p>"
"<p>You may want to <a href='/wifi'>config the wifi connection</a>.</p>"
"</body></html>"); "</body></html>");
server.send(200, "text/html", Page); server.send(200, "text/html", Page);
@ -44,8 +42,7 @@ void handleWifi() {
server.sendHeader("Expires", "-1"); server.sendHeader("Expires", "-1");
String Page; String Page;
Page += F( Page += F("<!DOCTYPE html><html lang='en'><head>"
"<!DOCTYPE html><html lang='en'><head>"
"<meta name='viewport' content='width=device-width'>" "<meta name='viewport' content='width=device-width'>"
"<title>CaptivePortal</title></head><body>" "<title>CaptivePortal</title></head><body>"
"<h1>Wifi config</h1>"); "<h1>Wifi config</h1>");
@ -54,25 +51,19 @@ void handleWifi() {
} else { } else {
Page += String(F("<p>You are connected through the wifi network: ")) + ssid + F("</p>"); Page += String(F("<p>You are connected through the wifi network: ")) + ssid + F("</p>");
} }
Page += Page += String(F("\r\n<br />"
String(F(
"\r\n<br />"
"<table><tr><th align='left'>SoftAP config</th></tr>" "<table><tr><th align='left'>SoftAP config</th></tr>"
"<tr><td>SSID ")) + "<tr><td>SSID "))
String(softAP_ssid) + + String(softAP_ssid) + F("</td></tr>"
F("</td></tr>" "<tr><td>IP ")
"<tr><td>IP ") + + toStringIp(WiFi.softAPIP()) + F("</td></tr>"
toStringIp(WiFi.softAPIP()) +
F("</td></tr>"
"</table>" "</table>"
"\r\n<br />" "\r\n<br />"
"<table><tr><th align='left'>WLAN config</th></tr>" "<table><tr><th align='left'>WLAN config</th></tr>"
"<tr><td>SSID ") + "<tr><td>SSID ")
String(ssid) + + String(ssid) + F("</td></tr>"
F("</td></tr>" "<tr><td>IP ")
"<tr><td>IP ") + + toStringIp(WiFi.localIP()) + F("</td></tr>"
toStringIp(WiFi.localIP()) +
F("</td></tr>"
"</table>" "</table>"
"\r\n<br />" "\r\n<br />"
"<table><tr><th align='left'>WLAN list (refresh if any missing)</th></tr>"); "<table><tr><th align='left'>WLAN list (refresh if any missing)</th></tr>");
@ -80,14 +71,11 @@ void handleWifi() {
int n = WiFi.scanNetworks(); int n = WiFi.scanNetworks();
Serial.println("scan done"); Serial.println("scan done");
if (n > 0) { if (n > 0) {
for (int i = 0; i < n; i++) { 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>"); }
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 { } else {
Page += F("<tr><td>No WLAN found</td></tr>"); Page += F("<tr><td>No WLAN found</td></tr>");
} }
Page += F( Page += F("</table>"
"</table>"
"\r\n<br /><form method='POST' action='wifisave'><h4>Connect to network:</h4>" "\r\n<br /><form method='POST' action='wifisave'><h4>Connect to network:</h4>"
"<input type='text' placeholder='network' name='n'/>" "<input type='text' placeholder='network' name='n'/>"
"<br /><input type='password' placeholder='password' name='p'/>" "<br /><input type='password' placeholder='password' name='p'/>"
@ -126,9 +114,7 @@ void handleNotFound() {
message += server.args(); message += server.args();
message += F("\n"); message += F("\n");
for (uint8_t i = 0; i < server.args(); i++) { for (uint8_t i = 0; i < server.args(); i++) { message += String(F(" ")) + server.argName(i) + F(": ") + server.arg(i) + F("\n"); }
message += String(F(" ")) + server.argName(i) + F(": ") + server.arg(i) + F("\n");
}
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache"); server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1"); server.sendHeader("Expires", "-1");

View File

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

View File

@ -11,9 +11,7 @@
void setup() { void setup() {
EEPROM.begin(512); EEPROM.begin(512);
// write a 0 to all 512 bytes of the EEPROM // write a 0 to all 512 bytes of the EEPROM
for (int i = 0; i < 512; i++) { for (int i = 0; i < 512; i++) { EEPROM.write(i, 0); }
EEPROM.write(i, 0);
}
// turn the LED on when we're done // turn the LED on when we're done
pinMode(13, OUTPUT); pinMode(13, OUTPUT);
@ -21,5 +19,4 @@ void setup() {
EEPROM.end(); 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 // there are only 512 bytes of EEPROM, from 0 to 511, so if we're
// on address 512, wrap around to address 0 // on address 512, wrap around to address 0
if (address == 512) { if (address == 512) { address = 0; }
address = 0;
}
delay(500); delay(500);
} }

View File

@ -51,17 +51,20 @@ void loop() {
AVRISPState_t new_state = avrprog.update(); AVRISPState_t new_state = avrprog.update();
if (last_state != new_state) { if (last_state != new_state) {
switch (new_state) { switch (new_state) {
case AVRISP_STATE_IDLE: { case AVRISP_STATE_IDLE:
{
Serial.printf("[AVRISP] now idle\r\n"); Serial.printf("[AVRISP] now idle\r\n");
// Use the SPI bus for other purposes // Use the SPI bus for other purposes
break; break;
} }
case AVRISP_STATE_PENDING: { case AVRISP_STATE_PENDING:
{
Serial.printf("[AVRISP] connection pending\r\n"); Serial.printf("[AVRISP] connection pending\r\n");
// Clean up your other purposes and prepare for programming mode // Clean up your other purposes and prepare for programming mode
break; break;
} }
case AVRISP_STATE_ACTIVE: { case AVRISP_STATE_ACTIVE:
{
Serial.printf("[AVRISP] programming mode\r\n"); Serial.printf("[AVRISP] programming mode\r\n");
// Stand by for completion // Stand by for completion
break; break;
@ -70,11 +73,7 @@ void loop() {
last_state = new_state; last_state = new_state;
} }
// Serve the client // Serve the client
if (last_state != AVRISP_STATE_IDLE) { if (last_state != AVRISP_STATE_IDLE) { avrprog.serve(); }
avrprog.serve();
}
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) { MDNS.update(); }
MDNS.update();
}
} }

View File

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

View File

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

View File

@ -14,7 +14,7 @@
#include <WiFiClientSecureBearSSL.h> #include <WiFiClientSecureBearSSL.h>
// Fingerprint for demo URL, expires on June 2, 2021, needs to be updated well before this date // 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; ESP8266WiFiMulti WiFiMulti;
@ -41,7 +41,7 @@ void loop() {
// wait for WiFi connection // wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED)) { 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); client->setFingerprint(fingerprint);
// Or, if you happy to ignore the SSL certificate, then use the following line instead: // Or, if you happy to ignore the SSL certificate, then use the following line instead:

View File

@ -19,30 +19,25 @@
const char* ssid = STASSID; const char* ssid = STASSID;
const char* ssidPassword = STAPSK; const char* ssidPassword = STAPSK;
const char *username = "admin"; const char* username = "admin";
const char *password = "admin"; const char* password = "admin";
const char *server = "http://httpbin.org"; const char* server = "http://httpbin.org";
const char *uri = "/digest-auth/auth/admin/admin/MD5"; const char* uri = "/digest-auth/auth/admin/admin/MD5";
String exractParam(String& authReq, const String& param, const char delimit) { String exractParam(String& authReq, const String& param, const char delimit) {
int _begin = authReq.indexOf(param); int _begin = authReq.indexOf(param);
if (_begin == -1) { if (_begin == -1) { return ""; }
return "";
}
return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length())); return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length()));
} }
String getCNonce(const int len) { String getCNonce(const int len) {
static const char alphanum[] = static const char alphanum[] = "0123456789"
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; "abcdefghijklmnopqrstuvwxyz";
String s = ""; String s = "";
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) { s += alphanum[rand() % (sizeof(alphanum) - 1)]; }
s += alphanum[rand() % (sizeof(alphanum) - 1)];
}
return s; return s;
} }
@ -73,8 +68,7 @@ String getDigestAuth(String& authReq, const String& username, const String& pass
md5.calculate(); md5.calculate();
String response = md5.toString(); String response = md5.toString();
String authorization = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + String authorization = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + uri + "\", algorithm=\"MD5\", qop=auth, nc=" + String(nc) + ", cnonce=\"" + cNonce + "\", response=\"" + response + "\"";
"\", uri=\"" + uri + "\", algorithm=\"MD5\", qop=auth, nc=" + String(nc) + ", cnonce=\"" + cNonce + "\", response=\"" + response + "\"";
Serial.println(authorization); Serial.println(authorization);
return authorization; return authorization;
@ -100,7 +94,7 @@ void setup() {
void loop() { void loop() {
WiFiClient client; 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"); Serial.print("[HTTP] begin...\n");
@ -108,7 +102,7 @@ void loop() {
http.begin(client, String(server) + String(uri)); http.begin(client, String(server) + String(uri));
const char *keys[] = {"WWW-Authenticate"}; const char* keys[] = { "WWW-Authenticate" };
http.collectHeaders(keys, 1); http.collectHeaders(keys, 1);
Serial.print("[HTTP] GET...\n"); Serial.print("[HTTP] GET...\n");

View File

@ -40,7 +40,6 @@ void setup() {
Serial.println(""); Serial.println("");
Serial.print("Connected! IP address: "); Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
} }
void loop() { void loop() {
@ -52,7 +51,7 @@ void loop() {
Serial.print("[HTTP] begin...\n"); Serial.print("[HTTP] begin...\n");
// configure traged server and url // 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"); http.addHeader("Content-Type", "application/json");
Serial.print("[HTTP] POST...\n"); Serial.print("[HTTP] POST...\n");

View File

@ -45,7 +45,7 @@ void setup() {
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html"); 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; int pass = 0;
@ -60,15 +60,13 @@ void loop() {
Serial.printf("[HTTP] GET... code: %d\n", httpCode); Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server // file found at server
if (httpCode == HTTP_CODE_OK) { if (httpCode == HTTP_CODE_OK) { http.writeToStream(&Serial); }
http.writeToStream(&Serial);
}
} else { } else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
// Something went wrong with the connection, try to reconnect // Something went wrong with the connection, try to reconnect
http.end(); http.end();
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html"); 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) { if (pass == 10) {

View File

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

View File

@ -31,7 +31,6 @@ void setup() {
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
WiFiMulti.addAP("SSID", "PASSWORD"); WiFiMulti.addAP("SSID", "PASSWORD");
} }
void loop() { void loop() {
@ -43,14 +42,12 @@ void loop() {
bool mfln = client->probeMaxFragmentLength("tls.mbed.org", 443, 1024); bool mfln = client->probeMaxFragmentLength("tls.mbed.org", 443, 1024);
Serial.printf("\nConnecting to https://tls.mbed.org\n"); Serial.printf("\nConnecting to https://tls.mbed.org\n");
Serial.printf("Maximum fragment Length negotiation supported: %s\n", mfln ? "yes" : "no"); Serial.printf("Maximum fragment Length negotiation supported: %s\n", mfln ? "yes" : "no");
if (mfln) { if (mfln) { client->setBufferSizes(1024, 1024); }
client->setBufferSizes(1024, 1024);
}
Serial.print("[HTTPS] begin...\n"); Serial.print("[HTTPS] begin...\n");
// configure server and url // 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); client->setFingerprint(fingerprint);
@ -86,16 +83,13 @@ void loop() {
// write it to Serial // write it to Serial
Serial.write(buff, c); Serial.write(buff, c);
if (len > 0) { if (len > 0) { len -= c; }
len -= c;
}
} }
delay(1); delay(1);
} }
Serial.println(); Serial.println();
Serial.print("[HTTPS] connection closed or file end.\n"); Serial.print("[HTTPS] connection closed or file end.\n");
} }
} else { } else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str()); Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());

View File

@ -88,8 +88,7 @@ gz5JWYhbD6c38khSzJb0pNXCo3EuYAVa36kDM96k1BtWuhRS10Q1VXk=
)EOF"; )EOF";
void setup() void setup() {
{
Serial.begin(115200); Serial.begin(115200);
Serial.println(); Serial.println();
@ -97,7 +96,7 @@ void setup()
WiFi.mode(WIFI_AP_STA); WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password); WiFi.begin(ssid, password);
while(WiFi.waitForConnectResult() != WL_CONNECTED){ while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password); WiFi.begin(ssid, password);
Serial.println("WiFi failed, retrying."); Serial.println("WiFi failed, retrying.");
} }
@ -111,13 +110,13 @@ void setup()
httpServer.begin(); httpServer.begin();
MDNS.addService("https", "tcp", 443); MDNS.addService("https", "tcp", 443);
Serial.printf("BearSSLUpdateServer ready!\nOpen https://%s.local%s in "\ Serial.printf("BearSSLUpdateServer ready!\nOpen https://%s.local%s in "
"your browser and login with username '%s' and password "\ "your browser and login with username '%s' and password "
"'%s'\n", host, update_path, update_username, update_password); "'%s'\n",
host, update_path, update_username, update_password);
} }
void loop() void loop() {
{
httpServer.handleClient(); httpServer.handleClient();
MDNS.update(); MDNS.update();
} }

View File

View File

@ -46,9 +46,7 @@ void setup() {
Serial.printf("Ready!\n"); Serial.printf("Ready!\n");
} else { } else {
Serial.printf("WiFi Failed\n"); Serial.printf("WiFi Failed\n");
while (1) { while (1) { delay(100); }
delay(100);
}
} }
} }

View File

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

View File

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

View File

@ -110,9 +110,7 @@ void replyServerError(String msg) {
bool handleFileRead(String path) { bool handleFileRead(String path) {
DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path); DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path);
if (path.endsWith("/")) { if (path.endsWith("/")) { path += "index.htm"; }
path += "index.htm";
}
String contentType = mime::getContentType(path); String contentType = mime::getContentType(path);
@ -122,9 +120,7 @@ bool handleFileRead(String path) {
} }
if (fileSystem->exists(path)) { if (fileSystem->exists(path)) {
File file = fileSystem->open(path, "r"); File file = fileSystem->open(path, "r");
if (server.streamFile(file, contentType) != file.size()) { if (server.streamFile(file, contentType) != file.size()) { DBG_OUTPUT_PORT.println("Sent less data than expected!"); }
DBG_OUTPUT_PORT.println("Sent less data than expected!");
}
file.close(); file.close();
return true; return true;
} }
@ -141,9 +137,7 @@ bool handleFileRead(String path) {
void handleNotFound() { 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)) { if (handleFileRead(uri)) { return; }
return;
}
// Dump debug data // Dump debug data
String message; String message;
@ -218,7 +212,7 @@ void setup(void) {
//////////////////////////////// ////////////////////////////////
// WEB SERVER INIT // 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, []() { server.on("/espData", HTTP_GET, []() {
String json; String json;
json.reserve(88); json.reserve(88);
@ -249,16 +243,13 @@ void setup(void) {
DBG_OUTPUT_PORT.println(" 0 (OFF): outputs are off and hidden from chart"); 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(" 1 (AUTO): outputs are rotated automatically every second");
DBG_OUTPUT_PORT.println(" 2 (MANUAL): outputs can be toggled from the web page"); 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 // Return default GPIO mask, that is all I/Os except SD card ones
unsigned int defaultMask() { unsigned int defaultMask() {
unsigned int mask = 0b11111111111111111; unsigned int mask = 0b11111111111111111;
for (auto pin = 0; pin <= 16; pin++) { for (auto pin = 0; pin <= 16; pin++) {
if (isFlashInterfacePin(pin)) { if (isFlashInterfacePin(pin)) { mask &= ~(1 << pin); }
mask &= ~(1 << pin);
}
} }
return mask; return mask;
} }
@ -278,17 +269,13 @@ void loop(void) {
} }
// see if one second has passed since last change, otherwise stop here // see if one second has passed since last change, otherwise stop here
if (!timeToChange) { if (!timeToChange) { return; }
return;
}
// see if a mode change was requested // see if a mode change was requested
if (modeChangeRequested) { if (modeChangeRequested) {
// increment mode (reset after 2) // increment mode (reset after 2)
rgbMode++; rgbMode++;
if (rgbMode > 2) { if (rgbMode > 2) { rgbMode = 0; }
rgbMode = 0;
}
modeChangeRequested = false; modeChangeRequested = false;
} }
@ -312,9 +299,7 @@ void loop(void) {
// increment value (reset after 7) // increment value (reset after 7)
rgbValue++; rgbValue++;
if (rgbValue > 7) { if (rgbValue > 7) { rgbValue = 0; }
rgbValue = 0;
}
// output new values // output new values
digitalWrite(12, rgbValue & 0b001); digitalWrite(12, rgbValue & 0b001);
@ -329,4 +314,3 @@ void loop(void) {
break; break;
} }
} }

View File

@ -31,9 +31,7 @@ void handleNotFound() {
message += "\nArguments: "; message += "\nArguments: ";
message += server.args(); message += server.args();
message += "\n"; message += "\n";
for (uint8_t i = 0; i < server.args(); i++) { for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message); server.send(404, "text/plain", message);
digitalWrite(led, 0); digitalWrite(led, 0);
} }
@ -57,9 +55,7 @@ void setup(void) {
Serial.print("IP address: "); Serial.print("IP address: ");
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) { if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
Serial.println("MDNS responder started");
}
server.on("/", handleRoot); server.on("/", handleRoot);
@ -89,7 +85,7 @@ void setup(void) {
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// Hook examples // Hook examples
server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { server.addHook([](const String& method, const String& url, WiFiClient* client, ESP8266WebServer::ContentTypeFunction contentType) {
(void)method; // GET, PUT, ... (void)method; // GET, PUT, ...
(void)url; // example: /root/myfile.html (void)url; // example: /root/myfile.html
(void)client; // the webserver tcp client connection (void)client; // the webserver tcp client connection
@ -99,7 +95,7 @@ void setup(void) {
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; 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")) { if (url.startsWith("/fail")) {
Serial.printf("An always failing web hook has been triggered\n"); Serial.printf("An always failing web hook has been triggered\n");
return ESP8266WebServer::CLIENT_MUST_STOP; return ESP8266WebServer::CLIENT_MUST_STOP;
@ -107,7 +103,7 @@ void setup(void) {
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; 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")) { if (url.startsWith("/dump")) {
Serial.printf("The dumper web hook is on the run\n"); Serial.printf("The dumper web hook is on the run\n");

View File

@ -89,24 +89,22 @@ void handleRoot() {
digitalWrite(led, 0); digitalWrite(led, 0);
} }
void handleNotFound(){ void handleNotFound() {
digitalWrite(led, 1); digitalWrite(led, 1);
String message = "File Not Found\n\n"; String message = "File Not Found\n\n";
message += "URI: "; message += "URI: ";
message += server.uri(); message += server.uri();
message += "\nMethod: "; message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST"; message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: "; message += "\nArguments: ";
message += server.args(); message += server.args();
message += "\n"; message += "\n";
for (uint8_t i=0; i<server.args(); i++){ for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message); server.send(404, "text/plain", message);
digitalWrite(led, 0); digitalWrite(led, 0);
} }
void setup(void){ void setup(void) {
pinMode(led, OUTPUT); pinMode(led, OUTPUT);
digitalWrite(led, 0); digitalWrite(led, 0);
Serial.begin(115200); Serial.begin(115200);
@ -127,9 +125,7 @@ void setup(void){
Serial.print("IP address: "); Serial.print("IP address: ");
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) { if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
Serial.println("MDNS responder started");
}
server.getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey)); server.getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));
@ -138,7 +134,7 @@ void setup(void){
server.on("/", handleRoot); server.on("/", handleRoot);
server.on("/inline", [](){ server.on("/inline", []() {
server.send(200, "text/plain", "this works as well"); 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) { void processKey(Print& out, int hotKey) {
switch (hotKey) { switch (hotKey) {
case 'd': { case 'd':
{
HeapSelectDram ephemeral; HeapSelectDram ephemeral;
umm_info(NULL, true); umm_info(NULL, true);
break; break;
} }
case 'i': { case 'i':
{
HeapSelectIram ephemeral; HeapSelectIram ephemeral;
umm_info(NULL, true); umm_info(NULL, true);
break; break;
} }
case 'h': { case 'h':
{
{ {
HeapSelectIram ephemeral; HeapSelectIram ephemeral;
Serial.printf(PSTR("IRAM ESP.getFreeHeap: %u\n"), ESP.getFreeHeap()); 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")); out.printf_P(PSTR("Restart, ESP.restart(); ...\r\n"));
ESP.restart(); ESP.restart();
break; break;
case '\r': case '\r': out.println();
out.println(); case '\n': break;
case '\n':
break;
case '?': case '?':
out.println(); out.println();
out.println(F("Press a key + <enter>")); 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(); server.handleClient();
MDNS.update(); MDNS.update();
if (Serial.available() > 0) { if (Serial.available() > 0) {

View File

@ -39,13 +39,13 @@ void setup() {
server.on("/", []() { server.on("/", []() {
if (!server.authenticate(www_username, www_password)) if (!server.authenticate(www_username, www_password))
//Basic 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); // return server.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
//Digest Auth Method with realm="Login Required" and empty Failure Response // Digest Auth Method with realm="Login Required" and empty Failure Response
//return server.requestAuthentication(DIGEST_AUTH); // return server.requestAuthentication(DIGEST_AUTH);
//Digest Auth Method with Custom realm and empty Failure Response // Digest Auth Method with Custom realm and empty Failure Response
//return server.requestAuthentication(DIGEST_AUTH, www_realm); // return server.requestAuthentication(DIGEST_AUTH, www_realm);
//Digest Auth Method with Custom realm and Failure Response // Digest Auth Method with Custom realm and Failure Response
{ {
return server.requestAuthentication(DIGEST_AUTH, www_realm, authFailResponse); return server.requestAuthentication(DIGEST_AUTH, www_realm, authFailResponse);
} }

View File

@ -15,7 +15,7 @@
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266WebServerSecure.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 #ifndef STASSID
#define STASSID "your-ssid" #define STASSID "your-ssid"
#define STAPSK "your-password" #define STAPSK "your-password"
@ -27,9 +27,9 @@ const char* wifi_pw = STAPSK;
const String file_credentials = R"(/credentials.txt)"; // LittleFS file name for the saved credentials 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 change_creds = "changecreds"; // Address for a credential change
//The ESP8266WebServerSecure requires an encryption certificate and matching key. // The ESP8266WebServerSecure requires an encryption certificate and matching key.
//These can generated with the bash script available in the ESP8266 Arduino repository. // 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. // 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( static const char serverCert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIDSzCCAjMCCQD2ahcfZAwXxDANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMC MIIDSzCCAjMCCQD2ahcfZAwXxDANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMC
@ -84,7 +84,7 @@ gz5JWYhbD6c38khSzJb0pNXCo3EuYAVa36kDM96k1BtWuhRS10Q1VXk=
ESP8266WebServerSecure server(443); 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"; String login = "admin";
const String realm = "global"; const String realm = "global";
String H1 = ""; String H1 = "";
@ -93,16 +93,16 @@ String authentication_failed = "User authentication has failed.";
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
//Initialize LittleFS to save credentials // Initialize LittleFS to save credentials
if(!LittleFS.begin()){ if (!LittleFS.begin()) {
Serial.println("LittleFS initialization error, programmer flash configured?"); Serial.println("LittleFS initialization error, programmer flash configured?");
ESP.restart(); 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(); loadcredentials();
//Initialize wifi // Initialize wifi
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
WiFi.begin(ssid, wifi_pw); WiFi.begin(ssid, wifi_pw);
if (WiFi.waitForConnectResult() != WL_CONNECTED) { if (WiFi.waitForConnectResult() != WL_CONNECTED) {
@ -112,8 +112,8 @@ void setup() {
} }
server.getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey)); 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("/", 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("/" + change_creds, handlecredentialchange); // handles submission of credentials from the client
server.onNotFound(redirect); server.onNotFound(redirect);
server.begin(); server.begin();
@ -127,49 +127,48 @@ void loop() {
server.handleClient(); server.handleClient();
} }
//This function redirects home // This function redirects home
void redirect(){ void redirect() {
String url = "https://" + WiFi.localIP().toString(); String url = "https://" + WiFi.localIP().toString();
Serial.println("Redirect called. Redirecting to " + url); Serial.println("Redirect called. Redirecting to " + url);
server.sendHeader("Location", url, true); server.sendHeader("Location", url, true);
Serial.println("Header sent."); 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."); 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."); 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() { bool session_authenticated() {
Serial.println("Checking authentication."); Serial.println("Checking authentication.");
if (server.authenticateDigest(login,H1)) { if (server.authenticateDigest(login, H1)) {
Serial.println("Authentication confirmed."); Serial.println("Authentication confirmed.");
return true; return true;
} else { } else {
Serial.println("Not authenticated. Requesting credentials."); 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(); redirect();
return false; return false;
} }
} }
//This function sends a simple webpage for changing login credentials to the client // This function sends a simple webpage for changing login credentials to the client
void showcredentialpage(){ void showcredentialpage() {
Serial.println("Show credential page called."); Serial.println("Show credential page called.");
if(!session_authenticated()){ if (!session_authenticated()) { return; }
return;
}
Serial.println("Forming credential modification page."); Serial.println("Forming credential modification page.");
String page; String page;
page = R"(<html>)"; page = R"(<html>)";
page+= page +=
R"( R"(
<h2>Login Credentials</h2><br> <h2>Login Credentials</h2><br>
<form action=")" + change_creds + R"(" method="post"> <form action=")"
+ change_creds + R"(" method="post">
Login:<br> Login:<br>
<input type="text" name="login"><br> <input type="text" name="login"><br>
Password:<br> Password:<br>
@ -178,8 +177,7 @@ void showcredentialpage(){
<input type="password" name="password_duplicate"><br> <input type="password" name="password_duplicate"><br>
<p><button type="submit" name="newcredentials">Change Credentials</button></p> <p><button type="submit" name="newcredentials">Change Credentials</button></p>
</form><br> </form><br>
)" )";
;
page += R"(</html>)"; page += R"(</html>)";
@ -188,17 +186,16 @@ void showcredentialpage(){
server.send(200, "text/html", page); server.send(200, "text/html", page);
} }
//Saves credentials to LittleFS // Saves credentials to LittleFS
void savecredentials(String new_login, String new_password) void savecredentials(String new_login, String new_password) {
{ // Set global variables to new values
//Set global variables to new values login = new_login;
login=new_login; H1 = ESP8266WebServer::credentialHash(new_login, realm, new_password);
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."); Serial.println("Saving credentials.");
File f=LittleFS.open(file_credentials,"w"); //open as a brand new file, discard old contents File f = LittleFS.open(file_credentials, "w"); // open as a brand new file, discard old contents
if(f){ if (f) {
Serial.println("Modifying credentials in file system."); Serial.println("Modifying credentials in file system.");
f.println(login); f.println(login);
f.println(H1); f.println(H1);
@ -209,19 +206,18 @@ void savecredentials(String new_login, String new_password)
Serial.println("Credentials saved."); Serial.println("Credentials saved.");
} }
//loads credentials from LittleFS // loads credentials from LittleFS
void loadcredentials() void loadcredentials() {
{
Serial.println("Searching for credentials."); Serial.println("Searching for credentials.");
File f; File f;
f=LittleFS.open(file_credentials,"r"); f = LittleFS.open(file_credentials, "r");
if(f){ if (f) {
Serial.println("Loading credentials from file system."); Serial.println("Loading credentials from file system.");
String mod=f.readString(); //read the file to a String String mod = f.readString(); // read the file to a String
int index_1=mod.indexOf('\n',0); //locate the first line break 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 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) 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) H1 = mod.substring(index_1 + 1, index_2 - 1); // get the second line (excluding the line break)
f.close(); f.close();
} else { } else {
String default_login = "admin"; String default_login = "admin";
@ -229,17 +225,15 @@ void loadcredentials()
Serial.println("None found. Setting to default credentials."); Serial.println("None found. Setting to default credentials.");
Serial.println("user:" + default_login); Serial.println("user:" + default_login);
Serial.println("password:" + default_password); Serial.println("password:" + default_password);
login=default_login; login = default_login;
H1=ESP8266WebServer::credentialHash(default_login,realm,default_password); 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() { void handlecredentialchange() {
Serial.println("Handle credential change called."); Serial.println("Handle credential change called.");
if(!session_authenticated()){ if (!session_authenticated()) { return; }
return;
}
Serial.println("Handling credential change request from client."); Serial.println("Handling credential change request from client.");
@ -247,9 +241,9 @@ void handlecredentialchange() {
String pw1 = server.arg("password"); String pw1 = server.arg("password");
String pw2 = server.arg("password_duplicate"); 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"); server.send(200, "text/plain", "Credentials updated");
redirect(); redirect();
} else { } else {

View File

@ -33,9 +33,7 @@ void setup(void) {
Serial.print("IP address: "); Serial.print("IP address: ");
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) { if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
Serial.println("MDNS responder started");
}
server.on(F("/"), []() { server.on(F("/"), []() {
server.send(200, "text/plain", "hello from esp8266!"); server.send(200, "text/plain", "hello from esp8266!");

View File

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

View File

@ -45,8 +45,8 @@ extern "C" {
#define STAPSK "your-password" #define STAPSK "your-password"
#endif #endif
const char* ssid = STASSID; const char *ssid = STASSID;
const char* password = STAPSK; const char *password = STAPSK;
const unsigned int port = 80; const unsigned int port = 80;
ESP8266WebServer server(port); ESP8266WebServer server(port);
@ -76,17 +76,13 @@ void handleNotFound() {
message += "\nArguments: "; message += "\nArguments: ";
message += server.args(); message += server.args();
message += "\n"; message += "\n";
for (uint8_t i = 0; i < server.args(); i++) { for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message); server.send(404, "text/plain", message);
} }
void SSEKeepAlive() { void SSEKeepAlive() {
for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) { for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) {
if (!(subscription[i].clientIP)) { if (!(subscription[i].clientIP)) { continue; }
continue;
}
if (subscription[i].client.connected()) { if (subscription[i].client.connected()) {
Serial.printf_P(PSTR("SSEKeepAlive - client is still listening on channel %d\n"), i); 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
@ -122,28 +118,20 @@ void SSEHandler(uint8_t channel) {
void handleAll() { void handleAll() {
const char *uri = server.uri().c_str(); const char *uri = server.uri().c_str();
const char *restEvents = PSTR("/rest/events/"); const char *restEvents = PSTR("/rest/events/");
if (strncmp_P(uri, restEvents, strlen_P(restEvents))) { if (strncmp_P(uri, restEvents, strlen_P(restEvents))) { return handleNotFound(); }
return handleNotFound();
}
uri += strlen_P(restEvents); // Skip the "/rest/events/" and get to the channel number uri += strlen_P(restEvents); // Skip the "/rest/events/" and get to the channel number
unsigned int channel = atoi(uri); unsigned int channel = atoi(uri);
if (channel < SSE_MAX_CHANNELS) { if (channel < SSE_MAX_CHANNELS) { return SSEHandler(channel); }
return SSEHandler(channel);
}
handleNotFound(); handleNotFound();
}; };
void SSEBroadcastState(const char *sensorName, unsigned short prevSensorValue, unsigned short sensorValue) { void SSEBroadcastState(const char *sensorName, unsigned short prevSensorValue, unsigned short sensorValue) {
for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) { for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) {
if (!(subscription[i].clientIP)) { if (!(subscription[i].clientIP)) { continue; }
continue;
}
String IPaddrstr = IPAddress(subscription[i].clientIP).toString(); String IPaddrstr = IPAddress(subscription[i].clientIP).toString();
if (subscription[i].client.connected()) { 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"), 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);
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);
subscription[i].client.printf_P(PSTR("event: event\ndata: {\"TYPE\":\"STATE\", \"%s\":{\"state\":%d, \"prevState\":%d}}\n\n"),
sensorName, sensorValue, prevSensorValue);
} else { } else {
Serial.printf_P(PSTR("SSEBroadcastState - client %s registered on channel %d but not listening\n"), IPaddrstr.c_str(), i); Serial.printf_P(PSTR("SSEBroadcastState - client %s registered on channel %d but not listening\n"), IPaddrstr.c_str(), i);
} }
@ -177,13 +165,11 @@ void handleSubscribe() {
++subscriptionCount; ++subscriptionCount;
for (channel = 0; channel < SSE_MAX_CHANNELS; channel++) // Find first free slot for (channel = 0; channel < SSE_MAX_CHANNELS; channel++) // Find first free slot
if (!subscription[channel].clientIP) { if (!subscription[channel].clientIP) { break; }
break; subscription[channel] = { clientIP, server.client(), Ticker() };
}
subscription[channel] = {clientIP, server.client(), Ticker()};
SSEurl += channel; SSEurl += channel;
Serial.printf_P(PSTR("Allocated channel %d, on uri %s\n"), channel, SSEurl.substring(offset).c_str()); 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()); 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()); server.send_P(200, "text/plain", SSEurl.c_str());
} }
@ -205,9 +191,7 @@ void setup(void) {
Serial.print("."); Serial.print(".");
} }
Serial.printf_P(PSTR("\nConnected to %s with IP address: %s\n"), ssid, WiFi.localIP().toString().c_str()); Serial.printf_P(PSTR("\nConnected to %s with IP address: %s\n"), ssid, WiFi.localIP().toString().c_str());
if (MDNS.begin("esp8266")) { if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
Serial.println("MDNS responder started");
}
startServers(); // start web and SSE servers startServers(); // start web and SSE servers
sensor[0].name = "sensorA"; sensor[0].name = "sensorA";

View File

@ -12,7 +12,7 @@ const char* password = STAPSK;
ESP8266WebServer server(80); ESP8266WebServer server(80);
//Check if header is present and correct // Check if header is present and correct
bool is_authenticated() { bool is_authenticated() {
Serial.println("Enter is_authenticated"); Serial.println("Enter is_authenticated");
if (server.hasHeader("Cookie")) { if (server.hasHeader("Cookie")) {
@ -28,7 +28,7 @@ bool is_authenticated() {
return false; return false;
} }
//login page, also called for disconnect // login page, also called for disconnect
void handleLogin() { void handleLogin() {
String msg; String msg;
if (server.hasHeader("Cookie")) { if (server.hasHeader("Cookie")) {
@ -64,7 +64,7 @@ void handleLogin() {
server.send(200, "text/html", content); 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() { void handleRoot() {
Serial.println("Enter handleRoot"); Serial.println("Enter handleRoot");
String header; String header;
@ -75,14 +75,12 @@ void handleRoot() {
return; return;
} }
String content = "<html><body><H2>hello, you successfully connected to esp8266!</H2><br>"; String content = "<html><body><H2>hello, you successfully connected to esp8266!</H2><br>";
if (server.hasHeader("User-Agent")) { if (server.hasHeader("User-Agent")) { content += "the user agent used is : " + server.header("User-Agent") + "<br><br>"; }
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>"; content += "You can access this page until you <a href=\"/login?DISCONNECT=YES\">disconnect</a></body></html>";
server.send(200, "text/html", content); server.send(200, "text/html", content);
} }
//no need authentication // no need authentication
void handleNotFound() { void handleNotFound() {
String message = "File Not Found\n\n"; String message = "File Not Found\n\n";
message += "URI: "; message += "URI: ";
@ -92,9 +90,7 @@ void handleNotFound() {
message += "\nArguments: "; message += "\nArguments: ";
message += server.args(); message += server.args();
message += "\n"; message += "\n";
for (uint8_t i = 0; i < server.args(); i++) { for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message); server.send(404, "text/plain", message);
} }
@ -123,7 +119,7 @@ void setup(void) {
}); });
server.onNotFound(handleNotFound); server.onNotFound(handleNotFound);
//ask server to track these headers // ask server to track these headers
server.collectHeaders("User-Agent", "Cookie"); server.collectHeaders("User-Agent", "Cookie");
server.begin(); server.begin();
Serial.println("HTTP server started"); Serial.println("HTTP server started");

View File

@ -41,9 +41,7 @@ void handleRedirect() {
TRACE("Redirect..."); TRACE("Redirect...");
String url = "/index.htm"; String url = "/index.htm";
if (!LittleFS.exists(url)) { if (!LittleFS.exists(url)) { url = "/$update.htm"; }
url = "/$update.htm";
}
server.sendHeader("Location", url, true); server.sendHeader("Location", url, true);
server.send(302); server.send(302);
@ -58,9 +56,7 @@ void handleListFiles() {
result += "[\n"; result += "[\n";
while (dir.next()) { while (dir.next()) {
if (result.length() > 4) { if (result.length() > 4) { result += ","; }
result += ",";
}
result += " {"; result += " {";
result += " \"name\": \"" + dir.fileName() + "\", "; result += " \"name\": \"" + dir.fileName() + "\", ";
result += " \"size\": " + String(dir.fileSize()) + ", "; result += " \"size\": " + String(dir.fileSize()) + ", ";
@ -97,7 +93,7 @@ void handleSysInfo() {
// The FileServerHandler is registered to the web server to support DELETE and UPLOAD of files into the filesystem. // The FileServerHandler is registered to the web server to support DELETE and UPLOAD of files into the filesystem.
class FileServerHandler : public RequestHandler { class FileServerHandler : public RequestHandler {
public: public:
// @brief Construct a new File Server Handler object // @brief Construct a new File Server Handler object
// @param fs The file system to be used. // @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 path Path to the root folder in the file system that is used for serving static data down and upload.
@ -125,17 +121,13 @@ class FileServerHandler : public RequestHandler {
bool handle(ESP8266WebServer &server, HTTPMethod requestMethod, const String &requestUri) override { bool handle(ESP8266WebServer &server, HTTPMethod requestMethod, const String &requestUri) override {
// ensure that filename starts with '/' // ensure that filename starts with '/'
String fName = requestUri; String fName = requestUri;
if (!fName.startsWith("/")) { if (!fName.startsWith("/")) { fName = "/" + fName; }
fName = "/" + fName;
}
if (requestMethod == HTTP_POST) { if (requestMethod == HTTP_POST) {
// all done in upload. no other forms. // all done in upload. no other forms.
} else if (requestMethod == HTTP_DELETE) { } else if (requestMethod == HTTP_DELETE) {
if (LittleFS.exists(fName)) { if (LittleFS.exists(fName)) { LittleFS.remove(fName); }
LittleFS.remove(fName);
}
} // if } // if
server.send(200); // all done. server.send(200); // all done.
@ -147,32 +139,24 @@ class FileServerHandler : public RequestHandler {
void upload(ESP8266WebServer UNUSED &server, const String UNUSED &_requestUri, HTTPUpload &upload) override { void upload(ESP8266WebServer UNUSED &server, const String UNUSED &_requestUri, HTTPUpload &upload) override {
// ensure that filename starts with '/' // ensure that filename starts with '/'
String fName = upload.filename; String fName = upload.filename;
if (!fName.startsWith("/")) { if (!fName.startsWith("/")) { fName = "/" + fName; }
fName = "/" + fName;
}
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
// Open the file // Open the file
if (LittleFS.exists(fName)) { if (LittleFS.exists(fName)) { LittleFS.remove(fName); } // if
LittleFS.remove(fName);
} // if
_fsUploadFile = LittleFS.open(fName, "w"); _fsUploadFile = LittleFS.open(fName, "w");
} else if (upload.status == UPLOAD_FILE_WRITE) { } else if (upload.status == UPLOAD_FILE_WRITE) {
// Write received bytes // Write received bytes
if (_fsUploadFile) { if (_fsUploadFile) { _fsUploadFile.write(upload.buf, upload.currentSize); }
_fsUploadFile.write(upload.buf, upload.currentSize);
}
} else if (upload.status == UPLOAD_FILE_END) { } else if (upload.status == UPLOAD_FILE_END) {
// Close the file // Close the file
if (_fsUploadFile) { if (_fsUploadFile) { _fsUploadFile.close(); }
_fsUploadFile.close();
}
} // if } // if
} // upload() } // upload()
protected: protected:
File _fsUploadFile; File _fsUploadFile;
}; };

View File

@ -31,18 +31,20 @@ void setup(void) {
server.sendHeader("Connection", "close"); server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex); server.send(200, "text/html", serverIndex);
}); });
server.on("/update", HTTP_POST, []() { server.on(
"/update", HTTP_POST, []() {
server.sendHeader("Connection", "close"); server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart(); ESP.restart();
}, []() { },
[]() {
HTTPUpload& upload = server.upload(); HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
Serial.setDebugOutput(true); Serial.setDebugOutput(true);
WiFiUDP::stopAll(); WiFiUDP::stopAll();
Serial.printf("Update: %s\n", upload.filename.c_str()); Serial.printf("Update: %s\n", upload.filename.c_str());
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { //start with max available size if (!Update.begin(maxSketchSpace)) { // start with max available size
Update.printError(Serial); Update.printError(Serial);
} }
} else if (upload.status == UPLOAD_FILE_WRITE) { } else if (upload.status == UPLOAD_FILE_WRITE) {
@ -50,7 +52,7 @@ void setup(void) {
Update.printError(Serial); Update.printError(Serial);
} }
} else if (upload.status == UPLOAD_FILE_END) { } else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress if (Update.end(true)) { // true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else { } else {
Update.printError(Serial); Update.printError(Serial);

View File

@ -72,9 +72,7 @@ void setClock() {
// Try and connect using a WiFiClientBearSSL to specified host:port and dump URL // 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) { void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) {
if (!path) { if (!path) { path = "/"; }
path = "/";
}
Serial.printf("Trying: %s:443...", host); Serial.printf("Trying: %s:443...", host);
client->connect(host, port); client->connect(host, port);
@ -94,11 +92,9 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
do { do {
char tmp[32]; char tmp[32];
memset(tmp, 0, 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(); yield();
if (rlen < 0) { if (rlen < 0) { break; }
break;
}
// Only print out first line up to \r, then abort connection // Only print out first line up to \r, then abort connection
char *nl = strchr(tmp, '\r'); char *nl = strchr(tmp, '\r');
if (nl) { if (nl) {
@ -156,9 +152,7 @@ void setup() {
void loop() { void loop() {
Serial.printf("\nPlease enter a website address (www.blah.com) to connect to: "); Serial.printf("\nPlease enter a website address (www.blah.com) to connect to: ");
String site; String site;
do { do { site = Serial.readString(); } while (site == "");
site = Serial.readString();
} while (site == "");
// Strip newline if present // Strip newline if present
site.replace(String("\r"), emptyString); site.replace(String("\r"), emptyString);
site.replace(String("\n"), emptyString); site.replace(String("\n"), emptyString);
@ -170,4 +164,3 @@ void loop() {
fetchURL(bear, site.c_str(), 443, "/"); fetchURL(bear, site.c_str(), 443, "/");
delete bear; delete bear;
} }

View File

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

View File

@ -181,7 +181,7 @@ void setup() {
#ifndef USE_EC #ifndef USE_EC
server.setRSACert(serverCertList, serverPrivKey); server.setRSACert(serverCertList, serverPrivKey);
#else #else
server.setECCert(serverCertList, BR_KEYTYPE_KEYX|BR_KEYTYPE_SIGN, serverPrivKey); server.setECCert(serverCertList, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, serverPrivKey);
#endif #endif
// Set the server's cache // Set the server's cache
@ -193,8 +193,7 @@ void setup() {
server.begin(); server.begin();
} }
static const char *HTTP_RES = static const char *HTTP_RES = "HTTP/1.0 200 OK\r\n"
"HTTP/1.0 200 OK\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Content-Length: 62\r\n" "Content-Length: 62\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n" "Content-Type: text/html; charset=iso-8859-1\r\n"
@ -208,16 +207,14 @@ static const char *HTTP_RES =
void loop() { void loop() {
static int cnt; static int cnt;
BearSSL::WiFiClientSecure incoming = server.accept(); BearSSL::WiFiClientSecure incoming = server.accept();
if (!incoming) { if (!incoming) { return; }
return; Serial.printf("Incoming connection...%d\n", cnt++);
}
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) // 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; int lcwn = 0;
for (;;) { for (;;) {
unsigned char x=0; unsigned char x = 0;
if ((millis() > timeout) || (incoming.available() && incoming.read(&x, 1) < 0)) { if ((millis() > timeout) || (incoming.available() && incoming.read(&x, 1) < 0)) {
incoming.stop(); incoming.stop();
Serial.printf("Connection error, closed\n"); Serial.printf("Connection error, closed\n");
@ -228,14 +225,12 @@ void loop() {
} else if (x == 0x0D) { } else if (x == 0x0D) {
continue; continue;
} else if (x == 0x0A) { } else if (x == 0x0A) {
if (lcwn) { if (lcwn) { break; }
break;
}
lcwn = 1; lcwn = 1;
} else } else
lcwn = 0; lcwn = 0;
} }
incoming.write((uint8_t*)HTTP_RES, strlen(HTTP_RES)); incoming.write((uint8_t *)HTTP_RES, strlen(HTTP_RES));
incoming.flush(); incoming.flush();
incoming.stop(); incoming.stop();
Serial.printf("Connection closed.\n"); Serial.printf("Connection closed.\n");

View File

@ -160,8 +160,7 @@ seoK24dHmt6tWmn/sbxX7Aa6TL/4mVlFoOgcaTJyVaY/BrY=
// head of the app. // head of the app.
// Set time via NTP, as required for x.509 validation // Set time via NTP, as required for x.509 validation
void setClock() void setClock() {
{
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
Serial.print("Waiting for NTP time sync: "); Serial.print("Waiting for NTP time sync: ");
@ -214,8 +213,7 @@ void setup() {
server.begin(); server.begin();
} }
static const char *HTTP_RES = static const char *HTTP_RES = "HTTP/1.0 200 OK\r\n"
"HTTP/1.0 200 OK\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Content-Length: 59\r\n" "Content-Length: 59\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n" "Content-Type: text/html; charset=iso-8859-1\r\n"
@ -228,16 +226,14 @@ static const char *HTTP_RES =
void loop() { void loop() {
BearSSL::WiFiClientSecure incoming = server.accept(); BearSSL::WiFiClientSecure incoming = server.accept();
if (!incoming) { if (!incoming) { return; }
return;
}
Serial.println("Incoming connection...\n"); 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) // 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; int lcwn = 0;
for (;;) { for (;;) {
unsigned char x=0; unsigned char x = 0;
if ((millis() > timeout) || (incoming.available() && incoming.read(&x, 1) < 0)) { if ((millis() > timeout) || (incoming.available() && incoming.read(&x, 1) < 0)) {
incoming.stop(); incoming.stop();
Serial.printf("Connection error, closed\n"); Serial.printf("Connection error, closed\n");
@ -248,14 +244,12 @@ void loop() {
} else if (x == 0x0D) { } else if (x == 0x0D) {
continue; continue;
} else if (x == 0x0A) { } else if (x == 0x0A) {
if (lcwn) { if (lcwn) { break; }
break;
}
lcwn = 1; lcwn = 1;
} else } else
lcwn = 0; lcwn = 0;
} }
incoming.write((uint8_t*)HTTP_RES, strlen(HTTP_RES)); incoming.write((uint8_t *)HTTP_RES, strlen(HTTP_RES));
incoming.flush(); incoming.flush();
incoming.stop(); incoming.stop();
Serial.printf("Connection closed.\n"); Serial.printf("Connection closed.\n");

View File

@ -15,7 +15,7 @@
const char *ssid = STASSID; const char *ssid = STASSID;
const char *pass = STAPSK; const char *pass = STAPSK;
const char * path = "/"; const char *path = "/";
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
@ -53,9 +53,7 @@ void setup() {
// Try and connect using a WiFiClientBearSSL to specified host:port and dump HTTP response // 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) { void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) {
if (!path) { if (!path) { path = "/"; }
path = "/";
}
Serial.printf("Trying: %s:443...", host); Serial.printf("Trying: %s:443...", host);
client->connect(host, port); client->connect(host, port);
@ -75,11 +73,9 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
do { do {
char tmp[32]; char tmp[32];
memset(tmp, 0, 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(); yield();
if (rlen < 0) { if (rlen < 0) { break; }
break;
}
// Only print out first line up to \r, then abort connection // Only print out first line up to \r, then abort connection
char *nl = strchr(tmp, '\r'); char *nl = strchr(tmp, '\r');
if (nl) { if (nl) {
@ -132,4 +128,3 @@ void loop() {
delay(10000); // Avoid DDOSing github delay(10000); // Avoid DDOSing github
} }

View File

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

View File

@ -74,10 +74,7 @@ void setup() {
Serial.print("Requesting URL: "); Serial.print("Requesting URL: ");
Serial.println(url); Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\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");
"Host: " + github_host + "\r\n" +
"User-Agent: BuildFailureDetectorESP8266\r\n" +
"Connection: close\r\n\r\n");
Serial.println("Request sent"); Serial.println("Request sent");
while (client.connected()) { while (client.connected()) {
@ -100,5 +97,4 @@ void setup() {
Serial.println("Closing connection"); Serial.println("Closing connection");
} }
void loop() { void loop() {}
}

View File

@ -71,29 +71,17 @@ void status(Print& out) {
for (int i = 0; i < DNS_MAX_SERVERS; i++) { for (int i = 0; i < DNS_MAX_SERVERS; i++) {
IPAddress dns = WiFi.dnsIP(i); IPAddress dns = WiFi.dnsIP(i);
if (dns.isSet()) { if (dns.isSet()) { out.printf("dns%d: %s\n", i, dns.toString().c_str()); }
out.printf("dns%d: %s\n", i, dns.toString().c_str());
}
} }
out.println(F("Try me at these addresses:")); out.println(F("Try me at these addresses:"));
out.println(F("(with 'telnet <addr> or 'nc -u <addr> 23')")); out.println(F("(with 'telnet <addr> or 'nc -u <addr> 23')"));
for (auto a : addrList) { for (auto a : addrList) {
out.printf("IF='%s' IPv6=%d local=%d hostname='%s' addr= %s", 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());
a.ifname().c_str(),
a.isV6(),
a.isLocal(),
a.ifhostname(),
a.toString().c_str());
if (a.isLegacy()) { if (a.isLegacy()) { out.printf(" / mask:%s / gw:%s", a.netmask().toString().c_str(), a.gw().toString().c_str()); }
out.printf(" / mask:%s / gw:%s",
a.netmask().toString().c_str(),
a.gw().toString().c_str());
}
out.println(); out.println();
} }
// lwIP's dns client will ask for IPv4 first (by default) // lwIP's dns client will ask for IPv4 first (by default)
@ -148,9 +136,7 @@ void setup() {
if ((configured = !addr.isLocal() if ((configured = !addr.isLocal()
// && addr.isV6() // uncomment when IPv6 is mandatory // && addr.isV6() // uncomment when IPv6 is mandatory
// && addr.ifnumber() == STATION_IF // && addr.ifnumber() == STATION_IF
)) { )) { break; }
break;
}
Serial.print('.'); Serial.print('.');
delay(500); delay(500);
} }
@ -189,9 +175,7 @@ void loop() {
Serial.print(F(" :")); Serial.print(F(" :"));
Serial.println(udp.remotePort()); Serial.println(udp.remotePort());
int c; int c;
while ((c = udp.read()) >= 0) { while ((c = udp.read()) >= 0) { Serial.write(c); }
Serial.write(c);
}
// send a reply, to the IP address and port that sent us the packet we received // send a reply, to the IP address and port that sent us the packet we received
udp.beginPacket(udp.remoteIP(), udp.remotePort()); udp.beginPacket(udp.remoteIP(), udp.remotePort());
@ -200,8 +184,5 @@ void loop() {
} }
if (showStatusOnSerialNow) { if (showStatusOnSerialNow) { status(Serial); }
status(Serial);
}
} }

View File

@ -26,21 +26,21 @@
#define STAPSK "your-password" #define STAPSK "your-password"
#endif #endif
const char * ssid = STASSID; // your network SSID (name) const char* ssid = STASSID; // your network SSID (name)
const char * pass = STAPSK; // your network password 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. /* 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 */ Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server // IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov"; 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 // A UDP instance to let us send and receive packets over UDP
WiFiUDP udp; WiFiUDP udp;
@ -73,7 +73,7 @@ void setup() {
} }
void loop() { void loop() {
//get a random server from the pool // get a random server from the pool
WiFi.hostByName(ntpServerName, timeServerIP); WiFi.hostByName(ntpServerName, timeServerIP);
sendNTPpacket(timeServerIP); // send an NTP packet to a time server sendNTPpacket(timeServerIP); // send an NTP packet to a time server
@ -89,7 +89,7 @@ void loop() {
// We've received a packet, read the data from it // 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, // the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words: // or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
@ -149,7 +149,7 @@ void sendNTPpacket(IPAddress& address) {
// all NTP fields have been given values, now // all NTP fields have been given values, now
// you can send a packet requesting a timestamp: // 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.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket(); udp.endPacket();
} }

View File

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

View File

@ -26,7 +26,7 @@
unsigned int localPort = 8888; // local port to listen on unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data // buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet, char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged\r\n"; // a string to send back char ReplyBuffer[] = "acknowledged\r\n"; // a string to send back
WiFiUDP Udp; WiFiUDP Udp;
@ -49,11 +49,7 @@ void loop() {
// if there's data available, read a packet // if there's data available, read a packet
int packetSize = Udp.parsePacket(); int packetSize = Udp.parsePacket();
if (packetSize) { if (packetSize) {
Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n", 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());
packetSize,
Udp.remoteIP().toString().c_str(), Udp.remotePort(),
Udp.destinationIP().toString().c_str(), Udp.localPort(),
ESP.getFreeHeap());
// read the packet into packetBufffer // read the packet into packetBufffer
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
@ -66,7 +62,6 @@ void loop() {
Udp.write(ReplyBuffer); Udp.write(ReplyBuffer);
Udp.endPacket(); Udp.endPacket();
} }
} }
/* /*

View File

@ -61,9 +61,7 @@ void loop() {
// This will send a string to the server // This will send a string to the server
Serial.println("sending data to server"); Serial.println("sending data to server");
if (client.connected()) { if (client.connected()) { client.println("hello from ESP8266"); }
client.println("hello from ESP8266");
}
// wait for data to be available // wait for data to be available
unsigned long timeout = millis(); unsigned long timeout = millis();

View File

@ -64,7 +64,7 @@ void loop() {
// This will send the request to the server // This will send the request to the server
client.println("hello from ESP8266"); client.println("hello from ESP8266");
//read back one line from server // read back one line from server
Serial.println("receiving from remote server"); Serial.println("receiving from remote server");
String line = client.readStringUntil('\r'); String line = client.readStringUntil('\r');
Serial.println(line); Serial.println(line);
@ -75,4 +75,3 @@ void loop() {
Serial.println("wait 5 sec..."); Serial.println("wait 5 sec...");
delay(5000); delay(5000);
} }

View File

@ -19,7 +19,7 @@ constexpr int port = 23;
WiFiServer server(port); WiFiServer server(port);
WiFiClient client; 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; constexpr uint32_t breathMs = 200;
esp8266::polledTimeout::oneShotFastMs enoughMs(breathMs); esp8266::polledTimeout::oneShotFastMs enoughMs(breathMs);
esp8266::polledTimeout::periodicFastMs test(2000); esp8266::polledTimeout::periodicFastMs test(2000);
@ -63,19 +63,13 @@ void loop() {
static uint32_t cnt = 0; static uint32_t cnt = 0;
if (test && cnt) { if (test && cnt) {
Serial.printf("measured-block-size=%u min-free-stack=%u", tot / cnt, ESP.getFreeContStack()); Serial.printf("measured-block-size=%u min-free-stack=%u", tot / cnt, ESP.getFreeContStack());
if (t == 2 && sizes[s]) { if (t == 2 && sizes[s]) { Serial.printf(" (blocks: at most %d bytes)", 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 == 3 && sizes[s]) {
Serial.printf(" (blocks: exactly %d bytes)", sizes[s]);
}
if (t == 3 && !sizes[s]) {
Serial.printf(" (blocks: any size)");
}
Serial.printf("\n"); Serial.printf("\n");
} }
//check if there are any new clients // check if there are any new clients
if (server.hasClient()) { if (server.hasClient()) {
client = server.accept(); client = server.accept();
Serial.println("New client"); Serial.println("New client");
@ -84,10 +78,25 @@ void loop() {
if (Serial.available()) { if (Serial.available()) {
s = (s + 1) % (sizeof(sizes) / sizeof(sizes[0])); s = (s + 1) % (sizeof(sizes) / sizeof(sizes[0]));
switch (Serial.read()) { 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 '1':
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; if (t != 1) s = 0;
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; t = 1;
case '4': t = 4; Serial.printf("direct access (sendAll - close peer to stop, then press 1, 2 or 3 before restarting peer)\n"); break; 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; tot = cnt = 0;
ESP.resetFreeContStack(); ESP.resetFreeContStack();
@ -113,9 +122,7 @@ void loop() {
uint8_t buf[maxTo]; uint8_t buf[maxTo];
size_t tcp_got = client.read(buf, maxTo); size_t tcp_got = client.read(buf, maxTo);
size_t tcp_sent = client.write(buf, tcp_got); size_t tcp_sent = client.write(buf, tcp_got);
if (tcp_sent != maxTo) { if (tcp_sent != maxTo) { Serial.printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxTo, tcp_got, tcp_sent); }
Serial.printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxTo, tcp_got, tcp_sent);
}
tot += tcp_sent; tot += tcp_sent;
cnt++; cnt++;
} }
@ -152,5 +159,4 @@ void loop() {
case Stream::Report::ShortOperation: Serial.println("Stream::send: short transfer"); break; case Stream::Report::ShortOperation: Serial.println("Stream::send: short transfer"); break;
} }
} }
} }

View File

@ -98,7 +98,6 @@ void loop() {
String macToString(const unsigned char* mac) { String macToString(const unsigned char* mac) {
char buf[20]; char buf[20];
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(buf); return String(buf);
} }

View File

@ -55,9 +55,7 @@ void setup() {
void loop() { void loop() {
// Check if a client has connected // Check if a client has connected
WiFiClient client = server.accept(); WiFiClient client = server.accept();
if (!client) { if (!client) { return; }
return;
}
Serial.println(F("new client")); Serial.println(F("new client"));
client.setTimeout(5000); // default is 1000 client.setTimeout(5000); // default is 1000

View File

@ -40,15 +40,7 @@ void loop() {
for (int8_t i = 0; i < scanResult; i++) { for (int8_t i = 0; i < scanResult; i++) {
WiFi.getNetworkInfo(i, ssid, encryptionType, rssi, bssid, channel, hidden); 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"), 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());
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(); yield();
} }
} else { } else {

View File

@ -26,7 +26,7 @@ const char* password = STAPSK;
void setup() { void setup() {
Serial.begin(74880); 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..."); 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 // 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. // 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(); unsigned long start = millis();
if (!WiFi.resumeFromShutdown(state) if (!WiFi.resumeFromShutdown(state) || (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
|| (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
Serial.println("Cannot resume WiFi connection, connecting via begin..."); Serial.println("Cannot resume WiFi connection, connecting via begin...");
WiFi.persistent(false); WiFi.persistent(false);
if (!WiFi.mode(WIFI_STA) if (!WiFi.mode(WIFI_STA) || !WiFi.begin(ssid, password) || (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
|| !WiFi.begin(ssid, password)
|| (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
Serial.println("Cannot connect!"); Serial.println("Cannot connect!");
Serial.flush(); Serial.flush();
@ -64,7 +61,7 @@ void setup() {
// --- // ---
WiFi.shutdown(state); 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. // Here you can do whatever you need to do that doesn't need a WiFi connection anymore.

View File

@ -66,7 +66,7 @@ SoftwareSerial* logger = nullptr;
#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 #define MAX_SRV_CLIENTS 2
const char* ssid = STASSID; const char* ssid = STASSID;
const char* password = STAPSK; const char* password = STAPSK;
@ -114,7 +114,7 @@ void setup() {
logger->print("connected, address="); logger->print("connected, address=");
logger->println(WiFi.localIP()); logger->println(WiFi.localIP());
//start server // start server
server.begin(); server.begin();
server.setNoDelay(true); server.setNoDelay(true);
@ -124,9 +124,9 @@ void setup() {
} }
void loop() { void loop() {
//check if there are any new clients // check if there are any new clients
if (server.hasClient()) { if (server.hasClient()) {
//find free/disconnected spot // find free/disconnected spot
int i; int i;
for (i = 0; i < MAX_SRV_CLIENTS; 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()
@ -136,7 +136,7 @@ void loop() {
break; break;
} }
//no free/disconnected spot so reject // no free/disconnected spot so reject
if (i == MAX_SRV_CLIENTS) { if (i == MAX_SRV_CLIENTS) {
server.accept().println("busy"); server.accept().println("busy");
// hints: server.accept() is a WiFiClient with short-term scope // 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 #if 1
// Incredibly, this code is faster than the buffered one below - #4620 is needed // Incredibly, this code is faster than the buffered one below - #4620 is needed
// loopback/3000000baud average 348KB/s // loopback/3000000baud average 348KB/s
@ -165,9 +165,7 @@ void loop() {
uint8_t buf[maxToSerial]; uint8_t buf[maxToSerial];
size_t tcp_got = serverClients[i].read(buf, maxToSerial); size_t tcp_got = serverClients[i].read(buf, maxToSerial);
size_t serial_sent = Serial.write(buf, tcp_got); size_t serial_sent = Serial.write(buf, tcp_got);
if (serial_sent != maxToSerial) { if (serial_sent != maxToSerial) { logger->printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxToSerial, tcp_got, serial_sent); }
logger->printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxToSerial, tcp_got, serial_sent);
}
} }
#endif #endif
@ -189,7 +187,7 @@ void loop() {
} }
} }
//check UART for data // check UART for data
size_t len = std::min(Serial.available(), maxToTcp); size_t len = std::min(Serial.available(), maxToTcp);
len = std::min(len, (size_t)STACK_PROTECTOR); len = std::min(len, (size_t)STACK_PROTECTOR);
if (len) { if (len) {
@ -202,9 +200,7 @@ void loop() {
// ensure write space is sufficient: // ensure write space is sufficient:
if (serverClients[i].availableForWrite() >= serial_got) { if (serverClients[i].availableForWrite() >= serial_got) {
size_t tcp_sent = serverClients[i].write(sbuf, serial_got); size_t tcp_sent = serverClients[i].write(sbuf, serial_got);
if (tcp_sent != len) { if (tcp_sent != len) { logger->printf("len mismatch: available:%zd serial-read:%zd tcp-write:%zd\n", len, serial_got, tcp_sent); }
logger->printf("len mismatch: available:%zd serial-read:%zd tcp-write:%zd\n", len, serial_got, tcp_sent);
}
} }
} }
} }

View File

@ -25,15 +25,12 @@ constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; //
// 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. // 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. // 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. // 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. 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 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.
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 };
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 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 requestNumber = 0;
unsigned int responseNumber = 0; unsigned int responseNumber = 0;
@ -281,8 +278,8 @@ void setup() {
// Uncomment the lines below to use automatic AEAD encryption/decryption of messages sent/received. // 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. // 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. // 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.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.setUseEncryptedMessages(true);
} }
int32_t timeOfLastScan = -10000; int32_t timeOfLastScan = -10000;
@ -293,7 +290,7 @@ 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. // 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. // 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(); 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.
@ -310,9 +307,7 @@ void loop() {
espnowDelay(100); espnowDelay(100);
// One way to check how attemptTransmission worked out // One way to check how attemptTransmission worked out
if (espnowNode.latestTransmissionSuccessful()) { if (espnowNode.latestTransmissionSuccessful()) { Serial.println(F("Transmission successful.")); }
Serial.println(F("Transmission successful."));
}
// Another way to check how attemptTransmission worked out // Another way to check how attemptTransmission worked out
if (espnowNode.latestTransmissionOutcomes().empty()) { if (espnowNode.latestTransmissionOutcomes().empty()) {
@ -348,7 +343,7 @@ void loop() {
// 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. // 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. // 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. // 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('.'); String espnowMessage = TypeCast::uint8ArrayToMultiString(dataArray, sizeof dataArray) + F(" from ") + espnowNode.getMeshName() + espnowNode.getNodeID() + String('.');
Serial.println(String(F("\nTransmitting: ")) + espnowMessage); Serial.println(String(F("\nTransmitting: ")) + espnowMessage);
espnowNode.attemptTransmission(espnowMessage, false); espnowNode.attemptTransmission(espnowMessage, false);
@ -356,7 +351,7 @@ void loop() {
Serial.println(F("\nPerforming encrypted ESP-NOW transmissions.")); 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. // 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) { if (espnowNode.constConnectionQueue()[0].getBSSID(targetBSSID) && espnowNode.requestEncryptedConnection(targetBSSID) == EncryptedConnectionStatus::CONNECTION_ESTABLISHED) {
@ -445,8 +440,7 @@ void loop() {
} }
// Our last request was sent to all nodes found, so time to create a new request. // 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.setMessage(String(F("Hello world request #")) + String(++requestNumber) + F(" from ") + espnowNode.getMeshName() + espnowNode.getNodeID() + String('.'));
+ espnowNode.getMeshName() + espnowNode.getNodeID() + String('.'));
} }
Serial.println(); Serial.println();

View File

@ -34,12 +34,10 @@ constexpr char exampleWiFiPassword[] PROGMEM = "ChangeThisWiFiPassword_TODO"; //
// 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. // 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. // 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. // 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. 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 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.
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 };
0x33, 0x44, 0x33, 0xB0, 0x33, 0x44, 0x32, 0xAD
};
bool meshMessageHandler(String &message, FloodingMesh &meshInstance); bool meshMessageHandler(String &message, FloodingMesh &meshInstance);
@ -101,12 +99,8 @@ bool meshMessageHandler(String &message, FloodingMesh &meshInstance) {
missedBroadcasts += totalBroadcasts - previousTotalBroadcasts - 1; // We expect an increment by 1. missedBroadcasts += totalBroadcasts - previousTotalBroadcasts - 1; // We expect an increment by 1.
previousTotalBroadcasts = totalBroadcasts; previousTotalBroadcasts = totalBroadcasts;
if (totalReceivedBroadcasts % 50 == 0) { if (totalReceivedBroadcasts % 50 == 0) { Serial.println(String(F("missed/total: ")) + String(missedBroadcasts) + '/' + String(totalReceivedBroadcasts)); }
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 % 500 == 0) {
Serial.println(String(F("Benchmark message: ")) + message.substring(0, 100));
}
} }
} }
} else { } else {
@ -138,7 +132,7 @@ void setup() {
floodingMesh.begin(); 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)); theOneMac = TypeCast::macToString(WiFi.softAPmacAddress(apMacArray));
if (useLED) { if (useLED) {
@ -150,8 +144,8 @@ void setup() {
// The main benefit of AEAD encryption is that it can be used with normal broadcasts (which are substantially faster than encryptedBroadcasts). // 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. // 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. // 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().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().setUseEncryptedMessages(true);
floodingMeshDelay(5000); // Give some time for user to start the nodes floodingMeshDelay(5000); // Give some time for user to start the nodes
} }

View File

@ -145,8 +145,7 @@ bool exampleTransmissionOutcomesUpdateHook(MeshBackendBase &meshInstance) {
if (TcpIpMeshBackend *tcpIpInstance = TypeCast::meshBackendCast<TcpIpMeshBackend *>(&meshInstance)) { if (TcpIpMeshBackend *tcpIpInstance = TypeCast::meshBackendCast<TcpIpMeshBackend *>(&meshInstance)) {
if (tcpIpInstance->latestTransmissionOutcomes().back().transmissionStatus() == TransmissionStatusType::TRANSMISSION_COMPLETE) { if (tcpIpInstance->latestTransmissionOutcomes().back().transmissionStatus() == TransmissionStatusType::TRANSMISSION_COMPLETE) {
// Our last request got a response, so time to create a new request. // 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.setMessage(String(F("Hello world request #")) + String(++requestNumber) + F(" from ") + meshInstance.getMeshName() + meshInstance.getNodeID() + String('.'));
+ meshInstance.getMeshName() + meshInstance.getNodeID() + String('.'));
} }
} else { } else {
Serial.println(F("Invalid mesh backend!")); Serial.println(F("Invalid mesh backend!"));
@ -194,9 +193,7 @@ void loop() {
timeOfLastScan = millis(); timeOfLastScan = millis();
// One way to check how attemptTransmission worked out // One way to check how attemptTransmission worked out
if (tcpIpNode.latestTransmissionSuccessful()) { if (tcpIpNode.latestTransmissionSuccessful()) { Serial.println(F("Transmission successful.")); }
Serial.println(F("Transmission successful."));
}
// Another way to check how attemptTransmission worked out // Another way to check how attemptTransmission worked out
if (tcpIpNode.latestTransmissionOutcomes().empty()) { if (tcpIpNode.latestTransmissionOutcomes().empty()) {

View File

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

View File

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

View File

@ -87,9 +87,7 @@ void loop() {
BearSSL::WiFiClientSecure client; BearSSL::WiFiClientSecure client;
bool mfln = client.probeMaxFragmentLength("server", 443, 1024); // server must be the same as in ESPhttpUpdate.update() 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"); Serial.printf("MFLN supported: %s\n", mfln ? "yes" : "no");
if (mfln) { if (mfln) { client.setBufferSizes(1024, 1024); }
client.setBufferSizes(1024, 1024);
}
client.setCertStore(&certStore); client.setCertStore(&certStore);
// The line below is optional. It can be used to blink the LED on the board during flashing // 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"); t_httpUpdate_return ret = ESPhttpUpdate.update(client, "https://server/file.bin");
// Or: // 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) { switch (ret) {
case HTTP_UPDATE_FAILED: case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES: case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK: case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;
Serial.println("HTTP_UPDATE_OK");
break;
} }
} }
} }

View File

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

View File

@ -73,8 +73,7 @@ const char* getTimeString(void) {
time_t now = time(nullptr); time_t now = time(nullptr);
ctime_r(&now, acTimeString); ctime_r(&now, acTimeString);
size_t stLength; size_t stLength;
while (((stLength = strlen(acTimeString))) && while (((stLength = strlen(acTimeString))) && ('\n' == acTimeString[stLength - 1])) {
('\n' == acTimeString[stLength - 1])) {
acTimeString[stLength - 1] = 0; // Remove trailing line break... acTimeString[stLength - 1] = 0; // Remove trailing line break...
} }
return acTimeString; return acTimeString;
@ -186,7 +185,8 @@ void handleHTTPRequest() {
Serial.println("HTTP Request"); Serial.println("HTTP Request");
// Get current time // Get current time
time_t now = time(nullptr);; time_t now = time(nullptr);
;
struct tm timeinfo; struct tm timeinfo;
gmtime_r(&now, &timeinfo); gmtime_r(&now, &timeinfo);
@ -231,8 +231,7 @@ void setup(void) {
// Setup MDNS responder // Setup MDNS responder
MDNS.setHostProbeResultCallback(hostProbeResult); MDNS.setHostProbeResultCallback(hostProbeResult);
// Init the (currently empty) host domain string with 'esp8266' // Init the (currently empty) host domain string with 'esp8266'
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) || if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) || (!MDNS.begin(pcHostDomain))) {
(!MDNS.begin(pcHostDomain))) {
Serial.println("Error setting up MDNS responder!"); Serial.println("Error setting up MDNS responder!");
while (1) { // STOP while (1) { // STOP
delay(1000); delay(1000);

View File

@ -80,26 +80,17 @@ bool setStationHostname(const char* p_pcHostname) {
void MDNSServiceQueryCallback(MDNSResponder::MDNSServiceInfo serviceInfo, MDNSResponder::AnswerType answerType, bool p_bSetContent) { void MDNSServiceQueryCallback(MDNSResponder::MDNSServiceInfo serviceInfo, MDNSResponder::AnswerType answerType, bool p_bSetContent) {
String answerInfo; String answerInfo;
switch (answerType) { switch (answerType) {
case MDNSResponder::AnswerType::ServiceDomain : case MDNSResponder::AnswerType::ServiceDomain: answerInfo = "ServiceDomain " + String(serviceInfo.serviceDomain()); break;
answerInfo = "ServiceDomain " + String(serviceInfo.serviceDomain()); case MDNSResponder::AnswerType::HostDomainAndPort: answerInfo = "HostDomainAndPort " + String(serviceInfo.hostDomain()) + ":" + String(serviceInfo.hostPort()); break;
break; case MDNSResponder::AnswerType::IP4Address:
case MDNSResponder::AnswerType::HostDomainAndPort :
answerInfo = "HostDomainAndPort " + String(serviceInfo.hostDomain()) + ":" + String(serviceInfo.hostPort());
break;
case MDNSResponder::AnswerType::IP4Address :
answerInfo = "IP4Address "; answerInfo = "IP4Address ";
for (IPAddress ip : serviceInfo.IP4Adresses()) { for (IPAddress ip : serviceInfo.IP4Adresses()) { answerInfo += "- " + ip.toString(); };
answerInfo += "- " + ip.toString();
};
break; break;
case MDNSResponder::AnswerType::Txt : case MDNSResponder::AnswerType::Txt:
answerInfo = "TXT " + String(serviceInfo.strKeyValue()); answerInfo = "TXT " + String(serviceInfo.strKeyValue());
for (auto kv : serviceInfo.keyValues()) { for (auto kv : serviceInfo.keyValues()) { answerInfo += "\nkv : " + String(kv.first) + " : " + String(kv.second); }
answerInfo += "\nkv : " + String(kv.first) + " : " + String(kv.second);
}
break; break;
default : default: answerInfo = "Unknown Answertype";
answerInfo = "Unknown Answertype";
} }
Serial.printf("Answer %s %s\n", answerInfo.c_str(), p_bSetContent ? "Modified" : "Deleted"); 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 Probe result callback for Services
*/ */
void serviceProbeResult(String p_pcServiceName, void serviceProbeResult(String p_pcServiceName, const MDNSResponder::hMDNSService p_hMDNSService, bool p_bProbeResult) {
const MDNSResponder::hMDNSService p_hMDNSService, (void)p_hMDNSService;
bool p_bProbeResult) {
(void) p_hMDNSService;
Serial.printf("MDNSServiceProbeResultCallback: Service %s probe %s\n", p_pcServiceName.c_str(), (p_bProbeResult ? "succeeded." : "failed!")); Serial.printf("MDNSServiceProbeResultCallback: Service %s probe %s\n", p_pcServiceName.c_str(), (p_bProbeResult ? "succeeded." : "failed!"));
} }
@ -196,15 +185,11 @@ void handleHTTPRequest() {
} }
if (info.IP4AddressAvailable()) { if (info.IP4AddressAvailable()) {
s += "<br/>IP4:"; s += "<br/>IP4:";
for (auto ip : info.IP4Adresses()) { for (auto ip : info.IP4Adresses()) { s += " " + ip.toString(); }
s += " " + ip.toString();
}
} }
if (info.txtAvailable()) { if (info.txtAvailable()) {
s += "<br/>TXT:<br/>"; s += "<br/>TXT:<br/>";
for (auto kv : info.keyValues()) { for (auto kv : info.keyValues()) { s += "\t" + String(kv.first) + " : " + String(kv.second) + "<br/>"; }
s += "\t" + String(kv.first) + " : " + String(kv.second) + "<br/>";
}
} }
s += "</li>"; s += "</li>";
} }
@ -245,8 +230,7 @@ void setup(void) {
MDNS.setHostProbeResultCallback(hostProbeResult); MDNS.setHostProbeResultCallback(hostProbeResult);
// Init the (currently empty) host domain string with 'esp8266' // Init the (currently empty) host domain string with 'esp8266'
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) || if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) || (!MDNS.begin(pcHostDomain))) {
(!MDNS.begin(pcHostDomain))) {
Serial.println(" Error setting up MDNS responder!"); Serial.println(" Error setting up MDNS responder!");
while (1) { // STOP while (1) { // STOP
delay(1000); delay(1000);
@ -265,6 +249,3 @@ void loop(void) {
// Allow MDNS processing // Allow MDNS processing
MDNS.update(); MDNS.update();
} }

View File

@ -42,8 +42,8 @@
@brief Default WiFi connection information. @brief Default WiFi connection information.
@{ @{
*/ */
const char* ap_default_ssid = APSSID; ///< Default SSID. const char *ap_default_ssid = APSSID; ///< Default SSID.
const char* ap_default_psk = APPSK; ///< Default PSK. const char *ap_default_psk = APPSK; ///< Default PSK.
/// @} /// @}
/// Uncomment the next line for verbose output over UART. /// Uncomment the next line for verbose output over UART.
@ -81,9 +81,7 @@ bool loadConfig(String *ssid, String *pass) {
if (pos == -1) { if (pos == -1) {
le = 1; le = 1;
pos = content.indexOf("\n"); pos = content.indexOf("\n");
if (pos == -1) { if (pos == -1) { pos = content.indexOf("\r"); }
pos = content.indexOf("\r");
}
} }
// If there is no second line: Some information is missing. // If there is no second line: Some information is missing.
@ -160,7 +158,7 @@ void setup() {
// Print hostname. // Print hostname.
Serial.println("Hostname: " + hostname); Serial.println("Hostname: " + hostname);
//Serial.println(WiFi.hostname()); // Serial.println(WiFi.hostname());
// Initialize file system. // Initialize file system.
@ -170,7 +168,7 @@ void setup() {
} }
// Load wifi connection information. // Load wifi connection information.
if (! loadConfig(&station_ssid, &station_psk)) { if (!loadConfig(&station_ssid, &station_psk)) {
station_ssid = STASSID; station_ssid = STASSID;
station_psk = STAPSK; station_psk = STAPSK;
@ -196,7 +194,7 @@ void setup() {
Serial.println(WiFi.SSID()); Serial.println(WiFi.SSID());
// ... Uncomment this for debugging output. // ... Uncomment this for debugging output.
//WiFi.printDiag(Serial); // WiFi.printDiag(Serial);
} else { } else {
// ... Begin with sdk config. // ... Begin with sdk config.
WiFi.begin(); WiFi.begin();
@ -208,7 +206,7 @@ void setup() {
unsigned long startTime = millis(); unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) { while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
Serial.write('.'); Serial.write('.');
//Serial.print(WiFi.status()); // Serial.print(WiFi.status());
delay(500); delay(500);
} }
Serial.println(); Serial.println();
@ -245,4 +243,3 @@ void loop() {
// Handle OTA server. // Handle OTA server.
ArduinoOTA.handle(); ArduinoOTA.handle();
} }

View File

@ -19,7 +19,7 @@
const char* ssid = STASSID; const char* ssid = STASSID;
const char* password = STAPSK; const char* password = STAPSK;
char hostString[16] = {0}; char hostString[16] = { 0 };
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
@ -43,9 +43,7 @@ void setup() {
Serial.print("IP address: "); Serial.print("IP address: ");
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
if (!MDNS.begin(hostString)) { if (!MDNS.begin(hostString)) { Serial.println("Error setting up MDNS responder!"); }
Serial.println("Error setting up MDNS responder!");
}
Serial.println("mDNS responder started"); 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

View File

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

View File

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

View File

@ -3,15 +3,19 @@
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
mDNS implementation, that supports many mDNS features like: 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 - Presenting a DNS-SD service to interested observers, eg. a http server by presenting
- Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented _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 - 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 - Announcing available services after successful probing
- Using fixed service TXT items or - Using fixed service TXT items or
- Using dynamic service TXT items for presented services (via callback) - Using dynamic service TXT items for presented services (via callback)
- Remove services (and un-announcing them to the observers by sending goodbye-messages) - 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 - Dynamic queries for DNS-SD services with cached and updated answers and user notifications
- Support for multi-homed client host domains - Support for multi-homed client host domains

File diff suppressed because it is too large Load Diff

View File

@ -11,15 +11,19 @@
A lot of the additions were basically taken from Erik Ekman's lwIP mdns app code. A lot of the additions were basically taken from Erik Ekman's lwIP mdns app code.
Supported mDNS features (in some cases somewhat limited): Supported mDNS features (in some cases somewhat limited):
- Presenting a DNS-SD service to interested observers, eg. a http server by presenting _http._tcp service - Presenting a DNS-SD service to interested observers, eg. a http server by presenting
- Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented _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 - 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 - Announcing available services after successful probing
- Using fixed service TXT items or - Using fixed service TXT items or
- Using dynamic service TXT items for presented services (via callback) - Using dynamic service TXT items for presented services (via callback)
- Remove services (and un-announcing them to the observers by sending goodbye-messages) - 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 - Dynamic queries for DNS-SD services with cached and updated answers and user notifications
@ -30,19 +34,23 @@
For presenting services: For presenting services:
In 'setup()': In 'setup()':
Install a callback for the probing of host (and service) domains via 'MDNS.setProbeResultCallback(probeResultCallback, &userData);' Install a callback for the probing of host (and service) domains via
Register DNS-SD services with 'MDNSResponder::hMDNSService hService = MDNS.addService("MyESP", "http", "tcp", 5000);' 'MDNS.setProbeResultCallback(probeResultCallback, &userData);' Register DNS-SD services with
(Install additional callbacks for the probing of these service domains via 'MDNS.setServiceProbeResultCallback(hService, probeResultCallback, &userData);') 'MDNSResponder::hMDNSService hService = MDNS.addService("MyESP", "http", "tcp", 5000);' (Install
Add service TXT items with 'MDNS.addServiceTxt(hService, "c#", "1");' or by installing a service TXT callback additional callbacks for the probing of these service domains via
using 'MDNS.setDynamicServiceTxtCallback(dynamicServiceTxtCallback, &userData);' or service specific 'MDNS.setServiceProbeResultCallback(hService, probeResultCallback, &userData);') Add service TXT
'MDNS.setDynamicServiceTxtCallback(hService, dynamicServiceTxtCallback, &userData);' items with 'MDNS.addServiceTxt(hService, "c#", "1");' or by installing a service TXT callback
using 'MDNS.setDynamicServiceTxtCallback(dynamicServiceTxtCallback, &userData);' or service
specific 'MDNS.setDynamicServiceTxtCallback(hService, dynamicServiceTxtCallback, &userData);'
Call MDNS.begin("MyHostname"); Call MDNS.begin("MyHostname");
In 'probeResultCallback(MDNSResponder* p_MDNSResponder, const char* p_pcDomain, MDNSResponder:hMDNSService p_hService, bool p_bProbeResult, void* p_pUserdata)': In 'probeResultCallback(MDNSResponder* p_MDNSResponder, const char* p_pcDomain,
Check the probe result and update the host or service domain name if the probe failed MDNSResponder:hMDNSService p_hService, bool p_bProbeResult, void* p_pUserdata)': Check the probe
result and update the host or service domain name if the probe failed
In 'dynamicServiceTxtCallback(MDNSResponder* p_MDNSResponder, const hMDNSService p_hService, void* p_pUserdata)': In 'dynamicServiceTxtCallback(MDNSResponder* p_MDNSResponder, const hMDNSService p_hService,
Add dynamic TXT items by calling 'MDNS.addDynamicServiceTxt(p_hService, "c#", "1");' void* p_pUserdata)': Add dynamic TXT items by calling 'MDNS.addDynamicServiceTxt(p_hService,
"c#", "1");'
In loop(): In loop():
Call 'MDNS.update();' Call 'MDNS.update();'
@ -51,15 +59,17 @@
For querying services: For querying services:
Static: Static:
Call 'uint32_t u32AnswerCount = MDNS.queryService("http", "tcp");' Call 'uint32_t u32AnswerCount = MDNS.queryService("http", "tcp");'
Iterate answers by: 'for (uint32_t u=0; u<u32AnswerCount; ++u) { const char* pHostname = MDNS.answerHostname(u); }' Iterate answers by: 'for (uint32_t u=0; u<u32AnswerCount; ++u) { const char* pHostname =
You should call MDNS.removeQuery() sometimes later (when the answers are not needed anymore) MDNS.answerHostname(u); }' You should call MDNS.removeQuery() sometimes later (when the answers
are not needed anymore)
Dynamic: Dynamic:
Install a dynamic query by calling 'DNSResponder::hMDNSServiceQuery hServiceQuery = MDNS.installServiceQuery("http", "tcp", serviceQueryCallback, &userData);' Install a dynamic query by calling 'DNSResponder::hMDNSServiceQuery hServiceQuery =
The callback 'serviceQueryCallback(MDNSResponder* p_MDNSResponder, const hMDNSServiceQuery p_hServiceQuery, uint32_t p_u32AnswerIndex, MDNS.installServiceQuery("http", "tcp", serviceQueryCallback, &userData);' The callback
enuServiceQueryAnswerType p_ServiceQueryAnswerType, bool p_bSetContent, void* p_pUserdata)' 'serviceQueryCallback(MDNSResponder* p_MDNSResponder, const hMDNSServiceQuery p_hServiceQuery,
is called for any change in the answer set. uint32_t p_u32AnswerIndex, enuServiceQueryAnswerType p_ServiceQueryAnswerType, bool
Call 'MDNS.removeServiceQuery(hServiceQuery);' when the answers are not needed anymore p_bSetContent, void* p_pUserdata)' is called for any change in the answer set. Call
'MDNS.removeServiceQuery(hServiceQuery);' when the answers are not needed anymore
Reference: Reference:
@ -69,9 +79,9 @@
PTR (0x0C, srv name): eg. _http._tcp.local PTR OP TTL MyESP._http._tcp.local PTR (0x0C, srv name): eg. _http._tcp.local PTR OP TTL MyESP._http._tcp.local
PTR (0x0C, srv type): eg. _services._dns-sd._udp.local PTR OP TTL _http._tcp.local PTR (0x0C, srv type): eg. _services._dns-sd._udp.local PTR OP TTL _http._tcp.local
PTR (0x0C, IP4): eg. 012.789.456.123.in-addr.arpa PTR OP TTL esp8266.local PTR (0x0C, IP4): eg. 012.789.456.123.in-addr.arpa PTR OP TTL esp8266.local
PTR (0x0C, IP6): eg. 90.0.0.0.0.0.0.0.0.0.0.0.78.56.34.12.ip6.arpa PTR OP TTL esp8266.local PTR (0x0C, IP6): eg. 90.0.0.0.0.0.0.0.0.0.0.0.78.56.34.12.ip6.arpa PTR OP TTL
SRV (0x21): eg. MyESP._http._tcp.local SRV OP TTL PRIORITY WEIGHT PORT esp8266.local esp8266.local SRV (0x21): eg. MyESP._http._tcp.local SRV OP TTL PRIORITY WEIGHT PORT
TXT (0x10): eg. MyESP._http._tcp.local TXT OP TTL c#=1 esp8266.local TXT (0x10): eg. MyESP._http._tcp.local TXT OP TTL c#=1
Some NOT used message types: Some NOT used message types:
OPT (0x29): eDNS OPT (0x29): eDNS
@ -111,10 +121,8 @@
#include <PolledTimeout.h> #include <PolledTimeout.h>
#include <map> #include <map>
#include "ESP8266WiFi.h" #include "ESP8266WiFi.h"
namespace esp8266 namespace esp8266
{ {
@ -124,7 +132,7 @@ namespace esp8266
namespace MDNSImplementation namespace MDNSImplementation
{ {
//this should be defined at build time // this should be defined at build time
#ifndef ARDUINO_BOARD #ifndef ARDUINO_BOARD
#define ARDUINO_BOARD "generic" #define ARDUINO_BOARD "generic"
#endif #endif
@ -170,12 +178,12 @@ namespace MDNSImplementation
*/ */
#define MDNS_UDPCONTEXT_TIMEOUT 50 #define MDNS_UDPCONTEXT_TIMEOUT 50
/** /**
MDNSResponder MDNSResponder
*/ */
class MDNSResponder class MDNSResponder
{ {
public: public:
/* INTERFACE */ /* INTERFACE */
MDNSResponder(void); MDNSResponder(void);
@ -185,8 +193,10 @@ public:
// Later call MDNS::update() in every 'loop' to run the process loop // Later call MDNS::update() in every 'loop' to run the process loop
// (probing, announcing, responding, ...) // (probing, announcing, responding, ...)
// if interfaceAddress is not specified, default interface is STA, or AP when STA is not set // if interfaceAddress is not specified, default interface is STA, or AP when STA is not set
bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/); bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY,
bool begin(const String& p_strHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/) uint32_t p_u32TTL = 120 /*ignored*/);
bool begin(const String& p_strHostname, const IPAddress& p_IPAddress = INADDR_ANY,
uint32_t p_u32TTL = 120 /*ignored*/)
{ {
return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL); return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);
} }
@ -212,31 +222,25 @@ public:
*/ */
typedef const void* hMDNSService; typedef const void* hMDNSService;
// Add a new service to the MDNS responder. If no name (instance name) is given (p_pcName = 0) // Add a new service to the MDNS responder. If no name (instance name) is given (p_pcName =
// the current hostname is used. If the hostname is changed later, the instance names for // 0) the current hostname is used. If the hostname is changed later, the instance names for
// these 'auto-named' services are changed to the new name also (and probing is restarted). // these 'auto-named' services are changed to the new name also (and probing is restarted).
// The usual '_' before p_pcService (eg. http) and protocol (eg. tcp) may be given. // The usual '_' before p_pcService (eg. http) and protocol (eg. tcp) may be given.
hMDNSService addService(const char* p_pcName, hMDNSService addService(const char* p_pcName, const char* p_pcService,
const char* p_pcService, const char* p_pcProtocol, uint16_t p_u16Port);
const char* p_pcProtocol,
uint16_t p_u16Port);
// Removes a service from the MDNS responder // Removes a service from the MDNS responder
bool removeService(const hMDNSService p_hService); bool removeService(const hMDNSService p_hService);
bool removeService(const char* p_pcInstanceName, bool removeService(const char* p_pcInstanceName, const char* p_pcServiceName,
const char* p_pcServiceName,
const char* p_pcProtocol); const char* p_pcProtocol);
// for compatibility... // for compatibility...
bool addService(const String& p_strServiceName, bool addService(const String& p_strServiceName, const String& p_strProtocol,
const String& p_strProtocol,
uint16_t p_u16Port); uint16_t p_u16Port);
// Change the services instance name (and restart probing). // Change the services instance name (and restart probing).
bool setServiceName(const hMDNSService p_hService, bool setServiceName(const hMDNSService p_hService, const char* p_pcInstanceName);
const char* p_pcInstanceName); // for compatibility
//for compatibility // Warning: this has the side effect of changing the hostname.
//Warning: this has the side effect of changing the hostname. // TODO: implement instancename different from hostname
//TODO: implement instancename different from hostname
void setInstanceName(const char* p_pcHostname) void setInstanceName(const char* p_pcHostname)
{ {
setHostname(p_pcHostname); setHostname(p_pcHostname);
@ -253,53 +257,39 @@ public:
typedef void* hMDNSTxt; typedef void* hMDNSTxt;
// Add a (static) MDNS TXT item ('key' = 'value') to the service // Add a (static) MDNS TXT item ('key' = 'value') to the service
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
const char* p_pcValue); const char* p_pcValue);
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
uint32_t p_u32Value); uint32_t p_u32Value);
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
uint16_t p_u16Value); uint16_t p_u16Value);
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
uint8_t p_u8Value); uint8_t p_u8Value);
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
int32_t p_i32Value); int32_t p_i32Value);
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
int16_t p_i16Value); int16_t p_i16Value);
hMDNSTxt addServiceTxt(const hMDNSService p_hService, hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
int8_t p_i8Value); int8_t p_i8Value);
// Remove an existing (static) MDNS TXT item from the service // Remove an existing (static) MDNS TXT item from the service
bool removeServiceTxt(const hMDNSService p_hService, bool removeServiceTxt(const hMDNSService p_hService, const hMDNSTxt p_hTxt);
const hMDNSTxt p_hTxt); bool removeServiceTxt(const hMDNSService p_hService, const char* p_pcKey);
bool removeServiceTxt(const hMDNSService p_hService, bool removeServiceTxt(const char* p_pcinstanceName, const char* p_pcServiceName,
const char* p_pcKey); const char* p_pcProtocol, const char* p_pcKey);
bool removeServiceTxt(const char* p_pcinstanceName,
const char* p_pcServiceName,
const char* p_pcProtocol,
const char* p_pcKey);
// for compatibility... // for compatibility...
bool addServiceTxt(const char* p_pcService, bool addServiceTxt(const char* p_pcService, const char* p_pcProtocol, const char* p_pcKey,
const char* p_pcProtocol,
const char* p_pcKey,
const char* p_pcValue); const char* p_pcValue);
bool addServiceTxt(const String& p_strService, bool addServiceTxt(const String& p_strService, const String& p_strProtocol,
const String& p_strProtocol, const String& p_strKey, const String& p_strValue);
const String& p_strKey,
const String& p_strValue);
/** /**
MDNSDynamicServiceTxtCallbackFn MDNSDynamicServiceTxtCallbackFn
Callback function for dynamic MDNS TXT items Callback function for dynamic MDNS TXT items
*/ */
typedef std::function<void(const hMDNSService p_hService)> MDNSDynamicServiceTxtCallbackFunc; typedef std::function<void(const hMDNSService p_hService)>
MDNSDynamicServiceTxtCallbackFunc;
// Set a global callback for dynamic MDNS TXT items. The callback function is called // Set a global callback for dynamic MDNS TXT items. The callback function is called
// every time, a TXT item is needed for one of the installed services. // every time, a TXT item is needed for one of the installed services.
@ -312,26 +302,19 @@ public:
// Add a (dynamic) MDNS TXT item ('key' = 'value') to the service // Add a (dynamic) MDNS TXT item ('key' = 'value') to the service
// Dynamic TXT items are removed right after one-time use. So they need to be added // Dynamic TXT items are removed right after one-time use. So they need to be added
// every time the value s needed (via callback). // every time the value s needed (via callback).
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
const char* p_pcValue); const char* p_pcValue);
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
uint32_t p_u32Value); uint32_t p_u32Value);
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
uint16_t p_u16Value); uint16_t p_u16Value);
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
uint8_t p_u8Value); uint8_t p_u8Value);
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
int32_t p_i32Value); int32_t p_i32Value);
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
int16_t p_i16Value); int16_t p_i16Value);
hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey,
const char* p_pcKey,
int8_t p_i8Value); int8_t p_i8Value);
// Perform a (static) service query. The function returns after p_u16Timeout milliseconds // Perform a (static) service query. The function returns after p_u16Timeout milliseconds
@ -339,13 +322,11 @@ public:
// - answerHostname (or hostname) // - answerHostname (or hostname)
// - answerIP (or IP) // - answerIP (or IP)
// - answerPort (or port) // - answerPort (or port)
uint32_t queryService(const char* p_pcService, uint32_t queryService(const char* p_pcService, const char* p_pcProtocol,
const char* p_pcProtocol,
const uint16_t p_u16Timeout = MDNS_QUERYSERVICES_WAIT_TIME); const uint16_t p_u16Timeout = MDNS_QUERYSERVICES_WAIT_TIME);
bool removeQuery(void); bool removeQuery(void);
// for compatibility... // for compatibility...
uint32_t queryService(const String& p_strService, uint32_t queryService(const String& p_strService, const String& p_strProtocol);
const String& p_strProtocol);
const char* answerHostname(const uint32_t p_u32AnswerIndex); const char* answerHostname(const uint32_t p_u32AnswerIndex);
IPAddress answerIP(const uint32_t p_u32AnswerIndex); IPAddress answerIP(const uint32_t p_u32AnswerIndex);
@ -395,10 +376,12 @@ public:
Callback function for received answers for dynamic service queries Callback function for received answers for dynamic service queries
*/ */
struct MDNSServiceInfo; // forward declaration struct MDNSServiceInfo; // forward declaration
typedef std::function<void(const MDNSServiceInfo& mdnsServiceInfo, typedef std::function<void(
const MDNSServiceInfo& mdnsServiceInfo,
AnswerType answerType, // flag for the updated answer item AnswerType answerType, // flag for the updated answer item
bool p_bSetContent // true: Answer component set, false: component deleted bool p_bSetContent // true: Answer component set, false: component deleted
)> MDNSServiceQueryCallbackFunc; )>
MDNSServiceQueryCallbackFunc;
// Install a dynamic service query. For every received answer (part) the given callback // Install a dynamic service query. For every received answer (part) the given callback
// function is called. The query will be updated every time, the TTL for an answer // function is called. The query will be updated every time, the TTL for an answer
@ -411,14 +394,14 @@ public:
// - hasAnswerIP6Address/answerIP6Address // - hasAnswerIP6Address/answerIP6Address
// - hasAnswerPort/answerPort // - hasAnswerPort/answerPort
// - hasAnswerTxts/answerTxts // - hasAnswerTxts/answerTxts
hMDNSServiceQuery installServiceQuery(const char* p_pcService, hMDNSServiceQuery installServiceQuery(const char* p_pcService, const char* p_pcProtocol,
const char* p_pcProtocol,
MDNSServiceQueryCallbackFunc p_fnCallback); MDNSServiceQueryCallbackFunc p_fnCallback);
// Remove a dynamic service query // Remove a dynamic service query
bool removeServiceQuery(hMDNSServiceQuery p_hServiceQuery); bool removeServiceQuery(hMDNSServiceQuery p_hServiceQuery);
uint32_t answerCount(const hMDNSServiceQuery p_hServiceQuery); uint32_t answerCount(const hMDNSServiceQuery p_hServiceQuery);
std::vector<MDNSResponder::MDNSServiceInfo> answerInfo(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery); std::vector<MDNSResponder::MDNSServiceInfo>
answerInfo(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery);
const char* answerServiceDomain(const hMDNSServiceQuery p_hServiceQuery, const char* answerServiceDomain(const hMDNSServiceQuery p_hServiceQuery,
const uint32_t p_u32AnswerIndex); const uint32_t p_u32AnswerIndex);
@ -458,21 +441,20 @@ public:
MDNSProbeResultCallbackFn MDNSProbeResultCallbackFn
Callback function for (host and service domain) probe results Callback function for (host and service domain) probe results
*/ */
typedef std::function<void(const char* p_pcDomainName, typedef std::function<void(const char* p_pcDomainName, bool p_bProbeResult)>
bool p_bProbeResult)> MDNSHostProbeFn; MDNSHostProbeFn;
typedef std::function<void(MDNSResponder& resp, typedef std::function<void(MDNSResponder& resp, const char* p_pcDomainName,
const char* p_pcDomainName, bool p_bProbeResult)>
bool p_bProbeResult)> MDNSHostProbeFn1; MDNSHostProbeFn1;
typedef std::function<void(const char* p_pcServiceName, typedef std::function<void(const char* p_pcServiceName, const hMDNSService p_hMDNSService,
const hMDNSService p_hMDNSService, bool p_bProbeResult)>
bool p_bProbeResult)> MDNSServiceProbeFn; MDNSServiceProbeFn;
typedef std::function<void(MDNSResponder& resp, typedef std::function<void(MDNSResponder& resp, const char* p_pcServiceName,
const char* p_pcServiceName, const hMDNSService p_hMDNSService, bool p_bProbeResult)>
const hMDNSService p_hMDNSService, MDNSServiceProbeFn1;
bool p_bProbeResult)> MDNSServiceProbeFn1;
// Set a global callback function for host and service probe results // Set a global callback function for host and service probe results
// The callback function is called, when the probing for the host domain // The callback function is called, when the probing for the host domain
@ -499,40 +481,39 @@ public:
bool announce(void); bool announce(void);
// Enable OTA update // Enable OTA update
hMDNSService enableArduino(uint16_t p_u16Port, hMDNSService enableArduino(uint16_t p_u16Port, bool p_bAuthUpload = false);
bool p_bAuthUpload = false);
// Domain name helper // Domain name helper
static bool indexDomain(char*& p_rpcDomain, static bool indexDomain(char*& p_rpcDomain, const char* p_pcDivider = "-",
const char* p_pcDivider = "-",
const char* p_pcDefaultDomain = 0); const char* p_pcDefaultDomain = 0);
/** STRUCTS **/ /** STRUCTS **/
public: public:
/** /**
MDNSServiceInfo, used in application callbacks MDNSServiceInfo, used in application callbacks
*/ */
struct MDNSServiceInfo struct MDNSServiceInfo
{ {
MDNSServiceInfo(MDNSResponder& p_pM, MDNSResponder::hMDNSServiceQuery p_hS, uint32_t p_u32A) MDNSServiceInfo(MDNSResponder& p_pM, MDNSResponder::hMDNSServiceQuery p_hS,
: p_pMDNSResponder(p_pM), uint32_t p_u32A) :
p_hServiceQuery(p_hS), p_pMDNSResponder(p_pM),
p_u32AnswerIndex(p_u32A) p_hServiceQuery(p_hS), p_u32AnswerIndex(p_u32A) {};
{};
struct CompareKey struct CompareKey
{ {
bool operator()(char const *a, char const *b) const bool operator()(char const* a, char const* b) const
{ {
return strcmp(a, b) < 0; return strcmp(a, b) < 0;
} }
}; };
using KeyValueMap = std::map<const char*, const char*, CompareKey>; using KeyValueMap = std::map<const char*, const char*, CompareKey>;
protected: protected:
MDNSResponder& p_pMDNSResponder; MDNSResponder& p_pMDNSResponder;
MDNSResponder::hMDNSServiceQuery p_hServiceQuery; MDNSResponder::hMDNSServiceQuery p_hServiceQuery;
uint32_t p_u32AnswerIndex; uint32_t p_u32AnswerIndex;
KeyValueMap keyValueMap; KeyValueMap keyValueMap;
public: public:
const char* serviceDomain() const char* serviceDomain()
{ {
@ -544,8 +525,9 @@ public:
} }
const char* hostDomain() const char* hostDomain()
{ {
return (hostDomainAvailable()) ? return (hostDomainAvailable())
p_pMDNSResponder.answerHostDomain(p_hServiceQuery, p_u32AnswerIndex) : nullptr; ? p_pMDNSResponder.answerHostDomain(p_hServiceQuery, p_u32AnswerIndex)
: nullptr;
}; };
bool hostPortAvailable() bool hostPortAvailable()
{ {
@ -553,8 +535,9 @@ public:
} }
uint16_t hostPort() uint16_t hostPort()
{ {
return (hostPortAvailable()) ? return (hostPortAvailable())
p_pMDNSResponder.answerPort(p_hServiceQuery, p_u32AnswerIndex) : 0; ? p_pMDNSResponder.answerPort(p_hServiceQuery, p_u32AnswerIndex)
: 0;
}; };
bool IP4AddressAvailable() bool IP4AddressAvailable()
{ {
@ -565,10 +548,12 @@ public:
std::vector<IPAddress> internalIP; std::vector<IPAddress> internalIP;
if (IP4AddressAvailable()) if (IP4AddressAvailable())
{ {
uint16_t cntIP4Adress = p_pMDNSResponder.answerIP4AddressCount(p_hServiceQuery, p_u32AnswerIndex); uint16_t cntIP4Adress
= p_pMDNSResponder.answerIP4AddressCount(p_hServiceQuery, p_u32AnswerIndex);
for (uint32_t u2 = 0; u2 < cntIP4Adress; ++u2) for (uint32_t u2 = 0; u2 < cntIP4Adress; ++u2)
{ {
internalIP.emplace_back(p_pMDNSResponder.answerIP4Address(p_hServiceQuery, p_u32AnswerIndex, u2)); internalIP.emplace_back(p_pMDNSResponder.answerIP4Address(
p_hServiceQuery, p_u32AnswerIndex, u2));
} }
} }
return internalIP; return internalIP;
@ -579,16 +564,20 @@ public:
} }
const char* strKeyValue() const char* strKeyValue()
{ {
return (txtAvailable()) ? return (txtAvailable())
p_pMDNSResponder.answerTxts(p_hServiceQuery, p_u32AnswerIndex) : nullptr; ? p_pMDNSResponder.answerTxts(p_hServiceQuery, p_u32AnswerIndex)
: nullptr;
}; };
const KeyValueMap& keyValues() const KeyValueMap& keyValues()
{ {
if (txtAvailable() && keyValueMap.size() == 0) if (txtAvailable() && keyValueMap.size() == 0)
{ {
for (auto kv = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); kv != nullptr; kv = kv->m_pNext) for (auto kv
= p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex);
kv != nullptr; kv = kv->m_pNext)
{ {
keyValueMap.emplace(std::pair<const char*, const char*>(kv->m_pcKey, kv->m_pcValue)); keyValueMap.emplace(
std::pair<const char*, const char*>(kv->m_pcKey, kv->m_pcValue));
} }
} }
return keyValueMap; return keyValueMap;
@ -597,10 +586,11 @@ public:
{ {
char* result = nullptr; char* result = nullptr;
for (stcMDNSServiceTxt* pTxt = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); pTxt; pTxt = pTxt->m_pNext) for (stcMDNSServiceTxt* pTxt
= p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex);
pTxt; pTxt = pTxt->m_pNext)
{ {
if ((key) && if ((key) && (0 == strcmp(pTxt->m_pcKey, key)))
(0 == strcmp(pTxt->m_pcKey, key)))
{ {
result = pTxt->m_pcValue; result = pTxt->m_pcValue;
break; break;
@ -609,8 +599,8 @@ public:
return result; return result;
} }
}; };
protected:
protected:
/** /**
stcMDNSServiceTxt stcMDNSServiceTxt
*/ */
@ -621,8 +611,7 @@ protected:
char* m_pcValue; char* m_pcValue;
bool m_bTemp; bool m_bTemp;
stcMDNSServiceTxt(const char* p_pcKey = 0, stcMDNSServiceTxt(const char* p_pcKey = 0, const char* p_pcValue = 0,
const char* p_pcValue = 0,
bool p_bTemp = false); bool p_bTemp = false);
stcMDNSServiceTxt(const stcMDNSServiceTxt& p_Other); stcMDNSServiceTxt(const stcMDNSServiceTxt& p_Other);
~stcMDNSServiceTxt(void); ~stcMDNSServiceTxt(void);
@ -631,20 +620,16 @@ protected:
bool clear(void); bool clear(void);
char* allocKey(size_t p_stLength); char* allocKey(size_t p_stLength);
bool setKey(const char* p_pcKey, bool setKey(const char* p_pcKey, size_t p_stLength);
size_t p_stLength);
bool setKey(const char* p_pcKey); bool setKey(const char* p_pcKey);
bool releaseKey(void); bool releaseKey(void);
char* allocValue(size_t p_stLength); char* allocValue(size_t p_stLength);
bool setValue(const char* p_pcValue, bool setValue(const char* p_pcValue, size_t p_stLength);
size_t p_stLength);
bool setValue(const char* p_pcValue); bool setValue(const char* p_pcValue);
bool releaseValue(void); bool releaseValue(void);
bool set(const char* p_pcKey, bool set(const char* p_pcKey, const char* p_pcValue, bool p_bTemp = false);
const char* p_pcValue,
bool p_bTemp = false);
bool update(const char* p_pcValue); bool update(const char* p_pcValue);
@ -724,18 +709,11 @@ protected:
uint16_t m_u16NSCount; // Authority Record count uint16_t m_u16NSCount; // Authority Record count
uint16_t m_u16ARCount; // Additional Record count uint16_t m_u16ARCount; // Additional Record count
stcMDNS_MsgHeader(uint16_t p_u16ID = 0, stcMDNS_MsgHeader(uint16_t p_u16ID = 0, bool p_bQR = false,
bool p_bQR = false, unsigned char p_ucOpcode = 0, bool p_bAA = false, bool p_bTC = false,
unsigned char p_ucOpcode = 0, bool p_bRD = false, bool p_bRA = false, unsigned char p_ucRCode = 0,
bool p_bAA = false, uint16_t p_u16QDCount = 0, uint16_t p_u16ANCount = 0,
bool p_bTC = false, uint16_t p_u16NSCount = 0, uint16_t p_u16ARCount = 0);
bool p_bRD = false,
bool p_bRA = false,
unsigned char p_ucRCode = 0,
uint16_t p_u16QDCount = 0,
uint16_t p_u16ANCount = 0,
uint16_t p_u16NSCount = 0,
uint16_t p_u16ARCount = 0);
}; };
/** /**
@ -753,8 +731,7 @@ protected:
bool clear(void); bool clear(void);
bool addLabel(const char* p_pcLabel, bool addLabel(const char* p_pcLabel, bool p_bPrependUnderline = false);
bool p_bPrependUnderline = false);
bool compare(const stcMDNS_RRDomain& p_Other) const; bool compare(const stcMDNS_RRDomain& p_Other) const;
bool operator==(const stcMDNS_RRDomain& p_Other) const; bool operator==(const stcMDNS_RRDomain& p_Other) const;
@ -839,8 +816,7 @@ protected:
bool clear(void); bool clear(void);
protected: protected:
stcMDNS_RRAnswer(enuAnswerType p_AnswerType, stcMDNS_RRAnswer(enuAnswerType p_AnswerType, const stcMDNS_RRHeader& p_Header,
const stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL); uint32_t p_u32TTL);
}; };
@ -848,12 +824,11 @@ protected:
/** /**
stcMDNS_RRAnswerA stcMDNS_RRAnswerA
*/ */
struct stcMDNS_RRAnswerA : public stcMDNS_RRAnswer struct stcMDNS_RRAnswerA: public stcMDNS_RRAnswer
{ {
IPAddress m_IPAddress; IPAddress m_IPAddress;
stcMDNS_RRAnswerA(const stcMDNS_RRHeader& p_Header, stcMDNS_RRAnswerA(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL);
uint32_t p_u32TTL);
~stcMDNS_RRAnswerA(void); ~stcMDNS_RRAnswerA(void);
bool clear(void); bool clear(void);
@ -863,12 +838,11 @@ protected:
/** /**
stcMDNS_RRAnswerPTR stcMDNS_RRAnswerPTR
*/ */
struct stcMDNS_RRAnswerPTR : public stcMDNS_RRAnswer struct stcMDNS_RRAnswerPTR: public stcMDNS_RRAnswer
{ {
stcMDNS_RRDomain m_PTRDomain; stcMDNS_RRDomain m_PTRDomain;
stcMDNS_RRAnswerPTR(const stcMDNS_RRHeader& p_Header, stcMDNS_RRAnswerPTR(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL);
uint32_t p_u32TTL);
~stcMDNS_RRAnswerPTR(void); ~stcMDNS_RRAnswerPTR(void);
bool clear(void); bool clear(void);
@ -877,12 +851,11 @@ protected:
/** /**
stcMDNS_RRAnswerTXT stcMDNS_RRAnswerTXT
*/ */
struct stcMDNS_RRAnswerTXT : public stcMDNS_RRAnswer struct stcMDNS_RRAnswerTXT: public stcMDNS_RRAnswer
{ {
stcMDNSServiceTxts m_Txts; stcMDNSServiceTxts m_Txts;
stcMDNS_RRAnswerTXT(const stcMDNS_RRHeader& p_Header, stcMDNS_RRAnswerTXT(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL);
uint32_t p_u32TTL);
~stcMDNS_RRAnswerTXT(void); ~stcMDNS_RRAnswerTXT(void);
bool clear(void); bool clear(void);
@ -892,12 +865,11 @@ protected:
/** /**
stcMDNS_RRAnswerAAAA stcMDNS_RRAnswerAAAA
*/ */
struct stcMDNS_RRAnswerAAAA : public stcMDNS_RRAnswer struct stcMDNS_RRAnswerAAAA: public stcMDNS_RRAnswer
{ {
//TODO: IP6Address m_IPAddress; // TODO: IP6Address m_IPAddress;
stcMDNS_RRAnswerAAAA(const stcMDNS_RRHeader& p_Header, stcMDNS_RRAnswerAAAA(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL);
uint32_t p_u32TTL);
~stcMDNS_RRAnswerAAAA(void); ~stcMDNS_RRAnswerAAAA(void);
bool clear(void); bool clear(void);
@ -907,15 +879,14 @@ protected:
/** /**
stcMDNS_RRAnswerSRV stcMDNS_RRAnswerSRV
*/ */
struct stcMDNS_RRAnswerSRV : public stcMDNS_RRAnswer struct stcMDNS_RRAnswerSRV: public stcMDNS_RRAnswer
{ {
uint16_t m_u16Priority; uint16_t m_u16Priority;
uint16_t m_u16Weight; uint16_t m_u16Weight;
uint16_t m_u16Port; uint16_t m_u16Port;
stcMDNS_RRDomain m_SRVDomain; stcMDNS_RRDomain m_SRVDomain;
stcMDNS_RRAnswerSRV(const stcMDNS_RRHeader& p_Header, stcMDNS_RRAnswerSRV(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL);
uint32_t p_u32TTL);
~stcMDNS_RRAnswerSRV(void); ~stcMDNS_RRAnswerSRV(void);
bool clear(void); bool clear(void);
@ -924,19 +895,17 @@ protected:
/** /**
stcMDNS_RRAnswerGeneric stcMDNS_RRAnswerGeneric
*/ */
struct stcMDNS_RRAnswerGeneric : public stcMDNS_RRAnswer struct stcMDNS_RRAnswerGeneric: public stcMDNS_RRAnswer
{ {
uint16_t m_u16RDLength; // Length of variable answer uint16_t m_u16RDLength; // Length of variable answer
uint8_t* m_pu8RDData; // Offset of start of variable answer in packet uint8_t* m_pu8RDData; // Offset of start of variable answer in packet
stcMDNS_RRAnswerGeneric(const stcMDNS_RRHeader& p_Header, stcMDNS_RRAnswerGeneric(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL);
uint32_t p_u32TTL);
~stcMDNS_RRAnswerGeneric(void); ~stcMDNS_RRAnswerGeneric(void);
bool clear(void); bool clear(void);
}; };
/** /**
enuProbingStatus enuProbingStatus
*/ */
@ -956,7 +925,8 @@ protected:
enuProbingStatus m_ProbingStatus; enuProbingStatus m_ProbingStatus;
uint8_t m_u8SentCount; // Used for probes and announcements uint8_t m_u8SentCount; // Used for probes and announcements
esp8266::polledTimeout::oneShotMs m_Timeout; // Used for probes and announcements esp8266::polledTimeout::oneShotMs m_Timeout; // Used for probes and announcements
//clsMDNSTimeFlag m_TimeFlag; // Used for probes and announcements // clsMDNSTimeFlag m_TimeFlag; // Used for probes and
// announcements
bool m_bConflict; bool m_bConflict;
bool m_bTiebreakNeeded; bool m_bTiebreakNeeded;
MDNSHostProbeFn m_fnHostProbeResultCallback; MDNSHostProbeFn m_fnHostProbeResultCallback;
@ -967,7 +937,6 @@ protected:
bool clear(bool p_bClearUserdata = false); bool clear(bool p_bClearUserdata = false);
}; };
/** /**
stcMDNSService stcMDNSService
*/ */
@ -984,8 +953,7 @@ protected:
MDNSDynamicServiceTxtCallbackFunc m_fnTxtCallback; MDNSDynamicServiceTxtCallbackFunc m_fnTxtCallback;
stcProbeInformation m_ProbeInformation; stcProbeInformation m_ProbeInformation;
stcMDNSService(const char* p_pcName = 0, stcMDNSService(const char* p_pcName = 0, const char* p_pcService = 0,
const char* p_pcService = 0,
const char* p_pcProtocol = 0); const char* p_pcProtocol = 0);
~stcMDNSService(void); ~stcMDNSService(void);
@ -1053,8 +1021,7 @@ protected:
IPAddress m_IPAddress; IPAddress m_IPAddress;
stcTTL m_TTL; stcTTL m_TTL;
stcIP4Address(IPAddress p_IPAddress, stcIP4Address(IPAddress p_IPAddress, uint32_t p_u32TTL = 0);
uint32_t p_u32TTL = 0);
}; };
#endif #endif
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT
@ -1067,18 +1034,19 @@ protected:
IP6Address m_IPAddress; IP6Address m_IPAddress;
stcTTL m_TTL; stcTTL m_TTL;
stcIP6Address(IPAddress p_IPAddress, stcIP6Address(IPAddress p_IPAddress, uint32_t p_u32TTL = 0);
uint32_t p_u32TTL = 0);
}; };
#endif #endif
stcAnswer* m_pNext; stcAnswer* m_pNext;
// The service domain is the first 'answer' (from PTR answer, using service and protocol) to be set // The service domain is the first 'answer' (from PTR answer, using service and
// Defines the key for additional answer, like host domain, etc. // protocol) to be set Defines the key for additional answer, like host domain, etc.
stcMDNS_RRDomain m_ServiceDomain; // 1. level answer (PTR), eg. MyESP._http._tcp.local stcMDNS_RRDomain
m_ServiceDomain; // 1. level answer (PTR), eg. MyESP._http._tcp.local
char* m_pcServiceDomain; char* m_pcServiceDomain;
stcTTL m_TTLServiceDomain; stcTTL m_TTLServiceDomain;
stcMDNS_RRDomain m_HostDomain; // 2. level answer (SRV, using service domain), eg. esp8266.local stcMDNS_RRDomain
m_HostDomain; // 2. level answer (SRV, using service domain), eg. esp8266.local
char* m_pcHostDomain; char* m_pcHostDomain;
uint16_t m_u16Port; // 2. level answer (SRV, using service domain), eg. 5000 uint16_t m_u16Port; // 2. level answer (SRV, using service domain), eg. 5000
stcTTL m_TTLHostDomainAndPort; stcTTL m_TTLHostDomainAndPort;
@ -1086,10 +1054,12 @@ protected:
char* m_pcTxts; char* m_pcTxts;
stcTTL m_TTLTxts; stcTTL m_TTLTxts;
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
stcIP4Address* m_pIP4Addresses; // 3. level answer (A, using host domain), eg. 123.456.789.012 stcIP4Address*
m_pIP4Addresses; // 3. level answer (A, using host domain), eg. 123.456.789.012
#endif #endif
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT
stcIP6Address* m_pIP6Addresses; // 3. level answer (AAAA, using host domain), eg. 1234::09 stcIP6Address*
m_pIP6Addresses; // 3. level answer (AAAA, using host domain), eg. 1234::09
#endif #endif
uint32_t m_u32ContentFlags; uint32_t m_u32ContentFlags;
@ -1171,8 +1141,7 @@ protected:
bool m_bAdditionalData; // Opaque flag for special info (service domain included) bool m_bAdditionalData; // Opaque flag for special info (service domain included)
uint16_t m_u16Offset; // Offset in UDP output buffer uint16_t m_u16Offset; // Offset in UDP output buffer
stcDomainCacheItem(const void* p_pHostnameOrService, stcDomainCacheItem(const void* p_pHostnameOrService, bool p_bAdditionalData,
bool p_bAdditionalData,
uint32_t p_u16Offset); uint32_t p_u16Offset);
}; };
@ -1197,8 +1166,7 @@ protected:
bool shiftOffset(uint16_t p_u16Shift); bool shiftOffset(uint16_t p_u16Shift);
bool addDomainCacheItem(const void* p_pHostnameOrService, bool addDomainCacheItem(const void* p_pHostnameOrService, bool p_bAdditionalData,
bool p_bAdditionalData,
uint16_t p_u16Offset); uint16_t p_u16Offset);
uint16_t findCachedDomainOffset(const void* p_pHostnameOrService, uint16_t findCachedDomainOffset(const void* p_pHostnameOrService,
bool p_bAdditionalData) const; bool p_bAdditionalData) const;
@ -1245,10 +1213,8 @@ protected:
bool _cancelProbingForService(stcMDNSService& p_rService); bool _cancelProbingForService(stcMDNSService& p_rService);
/* ANNOUNCE */ /* ANNOUNCE */
bool _announce(bool p_bAnnounce, bool _announce(bool p_bAnnounce, bool p_bIncludeServices);
bool p_bIncludeServices); bool _announceService(stcMDNSService& p_rService, bool p_bAnnounce = true);
bool _announceService(stcMDNSService& p_rService,
bool p_bAnnounce = true);
/* SERVICE QUERY CACHE */ /* SERVICE QUERY CACHE */
bool _hasServiceQueriesWaitingForAnswers(void) const; bool _hasServiceQueriesWaitingForAnswers(void) const;
@ -1258,11 +1224,9 @@ protected:
/* SENDING */ /* SENDING */
bool _sendMDNSMessage(stcMDNSSendParameter& p_SendParameter); bool _sendMDNSMessage(stcMDNSSendParameter& p_SendParameter);
bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter); bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter);
bool _prepareMDNSMessage(stcMDNSSendParameter& p_SendParameter, bool _prepareMDNSMessage(stcMDNSSendParameter& p_SendParameter, IPAddress p_IPAddress);
IPAddress p_IPAddress);
bool _sendMDNSServiceQuery(const stcMDNSServiceQuery& p_ServiceQuery); bool _sendMDNSServiceQuery(const stcMDNSServiceQuery& p_ServiceQuery);
bool _sendMDNSQuery(const stcMDNS_RRDomain& p_QueryDomain, bool _sendMDNSQuery(const stcMDNS_RRDomain& p_QueryDomain, uint16_t p_u16QueryType,
uint16_t p_u16QueryType,
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0); stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader, uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
@ -1275,37 +1239,28 @@ protected:
bool _readRRQuestion(stcMDNS_RRQuestion& p_rQuestion); bool _readRRQuestion(stcMDNS_RRQuestion& p_rQuestion);
bool _readRRAnswer(stcMDNS_RRAnswer*& p_rpAnswer); bool _readRRAnswer(stcMDNS_RRAnswer*& p_rpAnswer);
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
bool _readRRAnswerA(stcMDNS_RRAnswerA& p_rRRAnswerA, bool _readRRAnswerA(stcMDNS_RRAnswerA& p_rRRAnswerA, uint16_t p_u16RDLength);
uint16_t p_u16RDLength);
#endif #endif
bool _readRRAnswerPTR(stcMDNS_RRAnswerPTR& p_rRRAnswerPTR, bool _readRRAnswerPTR(stcMDNS_RRAnswerPTR& p_rRRAnswerPTR, uint16_t p_u16RDLength);
uint16_t p_u16RDLength); bool _readRRAnswerTXT(stcMDNS_RRAnswerTXT& p_rRRAnswerTXT, uint16_t p_u16RDLength);
bool _readRRAnswerTXT(stcMDNS_RRAnswerTXT& p_rRRAnswerTXT,
uint16_t p_u16RDLength);
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT
bool _readRRAnswerAAAA(stcMDNS_RRAnswerAAAA& p_rRRAnswerAAAA, bool _readRRAnswerAAAA(stcMDNS_RRAnswerAAAA& p_rRRAnswerAAAA, uint16_t p_u16RDLength);
uint16_t p_u16RDLength);
#endif #endif
bool _readRRAnswerSRV(stcMDNS_RRAnswerSRV& p_rRRAnswerSRV, bool _readRRAnswerSRV(stcMDNS_RRAnswerSRV& p_rRRAnswerSRV, uint16_t p_u16RDLength);
uint16_t p_u16RDLength);
bool _readRRAnswerGeneric(stcMDNS_RRAnswerGeneric& p_rRRAnswerGeneric, bool _readRRAnswerGeneric(stcMDNS_RRAnswerGeneric& p_rRRAnswerGeneric,
uint16_t p_u16RDLength); uint16_t p_u16RDLength);
bool _readRRHeader(stcMDNS_RRHeader& p_rHeader); bool _readRRHeader(stcMDNS_RRHeader& p_rHeader);
bool _readRRDomain(stcMDNS_RRDomain& p_rRRDomain); bool _readRRDomain(stcMDNS_RRDomain& p_rRRDomain);
bool _readRRDomain_Loop(stcMDNS_RRDomain& p_rRRDomain, bool _readRRDomain_Loop(stcMDNS_RRDomain& p_rRRDomain, uint8_t p_u8Depth);
uint8_t p_u8Depth);
bool _readRRAttributes(stcMDNS_RRAttributes& p_rAttributes); bool _readRRAttributes(stcMDNS_RRAttributes& p_rAttributes);
/* DOMAIN NAMES */ /* DOMAIN NAMES */
bool _buildDomainForHost(const char* p_pcHostname, bool _buildDomainForHost(const char* p_pcHostname, stcMDNS_RRDomain& p_rHostDomain) const;
stcMDNS_RRDomain& p_rHostDomain) const;
bool _buildDomainForDNSSD(stcMDNS_RRDomain& p_rDNSSDDomain) const; bool _buildDomainForDNSSD(stcMDNS_RRDomain& p_rDNSSDDomain) const;
bool _buildDomainForService(const stcMDNSService& p_Service, bool _buildDomainForService(const stcMDNSService& p_Service, bool p_bIncludeName,
bool p_bIncludeName,
stcMDNS_RRDomain& p_rServiceDomain) const; stcMDNS_RRDomain& p_rServiceDomain) const;
bool _buildDomainForService(const char* p_pcService, bool _buildDomainForService(const char* p_pcService, const char* p_pcProtocol,
const char* p_pcProtocol,
stcMDNS_RRDomain& p_rServiceDomain) const; stcMDNS_RRDomain& p_rServiceDomain) const;
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
bool _buildDomainForReverseIP4(IPAddress p_IP4Address, bool _buildDomainForReverseIP4(IPAddress p_IP4Address,
@ -1317,33 +1272,27 @@ protected:
#endif #endif
/* UDP */ /* UDP */
bool _udpReadBuffer(unsigned char* p_pBuffer, bool _udpReadBuffer(unsigned char* p_pBuffer, size_t p_stLength);
size_t p_stLength);
bool _udpRead8(uint8_t& p_ru8Value); bool _udpRead8(uint8_t& p_ru8Value);
bool _udpRead16(uint16_t& p_ru16Value); bool _udpRead16(uint16_t& p_ru16Value);
bool _udpRead32(uint32_t& p_ru32Value); bool _udpRead32(uint32_t& p_ru32Value);
bool _udpAppendBuffer(const unsigned char* p_pcBuffer, bool _udpAppendBuffer(const unsigned char* p_pcBuffer, size_t p_stLength);
size_t p_stLength);
bool _udpAppend8(uint8_t p_u8Value); bool _udpAppend8(uint8_t p_u8Value);
bool _udpAppend16(uint16_t p_u16Value); bool _udpAppend16(uint16_t p_u16Value);
bool _udpAppend32(uint32_t p_u32Value); bool _udpAppend32(uint32_t p_u32Value);
#if not defined ESP_8266_MDNS_INCLUDE || defined DEBUG_ESP_MDNS_RESPONDER #if not defined ESP_8266_MDNS_INCLUDE || defined DEBUG_ESP_MDNS_RESPONDER
bool _udpDump(bool p_bMovePointer = false); bool _udpDump(bool p_bMovePointer = false);
bool _udpDump(unsigned p_uOffset, bool _udpDump(unsigned p_uOffset, unsigned p_uLength);
unsigned p_uLength);
#endif #endif
/* READ/WRITE MDNS STRUCTS */ /* READ/WRITE MDNS STRUCTS */
bool _readMDNSMsgHeader(stcMDNS_MsgHeader& p_rMsgHeader); bool _readMDNSMsgHeader(stcMDNS_MsgHeader& p_rMsgHeader);
bool _write8(uint8_t p_u8Value, bool _write8(uint8_t p_u8Value, stcMDNSSendParameter& p_rSendParameter);
stcMDNSSendParameter& p_rSendParameter); bool _write16(uint16_t p_u16Value, stcMDNSSendParameter& p_rSendParameter);
bool _write16(uint16_t p_u16Value, bool _write32(uint32_t p_u32Value, stcMDNSSendParameter& p_rSendParameter);
stcMDNSSendParameter& p_rSendParameter);
bool _write32(uint32_t p_u32Value,
stcMDNSSendParameter& p_rSendParameter);
bool _writeMDNSMsgHeader(const stcMDNS_MsgHeader& p_MsgHeader, bool _writeMDNSMsgHeader(const stcMDNS_MsgHeader& p_MsgHeader,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
@ -1351,11 +1300,9 @@ protected:
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
bool _writeMDNSRRDomain(const stcMDNS_RRDomain& p_Domain, bool _writeMDNSRRDomain(const stcMDNS_RRDomain& p_Domain,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
bool _writeMDNSHostDomain(const char* m_pcHostname, bool _writeMDNSHostDomain(const char* m_pcHostname, bool p_bPrependRDLength,
bool p_bPrependRDLength,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
bool _writeMDNSServiceDomain(const stcMDNSService& p_Service, bool _writeMDNSServiceDomain(const stcMDNSService& p_Service, bool p_bIncludeName,
bool p_bIncludeName,
bool p_bPrependRDLength, bool p_bPrependRDLength,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
@ -1363,8 +1310,7 @@ protected:
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
bool _writeMDNSAnswer_A(IPAddress p_IPAddress, bool _writeMDNSAnswer_A(IPAddress p_IPAddress, stcMDNSSendParameter& p_rSendParameter);
stcMDNSSendParameter& p_rSendParameter);
bool _writeMDNSAnswer_PTR_IP4(IPAddress p_IPAddress, bool _writeMDNSAnswer_PTR_IP4(IPAddress p_IPAddress,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
#endif #endif
@ -1375,8 +1321,7 @@ protected:
bool _writeMDNSAnswer_TXT(stcMDNSService& p_rService, bool _writeMDNSAnswer_TXT(stcMDNSService& p_rService,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT
bool _writeMDNSAnswer_AAAA(IPAddress p_IPAddress, bool _writeMDNSAnswer_AAAA(IPAddress p_IPAddress, stcMDNSSendParameter& p_rSendParameter);
stcMDNSSendParameter& p_rSendParameter);
bool _writeMDNSAnswer_PTR_IP6(IPAddress p_IPAddress, bool _writeMDNSAnswer_PTR_IP6(IPAddress p_IPAddress,
stcMDNSSendParameter& p_rSendParameter); stcMDNSSendParameter& p_rSendParameter);
#endif #endif
@ -1396,7 +1341,8 @@ protected:
stcMDNSServiceQuery* _findServiceQuery(hMDNSServiceQuery p_hServiceQuery); stcMDNSServiceQuery* _findServiceQuery(hMDNSServiceQuery p_hServiceQuery);
stcMDNSServiceQuery* _findLegacyServiceQuery(void); stcMDNSServiceQuery* _findLegacyServiceQuery(void);
bool _releaseServiceQueries(void); bool _releaseServiceQueries(void);
stcMDNSServiceQuery* _findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceDomain, stcMDNSServiceQuery*
_findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceDomain,
const stcMDNSServiceQuery* p_pPrevServiceQuery); const stcMDNSServiceQuery* p_pPrevServiceQuery);
/* HOSTNAME */ /* HOSTNAME */
@ -1404,49 +1350,36 @@ protected:
bool _releaseHostname(void); bool _releaseHostname(void);
/* SERVICE */ /* SERVICE */
stcMDNSService* _allocService(const char* p_pcName, stcMDNSService* _allocService(const char* p_pcName, const char* p_pcService,
const char* p_pcService, const char* p_pcProtocol, uint16_t p_u16Port);
const char* p_pcProtocol,
uint16_t p_u16Port);
bool _releaseService(stcMDNSService* p_pService); bool _releaseService(stcMDNSService* p_pService);
bool _releaseServices(void); bool _releaseServices(void);
stcMDNSService* _findService(const char* p_pcName, stcMDNSService* _findService(const char* p_pcName, const char* p_pcService,
const char* p_pcService,
const char* p_pcProtocol); const char* p_pcProtocol);
stcMDNSService* _findService(const hMDNSService p_hService); stcMDNSService* _findService(const hMDNSService p_hService);
size_t _countServices(void) const; size_t _countServices(void) const;
/* SERVICE TXT */ /* SERVICE TXT */
stcMDNSServiceTxt* _allocServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* _allocServiceTxt(stcMDNSService* p_pService, const char* p_pcKey,
const char* p_pcKey, const char* p_pcValue, bool p_bTemp);
const char* p_pcValue, bool _releaseServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* p_pTxt);
bool p_bTemp); stcMDNSServiceTxt* _updateServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* p_pTxt,
bool _releaseServiceTxt(stcMDNSService* p_pService, const char* p_pcValue, bool p_bTemp);
stcMDNSServiceTxt* p_pTxt);
stcMDNSServiceTxt* _updateServiceTxt(stcMDNSService* p_pService,
stcMDNSServiceTxt* p_pTxt,
const char* p_pcValue,
bool p_bTemp);
stcMDNSServiceTxt* _findServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* _findServiceTxt(stcMDNSService* p_pService, const char* p_pcKey);
const char* p_pcKey); stcMDNSServiceTxt* _findServiceTxt(stcMDNSService* p_pService, const hMDNSTxt p_hTxt);
stcMDNSServiceTxt* _findServiceTxt(stcMDNSService* p_pService,
const hMDNSTxt p_hTxt);
stcMDNSServiceTxt* _addServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* _addServiceTxt(stcMDNSService* p_pService, const char* p_pcKey,
const char* p_pcKey, const char* p_pcValue, bool p_bTemp);
const char* p_pcValue,
bool p_bTemp);
stcMDNSServiceTxt* _answerKeyValue(const hMDNSServiceQuery p_hServiceQuery, stcMDNSServiceTxt* _answerKeyValue(const hMDNSServiceQuery p_hServiceQuery,
const uint32_t p_u32AnswerIndex); const uint32_t p_u32AnswerIndex);
bool _collectServiceTxts(stcMDNSService& p_rService); bool _collectServiceTxts(stcMDNSService& p_rService);
bool _releaseTempServiceTxts(stcMDNSService& p_rService); bool _releaseTempServiceTxts(stcMDNSService& p_rService);
const stcMDNSServiceTxt* _serviceTxts(const char* p_pcName, const stcMDNSServiceTxt* _serviceTxts(const char* p_pcName, const char* p_pcService,
const char* p_pcService,
const char* p_pcProtocol); const char* p_pcProtocol);
/* MISC */ /* MISC */
@ -1454,10 +1387,10 @@ protected:
bool _printRRDomain(const stcMDNS_RRDomain& p_rRRDomain) const; bool _printRRDomain(const stcMDNS_RRDomain& p_rRRDomain) const;
bool _printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const; bool _printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const;
#endif #endif
}; };
}// namespace MDNSImplementation } // namespace MDNSImplementation
}// namespace esp8266 } // namespace esp8266
#endif // MDNS_H #endif // MDNS_H

File diff suppressed because it is too large Load Diff

View File

@ -38,11 +38,11 @@ namespace esp8266
namespace MDNSImplementation namespace MDNSImplementation
{ {
/** /**
HELPERS HELPERS
*/ */
/* /*
MDNSResponder::indexDomain (static) MDNSResponder::indexDomain (static)
Updates the given domain 'p_rpcHostname' by appending a delimiter and an index number. Updates the given domain 'p_rpcHostname' by appending a delimiter and an index number.
@ -53,16 +53,15 @@ namespace MDNSImplementation
If 'p_rpcHostname' is empty (==0), the given default name 'p_pcDefaultHostname' is used, If 'p_rpcHostname' is empty (==0), the given default name 'p_pcDefaultHostname' is used,
if no default is given, 'esp8266' is used. if no default is given, 'esp8266' is used.
*/ */
/*static*/ bool MDNSResponder::indexDomain(char*& p_rpcDomain, /*static*/ bool MDNSResponder::indexDomain(char*& p_rpcDomain,
const char* p_pcDivider /*= "-"*/, const char* p_pcDivider /*= "-"*/,
const char* p_pcDefaultDomain /*= 0*/) const char* p_pcDefaultDomain /*= 0*/)
{ {
bool bResult = false; bool bResult = false;
// Ensure a divider exists; use '-' as default // Ensure a divider exists; use '-' as default
const char* pcDivider = (p_pcDivider ? : "-"); const char* pcDivider = (p_pcDivider ?: "-");
if (p_rpcDomain) if (p_rpcDomain)
{ {
@ -71,18 +70,18 @@ namespace MDNSImplementation
{ {
char* pEnd = 0; char* pEnd = 0;
unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10); unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10);
if ((ulIndex) && if ((ulIndex) && ((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain))
((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain)) && && (!*pEnd)) // Valid (old) index found
(!*pEnd)) // Valid (old) index found
{ {
char acIndexBuffer[16]; char acIndexBuffer[16];
sprintf(acIndexBuffer, "%lu", (++ulIndex)); sprintf(acIndexBuffer, "%lu", (++ulIndex));
size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider)) + strlen(acIndexBuffer) + 1); size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider))
+ strlen(acIndexBuffer) + 1);
char* pNewHostname = new char[stLength]; char* pNewHostname = new char[stLength];
if (pNewHostname) if (pNewHostname)
{ {
memcpy(pNewHostname, p_rpcDomain, (pFoundDivider - p_rpcDomain + strlen(pcDivider))); memcpy(pNewHostname, p_rpcDomain,
(pFoundDivider - p_rpcDomain + strlen(pcDivider)));
pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0; pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0;
strcat(pNewHostname, acIndexBuffer); strcat(pNewHostname, acIndexBuffer);
@ -93,7 +92,8 @@ namespace MDNSImplementation
} }
else else
{ {
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!"));); DEBUG_EX_ERR(DEBUG_OUTPUT.println(
F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
} }
} }
else else
@ -102,9 +102,11 @@ namespace MDNSImplementation
} }
} }
if (!pFoundDivider) // not yet extended (or failed to increment extension) -> start indexing if (!pFoundDivider) // not yet extended (or failed to increment extension) -> start
// indexing
{ {
size_t stLength = strlen(p_rpcDomain) + (strlen(pcDivider) + 1 + 1); // Name + Divider + '2' + '\0' size_t stLength = strlen(p_rpcDomain)
+ (strlen(pcDivider) + 1 + 1); // Name + Divider + '2' + '\0'
char* pNewHostname = new char[stLength]; char* pNewHostname = new char[stLength];
if (pNewHostname) if (pNewHostname)
{ {
@ -117,14 +119,15 @@ namespace MDNSImplementation
} }
else else
{ {
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!"));); DEBUG_EX_ERR(DEBUG_OUTPUT.println(
F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
} }
} }
} }
else else
{ {
// No given host domain, use base or default // No given host domain, use base or default
const char* cpcDefaultName = (p_pcDefaultDomain ? : "esp8266"); const char* cpcDefaultName = (p_pcDefaultDomain ?: "esp8266");
size_t stLength = strlen(cpcDefaultName) + 1; // '\0' size_t stLength = strlen(cpcDefaultName) + 1; // '\0'
p_rpcDomain = new char[stLength]; p_rpcDomain = new char[stLength];
@ -135,26 +138,29 @@ namespace MDNSImplementation
} }
else else
{ {
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!"));); DEBUG_EX_ERR(DEBUG_OUTPUT.println(
F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
} }
} }
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] indexDomain: %s\n"), p_rpcDomain);); DEBUG_EX_INFO(
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] indexDomain: %s\n"), p_rpcDomain););
return bResult; return bResult;
} }
/*
/*
UDP CONTEXT UDP CONTEXT
*/ */
bool MDNSResponder::_callProcess(void) bool MDNSResponder::_callProcess(void)
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str());); DEBUG_EX_INFO(
DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(),
IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()););
return _process(false); return _process(false);
} }
/* /*
MDNSResponder::_allocUDPContext MDNSResponder::_allocUDPContext
(Re-)Creates the one-and-only UDP context for the MDNS responder. (Re-)Creates the one-and-only UDP context for the MDNS responder.
@ -163,9 +169,9 @@ bool MDNSResponder::_callProcess(void)
Messages are received via the MDNSResponder '_update' function. CAUTION: This function Messages are received via the MDNSResponder '_update' function. CAUTION: This function
is called from the WiFi stack side of the ESP stack system. is called from the WiFi stack side of the ESP stack system.
*/ */
bool MDNSResponder::_allocUDPContext(void) bool MDNSResponder::_allocUDPContext(void)
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext");); DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext"););
_releaseUDPContext(); _releaseUDPContext();
@ -185,14 +191,13 @@ bool MDNSResponder::_allocUDPContext(void)
} }
return true; return true;
} }
/* /*
MDNSResponder::_releaseUDPContext MDNSResponder::_releaseUDPContext
*/ */
bool MDNSResponder::_releaseUDPContext(void) bool MDNSResponder::_releaseUDPContext(void)
{ {
if (m_pUDPContext) if (m_pUDPContext)
{ {
m_pUDPContext->unref(); m_pUDPContext->unref();
@ -200,19 +205,17 @@ bool MDNSResponder::_releaseUDPContext(void)
_leaveMulticastGroups(); _leaveMulticastGroups();
} }
return true; return true;
} }
/*
/*
SERVICE QUERY SERVICE QUERY
*/ */
/* /*
MDNSResponder::_allocServiceQuery MDNSResponder::_allocServiceQuery
*/ */
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void) MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void)
{ {
stcMDNSServiceQuery* pServiceQuery = new stcMDNSServiceQuery; stcMDNSServiceQuery* pServiceQuery = new stcMDNSServiceQuery;
if (pServiceQuery) if (pServiceQuery)
{ {
@ -221,21 +224,19 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void)
m_pServiceQueries = pServiceQuery; m_pServiceQueries = pServiceQuery;
} }
return m_pServiceQueries; return m_pServiceQueries;
} }
/* /*
MDNSResponder::_removeServiceQuery MDNSResponder::_removeServiceQuery
*/ */
bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pServiceQuery) bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pServiceQuery)
{ {
bool bResult = false; bool bResult = false;
if (p_pServiceQuery) if (p_pServiceQuery)
{ {
stcMDNSServiceQuery* pPred = m_pServiceQueries; stcMDNSServiceQuery* pPred = m_pServiceQueries;
while ((pPred) && while ((pPred) && (pPred->m_pNext != p_pServiceQuery))
(pPred->m_pNext != p_pServiceQuery))
{ {
pPred = pPred->m_pNext; pPred = pPred->m_pNext;
} }
@ -255,32 +256,32 @@ bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pS
} }
else else
{ {
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseServiceQuery: INVALID service query!");); DEBUG_EX_ERR(DEBUG_OUTPUT.println(
"[MDNSResponder] _releaseServiceQuery: INVALID service query!"););
} }
} }
} }
return bResult; return bResult;
} }
/* /*
MDNSResponder::_removeLegacyServiceQuery MDNSResponder::_removeLegacyServiceQuery
*/ */
bool MDNSResponder::_removeLegacyServiceQuery(void) bool MDNSResponder::_removeLegacyServiceQuery(void)
{ {
stcMDNSServiceQuery* pLegacyServiceQuery = _findLegacyServiceQuery(); stcMDNSServiceQuery* pLegacyServiceQuery = _findLegacyServiceQuery();
return (pLegacyServiceQuery ? _removeServiceQuery(pLegacyServiceQuery) : true); return (pLegacyServiceQuery ? _removeServiceQuery(pLegacyServiceQuery) : true);
} }
/* /*
MDNSResponder::_findServiceQuery MDNSResponder::_findServiceQuery
'Convert' hMDNSServiceQuery to stcMDNSServiceQuery* (ensure existence) 'Convert' hMDNSServiceQuery to stcMDNSServiceQuery* (ensure existence)
*/ */
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery) MDNSResponder::stcMDNSServiceQuery*
{ MDNSResponder::_findServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery)
{
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
while (pServiceQuery) while (pServiceQuery)
{ {
@ -291,14 +292,13 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findServiceQuery(MDNSRespond
pServiceQuery = pServiceQuery->m_pNext; pServiceQuery = pServiceQuery->m_pNext;
} }
return pServiceQuery; return pServiceQuery;
} }
/* /*
MDNSResponder::_findLegacyServiceQuery MDNSResponder::_findLegacyServiceQuery
*/ */
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void) MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void)
{ {
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
while (pServiceQuery) while (pServiceQuery)
{ {
@ -309,13 +309,13 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void)
pServiceQuery = pServiceQuery->m_pNext; pServiceQuery = pServiceQuery->m_pNext;
} }
return pServiceQuery; return pServiceQuery;
} }
/* /*
MDNSResponder::_releaseServiceQueries MDNSResponder::_releaseServiceQueries
*/ */
bool MDNSResponder::_releaseServiceQueries(void) bool MDNSResponder::_releaseServiceQueries(void)
{ {
while (m_pServiceQueries) while (m_pServiceQueries)
{ {
stcMDNSServiceQuery* pNext = m_pServiceQueries->m_pNext; stcMDNSServiceQuery* pNext = m_pServiceQueries->m_pNext;
@ -323,17 +323,18 @@ bool MDNSResponder::_releaseServiceQueries(void)
m_pServiceQueries = pNext; m_pServiceQueries = pNext;
} }
return true; return true;
} }
/* /*
MDNSResponder::_findNextServiceQueryByServiceType MDNSResponder::_findNextServiceQueryByServiceType
*/ */
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceTypeDomain, MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServiceType(
const stcMDNSServiceQuery* p_pPrevServiceQuery) const stcMDNS_RRDomain& p_ServiceTypeDomain, const stcMDNSServiceQuery* p_pPrevServiceQuery)
{ {
stcMDNSServiceQuery* pMatchingServiceQuery = 0; stcMDNSServiceQuery* pMatchingServiceQuery = 0;
stcMDNSServiceQuery* pServiceQuery = (p_pPrevServiceQuery ? p_pPrevServiceQuery->m_pNext : m_pServiceQueries); stcMDNSServiceQuery* pServiceQuery
= (p_pPrevServiceQuery ? p_pPrevServiceQuery->m_pNext : m_pServiceQueries);
while (pServiceQuery) while (pServiceQuery)
{ {
if (p_ServiceTypeDomain == pServiceQuery->m_ServiceTypeDomain) if (p_ServiceTypeDomain == pServiceQuery->m_ServiceTypeDomain)
@ -344,27 +345,28 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServic
pServiceQuery = pServiceQuery->m_pNext; pServiceQuery = pServiceQuery->m_pNext;
} }
return pMatchingServiceQuery; return pMatchingServiceQuery;
} }
/*
/*
HOSTNAME HOSTNAME
*/ */
/* /*
MDNSResponder::_setHostname MDNSResponder::_setHostname
*/ */
bool MDNSResponder::_setHostname(const char* p_pcHostname) bool MDNSResponder::_setHostname(const char* p_pcHostname)
{ {
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _allocHostname (%s)\n"), p_pcHostname);); // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _allocHostname (%s)\n"),
// p_pcHostname););
bool bResult = false; bool bResult = false;
_releaseHostname(); _releaseHostname();
size_t stLength = 0; size_t stLength = 0;
if ((p_pcHostname) && if ((p_pcHostname)
(MDNS_DOMAIN_LABEL_MAXLENGTH >= (stLength = strlen(p_pcHostname)))) // char max size for a single label && (MDNS_DOMAIN_LABEL_MAXLENGTH
>= (stLength = strlen(p_pcHostname)))) // char max size for a single label
{ {
// Copy in hostname characters as lowercase // Copy in hostname characters as lowercase
if ((bResult = (0 != (m_pcHostname = new char[stLength + 1])))) if ((bResult = (0 != (m_pcHostname = new char[stLength + 1]))))
@ -373,7 +375,8 @@ bool MDNSResponder::_setHostname(const char* p_pcHostname)
size_t i = 0; size_t i = 0;
for (; i < stLength; ++i) for (; i < stLength; ++i)
{ {
m_pcHostname[i] = (isupper(p_pcHostname[i]) ? tolower(p_pcHostname[i]) : p_pcHostname[i]); m_pcHostname[i]
= (isupper(p_pcHostname[i]) ? tolower(p_pcHostname[i]) : p_pcHostname[i]);
} }
m_pcHostname[i] = 0; m_pcHostname[i] = 0;
#else #else
@ -382,50 +385,41 @@ bool MDNSResponder::_setHostname(const char* p_pcHostname)
} }
} }
return bResult; return bResult;
} }
/* /*
MDNSResponder::_releaseHostname MDNSResponder::_releaseHostname
*/ */
bool MDNSResponder::_releaseHostname(void) bool MDNSResponder::_releaseHostname(void)
{ {
if (m_pcHostname) if (m_pcHostname)
{ {
delete[] m_pcHostname; delete[] m_pcHostname;
m_pcHostname = 0; m_pcHostname = 0;
} }
return true; return true;
} }
/*
/*
SERVICE SERVICE
*/ */
/* /*
MDNSResponder::_allocService MDNSResponder::_allocService
*/ */
MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName, MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName,
const char* p_pcService, const char* p_pcService,
const char* p_pcProtocol, const char* p_pcProtocol,
uint16_t p_u16Port) uint16_t p_u16Port)
{
stcMDNSService* pService = 0;
if (((!p_pcName) ||
(MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcName))) &&
(p_pcService) &&
(MDNS_SERVICE_NAME_LENGTH >= strlen(p_pcService)) &&
(p_pcProtocol) &&
(MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) &&
(p_u16Port) &&
(0 != (pService = new stcMDNSService)) &&
(pService->setName(p_pcName ? : m_pcHostname)) &&
(pService->setService(p_pcService)) &&
(pService->setProtocol(p_pcProtocol)))
{ {
stcMDNSService* pService = 0;
if (((!p_pcName) || (MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcName))) && (p_pcService)
&& (MDNS_SERVICE_NAME_LENGTH >= strlen(p_pcService)) && (p_pcProtocol)
&& (MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) && (p_u16Port)
&& (0 != (pService = new stcMDNSService))
&& (pService->setName(p_pcName ?: m_pcHostname)) && (pService->setService(p_pcService))
&& (pService->setProtocol(p_pcProtocol)))
{
pService->m_bAutoName = (0 == p_pcName); pService->m_bAutoName = (0 == p_pcName);
pService->m_u16Port = p_u16Port; pService->m_u16Port = p_u16Port;
@ -434,21 +428,19 @@ MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName
m_pServices = pService; m_pServices = pService;
} }
return pService; return pService;
} }
/* /*
MDNSResponder::_releaseService MDNSResponder::_releaseService
*/ */
bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService) bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService)
{ {
bool bResult = false; bool bResult = false;
if (p_pService) if (p_pService)
{ {
stcMDNSService* pPred = m_pServices; stcMDNSService* pPred = m_pServices;
while ((pPred) && while ((pPred) && (pPred->m_pNext != p_pService))
(pPred->m_pNext != p_pService))
{ {
pPred = pPred->m_pNext; pPred = pPred->m_pNext;
} }
@ -468,19 +460,19 @@ bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService)
} }
else else
{ {
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseService: INVALID service!");); DEBUG_EX_ERR(
DEBUG_OUTPUT.println("[MDNSResponder] _releaseService: INVALID service!"););
} }
} }
} }
return bResult; return bResult;
} }
/* /*
MDNSResponder::_releaseServices MDNSResponder::_releaseServices
*/ */
bool MDNSResponder::_releaseServices(void) bool MDNSResponder::_releaseServices(void)
{ {
stcMDNSService* pService = m_pServices; stcMDNSService* pService = m_pServices;
while (pService) while (pService)
{ {
@ -488,37 +480,35 @@ bool MDNSResponder::_releaseServices(void)
pService = m_pServices; pService = m_pServices;
} }
return true; return true;
} }
/* /*
MDNSResponder::_findService MDNSResponder::_findService
*/ */
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName, MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName,
const char* p_pcService, const char* p_pcService,
const char* p_pcProtocol) const char* p_pcProtocol)
{ {
stcMDNSService* pService = m_pServices; stcMDNSService* pService = m_pServices;
while (pService) while (pService)
{ {
if ((0 == strcmp(pService->m_pcName, p_pcName)) && if ((0 == strcmp(pService->m_pcName, p_pcName))
(0 == strcmp(pService->m_pcService, p_pcService)) && && (0 == strcmp(pService->m_pcService, p_pcService))
(0 == strcmp(pService->m_pcProtocol, p_pcProtocol))) && (0 == strcmp(pService->m_pcProtocol, p_pcProtocol)))
{ {
break; break;
} }
pService = pService->m_pNext; pService = pService->m_pNext;
} }
return pService; return pService;
} }
/* /*
MDNSResponder::_findService MDNSResponder::_findService
*/ */
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const MDNSResponder::hMDNSService p_hService) MDNSResponder::stcMDNSService*
{ MDNSResponder::_findService(const MDNSResponder::hMDNSService p_hService)
{
stcMDNSService* pService = m_pServices; stcMDNSService* pService = m_pServices;
while (pService) while (pService)
{ {
@ -529,33 +519,26 @@ MDNSResponder::stcMDNSService* MDNSResponder::_findService(const MDNSResponder::
pService = pService->m_pNext; pService = pService->m_pNext;
} }
return pService; return pService;
} }
/*
/*
SERVICE TXT SERVICE TXT
*/ */
/* /*
MDNSResponder::_allocServiceTxt MDNSResponder::_allocServiceTxt
*/ */
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder::stcMDNSService* p_pService, MDNSResponder::stcMDNSServiceTxt*
const char* p_pcKey, MDNSResponder::_allocServiceTxt(MDNSResponder::stcMDNSService* p_pService, const char* p_pcKey,
const char* p_pcValue, const char* p_pcValue, bool p_bTemp)
bool p_bTemp) {
{
stcMDNSServiceTxt* pTxt = 0; stcMDNSServiceTxt* pTxt = 0;
if ((p_pService) && if ((p_pService) && (p_pcKey)
(p_pcKey) && && (MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() + 1 + // Length byte
(MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() + (p_pcKey ? strlen(p_pcKey) : 0) + 1 + // '='
1 + // Length byte
(p_pcKey ? strlen(p_pcKey) : 0) +
1 + // '='
(p_pcValue ? strlen(p_pcValue) : 0)))) (p_pcValue ? strlen(p_pcValue) : 0))))
{ {
pTxt = new stcMDNSServiceTxt; pTxt = new stcMDNSServiceTxt;
if (pTxt) if (pTxt)
{ {
@ -563,7 +546,8 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder:
pTxt->m_pcKey = new char[stLength + 1]; pTxt->m_pcKey = new char[stLength + 1];
if (pTxt->m_pcKey) if (pTxt->m_pcKey)
{ {
strncpy(pTxt->m_pcKey, p_pcKey, stLength); pTxt->m_pcKey[stLength] = 0; strncpy(pTxt->m_pcKey, p_pcKey, stLength);
pTxt->m_pcKey[stLength] = 0;
} }
if (p_pcValue) if (p_pcValue)
@ -572,7 +556,8 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder:
pTxt->m_pcValue = new char[stLength + 1]; pTxt->m_pcValue = new char[stLength + 1];
if (pTxt->m_pcValue) if (pTxt->m_pcValue)
{ {
strncpy(pTxt->m_pcValue, p_pcValue, stLength); pTxt->m_pcValue[stLength] = 0; strncpy(pTxt->m_pcValue, p_pcValue, stLength);
pTxt->m_pcValue[stLength] = 0;
} }
} }
pTxt->m_bTemp = p_bTemp; pTxt->m_bTemp = p_bTemp;
@ -582,76 +567,66 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder:
} }
} }
return pTxt; return pTxt;
} }
/* /*
MDNSResponder::_releaseServiceTxt MDNSResponder::_releaseServiceTxt
*/ */
bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService, bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService,
MDNSResponder::stcMDNSServiceTxt* p_pTxt) MDNSResponder::stcMDNSServiceTxt* p_pTxt)
{ {
return ((p_pService) && (p_pTxt) && (p_pService->m_Txts.remove(p_pTxt)));
}
return ((p_pService) && /*
(p_pTxt) &&
(p_pService->m_Txts.remove(p_pTxt)));
}
/*
MDNSResponder::_updateServiceTxt MDNSResponder::_updateServiceTxt
*/ */
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_updateServiceTxt(MDNSResponder::stcMDNSService* p_pService, MDNSResponder::stcMDNSServiceTxt*
MDNSResponder::_updateServiceTxt(MDNSResponder::stcMDNSService* p_pService,
MDNSResponder::stcMDNSServiceTxt* p_pTxt, MDNSResponder::stcMDNSServiceTxt* p_pTxt,
const char* p_pcValue, const char* p_pcValue, bool p_bTemp)
bool p_bTemp) {
{ if ((p_pService) && (p_pTxt)
&& (MDNS_SERVICE_TXT_MAXLENGTH
if ((p_pService) && > (p_pService->m_Txts.length() - (p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0)
(p_pTxt) && + (p_pcValue ? strlen(p_pcValue) : 0))))
(MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() -
(p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0) +
(p_pcValue ? strlen(p_pcValue) : 0))))
{ {
p_pTxt->update(p_pcValue); p_pTxt->update(p_pcValue);
p_pTxt->m_bTemp = p_bTemp; p_pTxt->m_bTemp = p_bTemp;
} }
return p_pTxt; return p_pTxt;
} }
/* /*
MDNSResponder::_findServiceTxt MDNSResponder::_findServiceTxt
*/ */
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService, MDNSResponder::stcMDNSServiceTxt*
const char* p_pcKey) MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService, const char* p_pcKey)
{ {
return (p_pService ? p_pService->m_Txts.find(p_pcKey) : 0); return (p_pService ? p_pService->m_Txts.find(p_pcKey) : 0);
} }
/* /*
MDNSResponder::_findServiceTxt MDNSResponder::_findServiceTxt
*/ */
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService, MDNSResponder::stcMDNSServiceTxt*
const hMDNSTxt p_hTxt) MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService, const hMDNSTxt p_hTxt)
{ {
return (((p_pService) && (p_hTxt)) ? p_pService->m_Txts.find((stcMDNSServiceTxt*)p_hTxt)
: 0);
}
return (((p_pService) && (p_hTxt)) ? p_pService->m_Txts.find((stcMDNSServiceTxt*)p_hTxt) : 0); /*
}
/*
MDNSResponder::_addServiceTxt MDNSResponder::_addServiceTxt
*/ */
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::stcMDNSService* p_pService, MDNSResponder::stcMDNSServiceTxt*
const char* p_pcKey, MDNSResponder::_addServiceTxt(MDNSResponder::stcMDNSService* p_pService, const char* p_pcKey,
const char* p_pcValue, const char* p_pcValue, bool p_bTemp)
bool p_bTemp) {
{
stcMDNSServiceTxt* pResult = 0; stcMDNSServiceTxt* pResult = 0;
if ((p_pService) && if ((p_pService) && (p_pcKey) && (strlen(p_pcKey)))
(p_pcKey) &&
(strlen(p_pcKey)))
{ {
stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey); stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey);
if (pTxt) if (pTxt)
{ {
@ -663,23 +638,24 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::s
} }
} }
return pResult; return pResult;
} }
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_answerKeyValue(const hMDNSServiceQuery p_hServiceQuery, MDNSResponder::stcMDNSServiceTxt*
MDNSResponder::_answerKeyValue(const hMDNSServiceQuery p_hServiceQuery,
const uint32_t p_u32AnswerIndex) const uint32_t p_u32AnswerIndex)
{ {
stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery);
stcMDNSServiceQuery::stcAnswer* pSQAnswer = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); stcMDNSServiceQuery::stcAnswer* pSQAnswer
= (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0);
// Fill m_pcTxts (if not already done) // Fill m_pcTxts (if not already done)
return (pSQAnswer) ? pSQAnswer->m_Txts.m_pTxts : 0; return (pSQAnswer) ? pSQAnswer->m_Txts.m_pTxts : 0;
} }
/* /*
MDNSResponder::_collectServiceTxts MDNSResponder::_collectServiceTxts
*/ */
bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rService) bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rService)
{ {
// Call Dynamic service callbacks // Call Dynamic service callbacks
if (m_fnServiceTxtCallback) if (m_fnServiceTxtCallback)
{ {
@ -690,30 +666,27 @@ bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rServic
p_rService.m_fnTxtCallback((hMDNSService)&p_rService); p_rService.m_fnTxtCallback((hMDNSService)&p_rService);
} }
return true; return true;
} }
/* /*
MDNSResponder::_releaseTempServiceTxts MDNSResponder::_releaseTempServiceTxts
*/ */
bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rService) bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rService)
{ {
return (p_rService.m_Txts.removeTempTxts()); return (p_rService.m_Txts.removeTempTxts());
} }
/*
/*
MISC MISC
*/ */
#ifdef DEBUG_ESP_MDNS_RESPONDER #ifdef DEBUG_ESP_MDNS_RESPONDER
/* /*
MDNSResponder::_printRRDomain MDNSResponder::_printRRDomain
*/ */
bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDomain) const bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDomain) const
{ {
// DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
//DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
const char* pCursor = p_RRDomain.m_acName; const char* pCursor = p_RRDomain.m_acName;
uint8_t u8Length = *pCursor++; uint8_t u8Length = *pCursor++;
@ -736,25 +709,29 @@ bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDo
{ {
DEBUG_OUTPUT.printf_P(PSTR("-empty-")); DEBUG_OUTPUT.printf_P(PSTR("-empty-"));
} }
//DEBUG_OUTPUT.printf_P(PSTR("\n")); // DEBUG_OUTPUT.printf_P(PSTR("\n"));
return true; return true;
} }
/* /*
MDNSResponder::_printRRAnswer MDNSResponder::_printRRAnswer
*/ */
bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const
{ {
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] RRAnswer: ")); DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] RRAnswer: "));
_printRRDomain(p_RRAnswer.m_Header.m_Domain); _printRRDomain(p_RRAnswer.m_Header.m_Domain);
DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "), p_RRAnswer.m_Header.m_Attributes.m_u16Type, p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL); DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "),
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type & (~0x8000)) // Topmost bit might carry 'cache flush' flag p_RRAnswer.m_Header.m_Attributes.m_u16Type,
p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL);
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type
& (~0x8000)) // Topmost bit might carry 'cache flush' flag
{ {
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
case DNS_RRTYPE_A: case DNS_RRTYPE_A:
DEBUG_OUTPUT.printf_P(PSTR("A IP:%s"), ((const stcMDNS_RRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str()); DEBUG_OUTPUT.printf_P(
PSTR("A IP:%s"),
((const stcMDNS_RRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str());
break; break;
#endif #endif
case DNS_RRTYPE_PTR: case DNS_RRTYPE_PTR:
@ -767,7 +744,7 @@ bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAn
char* pTxts = new char[stTxtLength]; char* pTxts = new char[stTxtLength];
if (pTxts) if (pTxts)
{ {
((/*const c_str()!!*/stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts); ((/*const c_str()!!*/ stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts);
DEBUG_OUTPUT.printf_P(PSTR("TXT(%zu) %s"), stTxtLength, pTxts); DEBUG_OUTPUT.printf_P(PSTR("TXT(%zu) %s"), stTxtLength, pTxts);
delete[] pTxts; delete[] pTxts;
} }
@ -775,11 +752,14 @@ bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAn
} }
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT
case DNS_RRTYPE_AAAA: case DNS_RRTYPE_AAAA:
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((stcMDNS_RRAnswerA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str()); DEBUG_OUTPUT.printf_P(
PSTR("AAAA IP:%s"),
((stcMDNS_RRAnswerA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str());
break; break;
#endif #endif
case DNS_RRTYPE_SRV: case DNS_RRTYPE_SRV:
DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "), ((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_u16Port); DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "),
((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_u16Port);
_printRRDomain(((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_SRVDomain); _printRRDomain(((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_SRVDomain);
break; break;
default: default:
@ -789,13 +769,9 @@ bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAn
DEBUG_OUTPUT.printf_P(PSTR("\n")); DEBUG_OUTPUT.printf_P(PSTR("\n"));
return true; return true;
} }
#endif #endif
} // namespace MDNSImplementation } // namespace MDNSImplementation
} // namespace esp8266 } // namespace esp8266

View File

@ -37,7 +37,7 @@ namespace MDNSImplementation
// Enable class debug functions // Enable class debug functions
#define ESP_8266_MDNS_INCLUDE #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) #if !defined(DEBUG_ESP_MDNS_RESPONDER) && defined(DEBUG_ESP_MDNS)
#define DEBUG_ESP_MDNS_RESPONDER #define DEBUG_ESP_MDNS_RESPONDER
@ -48,8 +48,9 @@ namespace MDNSImplementation
#endif #endif
// //
// If ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE is defined, the mDNS responder ignores a successful probing // If ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE is defined, the mDNS responder ignores a successful
// This allows to drive the responder in a environment, where 'update()' isn't called in the loop // 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 //#define ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
// Enable/disable debug trace macros // Enable/disable debug trace macros
@ -88,19 +89,34 @@ namespace MDNSImplementation
#define DEBUG_OUTPUT Serial #define DEBUG_OUTPUT Serial
#endif #endif
#else #else
#define DEBUG_EX_INFO(A) do { (void)0; } while (0) #define DEBUG_EX_INFO(A) \
#define DEBUG_EX_ERR(A) do { (void)0; } while (0) do \
#define DEBUG_EX_TX(A) do { (void)0; } while (0) { \
#define DEBUG_EX_RX(A) do { (void)0; } while (0) (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 #endif
/* already defined in lwIP ('lwip/prot/dns.h') /* already defined in lwIP ('lwip/prot/dns.h')
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
#define DNS_MQUERY_IPV4_GROUP_INIT (IPAddress(224, 0, 0, 251)) // ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT #define DNS_MQUERY_IPV4_GROUP_INIT (IPAddress(224, 0, 0, 251)) // ip_addr_t
#endif v4group = DNS_MQUERY_IPV4_GROUP_INIT #endif #ifdef MDNS_IP6_SUPPORT #define
#ifdef MDNS_IP6_SUPPORT DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) // ip_addr_t v6group =
#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) // ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT DNS_MQUERY_IPV6_GROUP_INIT #endif*/
#endif*/
//#define MDNS_MULTICAST_PORT 5353 //#define MDNS_MULTICAST_PORT 5353
/* /*
@ -111,7 +127,7 @@ namespace MDNSImplementation
However, RFC 3171 seems to force 255 instead 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 This is the MDNS record TTL
@ -139,7 +155,8 @@ namespace MDNSImplementation
/* /*
Delay between and number of probes for host and service domains 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 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_DELAY 250
#define MDNS_PROBE_COUNT 3 #define MDNS_PROBE_COUNT 3
@ -148,7 +165,6 @@ namespace MDNSImplementation
#define MDNS_DYNAMIC_QUERY_RESEND_COUNT 5 #define MDNS_DYNAMIC_QUERY_RESEND_COUNT 5
#define MDNS_DYNAMIC_QUERY_RESEND_DELAY 5000 #define MDNS_DYNAMIC_QUERY_RESEND_DELAY 5000
/* /*
Force host domain to use only lowercase letters Force host domain to use only lowercase letters
*/ */
@ -177,5 +193,4 @@ namespace MDNSImplementation
// Include the main header, so the submodlues only need to include this header // Include the main header, so the submodlues only need to include this header
#include "LEAmDNS.h" #include "LEAmDNS.h"
#endif // MDNS_PRIV_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

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

View File

@ -21,7 +21,8 @@ void setup() {
// start I2S at 8 kHz with 24-bits per sample // start I2S at 8 kHz with 24-bits per sample
if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 24)) { if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 24)) {
Serial.println("Failed to initialize I2S!"); Serial.println("Failed to initialize I2S!");
while (1); // do nothing while (1)
; // do nothing
} }
} }

View File

@ -26,7 +26,8 @@ void setup() {
// start I2S at the sample rate with 16-bits per sample // start I2S at the sample rate with 16-bits per sample
if (!I2S.begin(I2S_PHILIPS_MODE, sampleRate, 16)) { if (!I2S.begin(I2S_PHILIPS_MODE, sampleRate, 16)) {
Serial.println("Failed to initialize I2S!"); 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 // increment the counter for the next sample
count++; count++;
} }

View File

@ -19,7 +19,7 @@ long timezone = 2;
byte daysavetime = 1; byte daysavetime = 1;
void listDir(const char * dirname) { void listDir(const char *dirname) {
Serial.printf("Listing directory: %s\n", dirname); Serial.printf("Listing directory: %s\n", dirname);
Dir root = LittleFS.openDir(dirname); Dir root = LittleFS.openDir(dirname);
@ -33,7 +33,7 @@ void listDir(const char * dirname) {
time_t cr = file.getCreationTime(); time_t cr = file.getCreationTime();
time_t lw = file.getLastWrite(); time_t lw = file.getLastWrite();
file.close(); 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); 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); 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); 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); Serial.printf("Reading file: %s\n", path);
File file = LittleFS.open(path, "r"); File file = LittleFS.open(path, "r");
@ -51,13 +51,11 @@ void readFile(const char * path) {
} }
Serial.print("Read from file: "); Serial.print("Read from file: ");
while (file.available()) { while (file.available()) { Serial.write(file.read()); }
Serial.write(file.read());
}
file.close(); 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); Serial.printf("Writing file: %s\n", path);
File file = LittleFS.open(path, "w"); File file = LittleFS.open(path, "w");
@ -74,7 +72,7 @@ void writeFile(const char * path, const char * message) {
file.close(); 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); Serial.printf("Appending to file: %s\n", path);
File file = LittleFS.open(path, "a"); File file = LittleFS.open(path, "a");
@ -90,7 +88,7 @@ void appendFile(const char * path, const char * message) {
file.close(); 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); Serial.printf("Renaming file %s to %s\n", path1, path2);
if (LittleFS.rename(path1, path2)) { if (LittleFS.rename(path1, path2)) {
Serial.println("File renamed"); 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); Serial.printf("Deleting file: %s\n", path);
if (LittleFS.remove(path)) { if (LittleFS.remove(path)) {
Serial.println("File deleted"); Serial.println("File deleted");
@ -127,7 +125,7 @@ void setup() {
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
Serial.println("Contacting Time Server"); Serial.println("Contacting Time Server");
configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
struct tm tmstruct ; struct tm tmstruct;
delay(2000); delay(2000);
tmstruct.tm_year = 0; tmstruct.tm_year = 0;
getLocalTime(&tmstruct, 5000); getLocalTime(&tmstruct, 5000);
@ -158,9 +156,6 @@ void setup() {
} }
readFile("/hello.txt"); readFile("/hello.txt");
listDir("/"); listDir("/");
} }
void loop() { } void loop() {}

View File

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

View File

@ -20,7 +20,7 @@ const char* password = STAPSK;
Netdump nd; Netdump nd;
//FS* filesystem = &SPIFFS; // FS* filesystem = &SPIFFS;
FS* filesystem = &LittleFS; FS* filesystem = &LittleFS;
ESP8266WebServer webServer(80); // Used for sending commands ESP8266WebServer webServer(80); // Used for sending commands
@ -29,34 +29,27 @@ File tracefile;
std::map<PacketType, int> packetCount; std::map<PacketType, int> packetCount;
enum class SerialOption : uint8_t { enum class SerialOption : uint8_t { AllFull,
AllFull,
LocalNone, LocalNone,
HTTPChar HTTPChar };
};
void startSerial(SerialOption option) { void startSerial(SerialOption option) {
switch (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); nd.printDump(Serial, Packet::PacketDetail::FULL);
break; break;
case SerialOption::LocalNone : // Only local IP traffic, full details case SerialOption::LocalNone: // Only local IP traffic, full details
nd.printDump(Serial, Packet::PacketDetail::NONE, nd.printDump(Serial, Packet::PacketDetail::NONE, [](Packet n) {
[](Packet n) {
return (n.hasIP(WiFi.localIP())); return (n.hasIP(WiFi.localIP()));
} });
);
break; break;
case SerialOption::HTTPChar : // Only HTTP traffic, show packet content as chars case SerialOption::HTTPChar: // Only HTTP traffic, show packet content as chars
nd.printDump(Serial, Packet::PacketDetail::CHAR, nd.printDump(Serial, Packet::PacketDetail::CHAR, [](Packet n) {
[](Packet n) {
return (n.isHTTP()); return (n.isHTTP());
} });
);
break; break;
default : default: Serial.printf("No valid SerialOption provided\r\n");
Serial.printf("No valid SerialOption provided\r\n");
}; };
} }
@ -80,44 +73,34 @@ void setup(void) {
if (WiFi.waitForConnectResult() != WL_CONNECTED) { if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed, stopping sketch"); Serial.println("WiFi Failed, stopping sketch");
while (1) { while (1) { delay(1000); }
delay(1000);
}
} }
if (!MDNS.begin("netdumphost")) { if (!MDNS.begin("netdumphost")) { Serial.println("Error setting up MDNS responder!"); }
Serial.println("Error setting up MDNS responder!");
}
filesystem->begin(); filesystem->begin();
webServer.on("/list", webServer.on("/list", []() {
[]() {
Dir dir = filesystem->openDir("/"); Dir dir = filesystem->openDir("/");
String d = "<h1>File list</h1>"; String d = "<h1>File list</h1>";
while (dir.next()) { while (dir.next()) {
d.concat("<li>" + dir.fileName() + "</li>"); d.concat("<li>" + dir.fileName() + "</li>");
} }
webServer.send(200, "text.html", d); webServer.send(200, "text.html", d);
} });
);
webServer.on("/req", webServer.on("/req", []() {
[]() {
static int rq = 0; static int rq = 0;
String a = "<h1>You are connected, Number of requests = " + String(rq++) + "</h1>"; String a = "<h1>You are connected, Number of requests = " + String(rq++) + "</h1>";
webServer.send(200, "text/html", a); webServer.send(200, "text/html", a);
} });
);
webServer.on("/reset", webServer.on("/reset", []() {
[]() {
nd.reset(); nd.reset();
tracefile.close(); tracefile.close();
tcpServer.close(); tcpServer.close();
webServer.send(200, "text.html", "<h1>Netdump session reset</h1>"); webServer.send(200, "text.html", "<h1>Netdump session reset</h1>");
} });
);
webServer.serveStatic("/", *filesystem, "/"); webServer.serveStatic("/", *filesystem, "/");
webServer.begin(); webServer.begin();
@ -153,4 +136,3 @@ void loop(void) {
webServer.handleClient(); webServer.handleClient();
MDNS.update(); MDNS.update();
} }

View File

@ -23,7 +23,6 @@
#include <lwip/init.h> #include <lwip/init.h>
#include "Schedule.h" #include "Schedule.h"
namespace NetCapture namespace NetCapture
{ {
@ -69,24 +68,26 @@ void Netdump::reset()
void Netdump::printDump(Print& out, Packet::PacketDetail ndd, const Filter nf) void Netdump::printDump(Print& out, Packet::PacketDetail ndd, const Filter nf)
{ {
out.printf_P(PSTR("netDump starting\r\n")); out.printf_P(PSTR("netDump starting\r\n"));
setCallback([&out, ndd, this](const Packet & ndp) setCallback(
[&out, ndd, this](const Packet& ndp)
{ {
printDumpProcess(out, ndd, ndp); printDumpProcess(out, ndd, ndp);
}, nf); },
nf);
} }
void Netdump::fileDump(File& outfile, const Filter nf) void Netdump::fileDump(File& outfile, const Filter nf)
{ {
writePcapHeader(outfile); writePcapHeader(outfile);
setCallback([&outfile, this](const Packet & ndp) setCallback(
[&outfile, this](const Packet& ndp)
{ {
fileDumpProcess(outfile, ndp); fileDumpProcess(outfile, ndp);
}, nf); },
nf);
} }
bool Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) bool Netdump::tcpDump(WiFiServer& tcpDumpServer, const Filter nf)
{ {
if (!packetBuffer) if (!packetBuffer)
{ {
packetBuffer = new (std::nothrow) char[tcpBufferSize]; packetBuffer = new (std::nothrow) char[tcpBufferSize];
@ -98,7 +99,8 @@ bool Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf)
} }
bufferIndex = 0; bufferIndex = 0;
schedule_function([&tcpDumpServer, this, nf]() schedule_function(
[&tcpDumpServer, this, nf]()
{ {
tcpDumpLoop(tcpDumpServer, nf); tcpDumpLoop(tcpDumpServer, nf);
}); });
@ -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) 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.
} }
} }
@ -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()) if (tcpDumpServer.hasClient())
{ {
@ -199,10 +202,12 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf)
bufferIndex = 0; bufferIndex = 0;
writePcapHeader(tcpDumpClient); writePcapHeader(tcpDumpClient);
setCallback([this](const Packet & ndp) setCallback(
[this](const Packet& ndp)
{ {
tcpDumpProcess(ndp); tcpDumpProcess(ndp);
}, nf); },
nf);
} }
if (!tcpDumpClient || !tcpDumpClient.connected()) if (!tcpDumpClient || !tcpDumpClient.connected())
{ {
@ -216,7 +221,8 @@ void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf)
if (tcpDumpServer.status() != CLOSED) if (tcpDumpServer.status() != CLOSED)
{ {
schedule_function([&tcpDumpServer, this, nf]() schedule_function(
[&tcpDumpServer, this, nf]()
{ {
tcpDumpLoop(tcpDumpServer, nf); tcpDumpLoop(tcpDumpServer, nf);
}); });

View File

@ -38,7 +38,6 @@ using namespace experimental::CBListImplentation;
class Netdump class Netdump
{ {
public: public:
using Filter = std::function<bool(const Packet&)>; using Filter = std::function<bool(const Packet&)>;
using Callback = std::function<void(const Packet&)>; using Callback = std::function<void(const Packet&)>;
using LwipCallback = std::function<void(int, const char*, int, int, int)>; using LwipCallback = std::function<void(int, const char*, int, int, int)>;
@ -53,8 +52,7 @@ public:
void printDump(Print& out, Packet::PacketDetail ndd, const Filter nf = nullptr); void printDump(Print& out, Packet::PacketDetail ndd, const Filter nf = nullptr);
void fileDump(File& outfile, 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: private:
Callback netDumpCallback = nullptr; Callback netDumpCallback = nullptr;
@ -69,7 +67,7 @@ private:
void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const; void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const;
void fileDumpProcess(File& outfile, const Packet& np) const; void fileDumpProcess(File& outfile, const Packet& np) const;
void tcpDumpProcess(const Packet& np); void tcpDumpProcess(const Packet& np);
void tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf); void tcpDumpLoop(WiFiServer& tcpDumpServer, const Filter nf);
void writePcapHeader(Stream& s) const; void writePcapHeader(Stream& s) const;

View File

@ -24,11 +24,10 @@
namespace NetCapture namespace NetCapture
{ {
NetdumpIP::NetdumpIP() NetdumpIP::NetdumpIP() { }
{
}
NetdumpIP::NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) NetdumpIP::NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet,
uint8_t fourth_octet)
{ {
setV4(); setV4();
(*this)[0] = first_octet; (*this)[0] = first_octet;
@ -37,7 +36,7 @@ NetdumpIP::NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_oc
(*this)[3] = fourth_octet; (*this)[3] = fourth_octet;
} }
NetdumpIP::NetdumpIP(const uint8_t *address, bool v4) NetdumpIP::NetdumpIP(const uint8_t* address, bool v4)
{ {
uint8_t cnt; uint8_t cnt;
if (v4) if (v4)
@ -88,7 +87,7 @@ NetdumpIP::NetdumpIP(const String& ip)
} }
} }
bool NetdumpIP::fromString(const char *address) bool NetdumpIP::fromString(const char* address)
{ {
if (!fromString4(address)) if (!fromString4(address))
{ {
@ -97,7 +96,7 @@ bool NetdumpIP::fromString(const char *address)
return true; return true;
} }
bool NetdumpIP::fromString4(const char *address) bool NetdumpIP::fromString4(const char* address)
{ {
// TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats
@ -144,7 +143,7 @@ bool NetdumpIP::fromString4(const char *address)
return true; return true;
} }
bool NetdumpIP::fromString6(const char *address) bool NetdumpIP::fromString6(const char* address)
{ {
// TODO: test test test // TODO: test test test
@ -206,7 +205,8 @@ bool NetdumpIP::fromString6(const char *address)
{ {
for (int i = dots - doubledots - 1; i >= 0; i--) for (int i = dots - doubledots - 1; i >= 0; i--)
{ {
reinterpret_cast<uint16_t*>(rawip)[8 - dots + doubledots + i] = reinterpret_cast<uint16_t*>(rawip)[doubledots + i]; reinterpret_cast<uint16_t*>(rawip)[8 - dots + doubledots + i]
= reinterpret_cast<uint16_t*>(rawip)[doubledots + i];
} }
for (int i = doubledots; i < 8 - dots + doubledots; i++) for (int i = doubledots; i < 8 - dots + doubledots; i++)
{ {
@ -224,7 +224,6 @@ String NetdumpIP::toString()
if (isV6()) if (isV6())
{ {
sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm
} }
else else
{ {
@ -296,7 +295,7 @@ bool NetdumpIP::compareIP(const IPAddress& ip) const
{ {
switch (ipv) switch (ipv)
{ {
case IPversion::UNSET : case IPversion::UNSET:
if (ip.isSet()) if (ip.isSet())
{ {
return false; return false;
@ -306,7 +305,7 @@ bool NetdumpIP::compareIP(const IPAddress& ip) const
return true; return true;
} }
break; break;
case IPversion::IPV4 : case IPversion::IPV4:
if (ip.isV6() || !ip.isSet()) if (ip.isV6() || !ip.isSet())
{ {
return false; return false;
@ -316,7 +315,7 @@ bool NetdumpIP::compareIP(const IPAddress& ip) const
return compareRaw(IPversion::IPV4, rawip, reinterpret_cast<const uint8_t*>(&ip.v4())); return compareRaw(IPversion::IPV4, rawip, reinterpret_cast<const uint8_t*>(&ip.v4()));
} }
break; break;
case IPversion::IPV6 : case IPversion::IPV6:
if (ip.isV4() || !ip.isSet()) if (ip.isV4() || !ip.isSet())
{ {
return false; return false;
@ -326,7 +325,7 @@ bool NetdumpIP::compareIP(const IPAddress& ip) const
return compareRaw(IPversion::IPV6, rawip, reinterpret_cast<const uint8_t*>(ip.raw6())); return compareRaw(IPversion::IPV6, rawip, reinterpret_cast<const uint8_t*>(ip.raw6()));
} }
break; break;
default : default:
return false; return false;
break; break;
} }
@ -336,7 +335,7 @@ bool NetdumpIP::compareIP(const NetdumpIP& nip) const
{ {
switch (ipv) switch (ipv)
{ {
case IPversion::UNSET : case IPversion::UNSET:
if (nip.isSet()) if (nip.isSet())
{ {
return false; return false;
@ -346,7 +345,7 @@ bool NetdumpIP::compareIP(const NetdumpIP& nip) const
return true; return true;
} }
break; break;
case IPversion::IPV4 : case IPversion::IPV4:
if (nip.isV6() || !nip.isSet()) if (nip.isV6() || !nip.isSet())
{ {
return false; return false;
@ -356,7 +355,7 @@ bool NetdumpIP::compareIP(const NetdumpIP& nip) const
return compareRaw(IPversion::IPV4, rawip, nip.rawip); return compareRaw(IPversion::IPV4, rawip, nip.rawip);
} }
break; break;
case IPversion::IPV6 : case IPversion::IPV6:
if (nip.isV4() || !nip.isSet()) if (nip.isV4() || !nip.isSet())
{ {
return false; return false;
@ -366,7 +365,7 @@ bool NetdumpIP::compareIP(const NetdumpIP& nip) const
return compareRaw(IPversion::IPV6, rawip, nip.rawip); return compareRaw(IPversion::IPV6, rawip, nip.rawip);
} }
break; break;
default : default:
return false; return false;
break; break;
} }

View File

@ -22,7 +22,7 @@ public:
NetdumpIP(); NetdumpIP();
NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
NetdumpIP(const uint8_t *address, bool V4 = true); NetdumpIP(const uint8_t* address, bool V4 = true);
NetdumpIP(const IPAddress& ip); NetdumpIP(const IPAddress& ip);
NetdumpIP(const String& ip); NetdumpIP(const String& ip);
@ -31,15 +31,20 @@ public:
return rawip[index]; return rawip[index];
} }
bool fromString(const char *address); bool fromString(const char* address);
String toString(); String toString();
private: private:
enum class IPversion {UNSET, IPV4, IPV6}; enum class IPversion
{
UNSET,
IPV4,
IPV6
};
IPversion ipv = IPversion::UNSET; IPversion ipv = IPversion::UNSET;
uint8_t rawip[16] = {0}; uint8_t rawip[16] = { 0 };
void setV4() void setV4()
{ {
@ -74,10 +79,11 @@ private:
bool compareIP(const IPAddress& ip) const; bool compareIP(const IPAddress& ip) const;
bool compareIP(const NetdumpIP& nip) const; bool compareIP(const NetdumpIP& nip) const;
bool fromString4(const char *address); bool fromString4(const char* address);
bool fromString6(const char *address); bool fromString6(const char* address);
size_t printTo(Print& p); size_t printTo(Print& p);
public: public:
bool operator==(const IPAddress& addr) const bool operator==(const IPAddress& addr) const
{ {
@ -95,7 +101,6 @@ public:
{ {
return !compareIP(addr); return !compareIP(addr);
}; };
}; };
} // namespace NetCapture } // namespace NetCapture

View File

@ -25,7 +25,8 @@
namespace NetCapture namespace NetCapture
{ {
void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size,
PacketDetail pd) const
{ {
if (pd == PacketDetail::NONE) if (pd == PacketDetail::NONE)
{ {
@ -159,21 +160,24 @@ void Packet::MACtoString(int dataIdx, StreamString& sstr) const
sstr.print(':'); sstr.print(':');
} }
} }
} }
void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
{ {
switch (getARPType()) switch (getARPType())
{ {
case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); case 1:
sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(),
getIP(ETH_HDR_LEN + 14).toString().c_str());
break; break;
case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); case 2:
sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str());
MACtoString(ETH_HDR_LEN + 8, sstr); MACtoString(ETH_HDR_LEN + 8, sstr);
break; break;
} }
sstr.printf("\r\n"); sstr.printf("\r\n");
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN, netdumpDetail); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN,
netdumpDetail);
} }
void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const
@ -198,8 +202,10 @@ void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const
sstr.printf_P(PSTR("DR=%d "), t); sstr.printf_P(PSTR("DR=%d "), t);
} }
sstr.printf_P(PSTR("\r\n")); sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(),
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()],
getUdpLen(), netdumpDetail);
} }
void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
@ -207,8 +213,10 @@ void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort());
sstr.printf_P(PSTR("\r\n")); sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(),
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()],
getUdpLen(), netdumpDetail);
} }
void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
@ -217,17 +225,20 @@ void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort());
uint16_t flags = getTcpFlags(); uint16_t flags = getTcpFlags();
sstr.print('['); sstr.print('[');
const char chars [] = "FSRPAUECN"; const char chars[] = "FSRPAUECN";
for (uint8_t i = 0; i < sizeof chars; i++) for (uint8_t i = 0; i < sizeof chars; i++)
if (flags & (1 << i)) if (flags & (1 << i))
{ {
sstr.print(chars[i]); sstr.print(chars[i]);
} }
sstr.print(']'); sstr.print(']');
sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(),
getTcpAck(), getTcpWindow());
sstr.printf_P(PSTR("\r\n")); sstr.printf_P(PSTR("\r\n"));
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(),
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()],
getTcpLen(), netdumpDetail);
} }
void Packet::ICMPtoString(PacketDetail, StreamString& sstr) const void Packet::ICMPtoString(PacketDetail, StreamString& sstr) const
@ -237,20 +248,36 @@ void Packet::ICMPtoString(PacketDetail, StreamString& sstr) const
{ {
switch (getIcmpType()) switch (getIcmpType())
{ {
case 0 : sstr.printf_P(PSTR("ping reply")); break; case 0:
case 8 : sstr.printf_P(PSTR("ping request")); break; sstr.printf_P(PSTR("ping reply"));
default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; break;
case 8:
sstr.printf_P(PSTR("ping request"));
break;
default:
sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType());
break;
} }
} }
if (isIPv6()) if (isIPv6())
{ {
switch (getIcmpType()) switch (getIcmpType())
{ {
case 129 : sstr.printf_P(PSTR("ping reply")); break; case 129:
case 128 : sstr.printf_P(PSTR("ping request")); break; sstr.printf_P(PSTR("ping reply"));
case 135 : sstr.printf_P(PSTR("Neighbour solicitation")); break; break;
case 136 : sstr.printf_P(PSTR("Neighbour advertisement")); break; case 128:
default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; sstr.printf_P(PSTR("ping request"));
break;
case 135:
sstr.printf_P(PSTR("Neighbour solicitation"));
break;
case 136:
sstr.printf_P(PSTR("Neighbour advertisement"));
break;
default:
sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType());
break;
} }
} }
sstr.printf_P(PSTR("\r\n")); sstr.printf_P(PSTR("\r\n"));
@ -260,18 +287,42 @@ void Packet::IGMPtoString(PacketDetail, StreamString& sstr) const
{ {
switch (getIgmpType()) switch (getIgmpType())
{ {
case 1 : sstr.printf_P(PSTR("Create Group Request")); break; case 1:
case 2 : sstr.printf_P(PSTR("Create Group Reply")); break; sstr.printf_P(PSTR("Create Group Request"));
case 3 : sstr.printf_P(PSTR("Join Group Request")); break; break;
case 4 : sstr.printf_P(PSTR("Join Group Reply")); break; case 2:
case 5 : sstr.printf_P(PSTR("Leave Group Request")); break; sstr.printf_P(PSTR("Create Group Reply"));
case 6 : sstr.printf_P(PSTR("Leave Group Reply")); break; break;
case 7 : sstr.printf_P(PSTR("Confirm Group Request")); break; case 3:
case 8 : sstr.printf_P(PSTR("Confirm Group Reply")); break; sstr.printf_P(PSTR("Join Group Request"));
case 0x11 : sstr.printf_P(PSTR("Group Membership Query")); break; break;
case 0x12 : sstr.printf_P(PSTR("IGMPv1 Membership Report")); break; case 4:
case 0x22 : sstr.printf_P(PSTR("IGMPv3 Membership Report")); break; sstr.printf_P(PSTR("Join Group Reply"));
default: sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType()); break; break;
case 5:
sstr.printf_P(PSTR("Leave Group Request"));
break;
case 6:
sstr.printf_P(PSTR("Leave Group Reply"));
break;
case 7:
sstr.printf_P(PSTR("Confirm Group Request"));
break;
case 8:
sstr.printf_P(PSTR("Confirm Group Reply"));
break;
case 0x11:
sstr.printf_P(PSTR("Group Membership Query"));
break;
case 0x12:
sstr.printf_P(PSTR("IGMPv1 Membership Report"));
break;
case 0x22:
sstr.printf_P(PSTR("IGMPv3 Membership Report"));
break;
default:
sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType());
break;
} }
sstr.printf_P(PSTR("\r\n")); sstr.printf_P(PSTR("\r\n"));
} }
@ -281,7 +332,8 @@ void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const
sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str());
sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType());
printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail);
printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen(), netdumpDetail); printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()],
getIpTotalLen() - getIpHdrLen(), netdumpDetail);
} }
void Packet::UKNWtoString(PacketDetail, StreamString& sstr) const void Packet::UKNWtoString(PacketDetail, StreamString& sstr) const
@ -298,13 +350,13 @@ const String Packet::toString() const
return toString(PacketDetail::NONE); return toString(PacketDetail::NONE);
} }
const String Packet::toString(PacketDetail netdumpDetail) const const String Packet::toString(PacketDetail netdumpDetail) const
{ {
StreamString sstr; StreamString sstr;
sstr.reserve(128); sstr.reserve(128);
sstr.printf_P(PSTR("%d %3s %-4s "), netif_idx, out ? "out" : "in ", packetType().toString().c_str()); sstr.printf_P(PSTR("%d %3s %-4s "), netif_idx, out ? "out" : "in ",
packetType().toString().c_str());
if (netdumpDetail == PacketDetail::RAW) if (netdumpDetail == PacketDetail::RAW)
{ {
@ -320,56 +372,56 @@ const String Packet::toString(PacketDetail netdumpDetail) const
switch (thisPacketType) switch (thisPacketType)
{ {
case PacketType::ARP : case PacketType::ARP:
{ {
ARPtoString(netdumpDetail, sstr); ARPtoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::MDNS : case PacketType::MDNS:
case PacketType::DNS : case PacketType::DNS:
{ {
DNStoString(netdumpDetail, sstr); DNStoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::SSDP : case PacketType::SSDP:
case PacketType::DHCP : case PacketType::DHCP:
case PacketType::WSDD : case PacketType::WSDD:
case PacketType::NETBIOS : case PacketType::NETBIOS:
case PacketType::SMB : case PacketType::SMB:
case PacketType::OTA : case PacketType::OTA:
case PacketType::UDP : case PacketType::UDP:
{ {
UDPtoString(netdumpDetail, sstr); UDPtoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::TCP : case PacketType::TCP:
case PacketType::HTTP : case PacketType::HTTP:
{ {
TCPtoString(netdumpDetail, sstr); TCPtoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::ICMP : case PacketType::ICMP:
{ {
ICMPtoString(netdumpDetail, sstr); ICMPtoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::IGMP : case PacketType::IGMP:
{ {
IGMPtoString(netdumpDetail, sstr); IGMPtoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::IPv4 : case PacketType::IPv4:
case PacketType::IPv6 : case PacketType::IPv6:
{ {
IPtoString(netdumpDetail, sstr); IPtoString(netdumpDetail, sstr);
break; break;
} }
case PacketType::UKNW : case PacketType::UKNW:
{ {
UKNWtoString(netdumpDetail, sstr); UKNWtoString(netdumpDetail, sstr);
break; break;
} }
default : default:
{ {
sstr.printf_P(PSTR("Non identified packet\r\n")); sstr.printf_P(PSTR("Non identified packet\r\n"));
break; break;

View File

@ -37,8 +37,8 @@ int constexpr ETH_HDR_LEN = 14;
class Packet class Packet
{ {
public: public:
Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) :
: packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s)
{ {
setPacketTypes(); setPacketTypes();
}; };
@ -93,7 +93,8 @@ public:
}; };
uint16_t getIpHdrLen() const uint16_t getIpHdrLen() const
{ {
return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2 : 40 ; // IPv6 is fixed length return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2
: 40; // IPv6 is fixed length
} }
uint16_t getIpTotalLen() const uint16_t getIpTotalLen() const
{ {
@ -118,10 +119,10 @@ public:
uint8_t getTcpHdrLen() const uint8_t getTcpHdrLen() const
{ {
return isTCP() ? (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4 : 0; return isTCP() ? (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4 : 0;
};//Header len is in multiple of 4 bytes }; // Header len is in multiple of 4 bytes
uint16_t getTcpLen() const uint16_t getTcpLen() const
{ {
return isTCP() ? getIpTotalLen() - getIpHdrLen() - getTcpHdrLen() : 0 ; return isTCP() ? getIpTotalLen() - getIpHdrLen() - getTcpHdrLen() : 0;
}; };
uint8_t getIcmpType() const uint8_t getIcmpType() const
@ -277,14 +278,13 @@ public:
const String toString() const; const String toString() const;
const String toString(PacketDetail netdumpDetail) const; const String toString(PacketDetail netdumpDetail) const;
void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; void printDetail(Print& out, const String& indent, const char* data, size_t size,
PacketDetail pd) const;
const PacketType packetType() const; const PacketType packetType() const;
const std::vector<PacketType>& allPacketTypes() const; const std::vector<PacketType>& allPacketTypes() const;
private: private:
void setPacketType(PacketType); void setPacketType(PacketType);
void setPacketTypes(); void setPacketTypes();
@ -298,7 +298,6 @@ private:
void IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; void IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const;
void UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const; void UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const;
time_t packetTime; time_t packetTime;
int netif_idx; int netif_idx;
const char* data; const char* data;

View File

@ -10,33 +10,50 @@
namespace NetCapture namespace NetCapture
{ {
PacketType::PacketType() PacketType::PacketType() { }
{
}
String PacketType::toString() const String PacketType::toString() const
{ {
switch (ptype) switch (ptype)
{ {
case PType::ARP : return PSTR("ARP"); case PType::ARP:
case PType::IP : return PSTR("IP"); return PSTR("ARP");
case PType::UDP : return PSTR("UDP"); case PType::IP:
case PType::MDNS : return PSTR("MDNS"); return PSTR("IP");
case PType::DNS : return PSTR("DNS"); case PType::UDP:
case PType::SSDP : return PSTR("SSDP"); return PSTR("UDP");
case PType::DHCP : return PSTR("DHCP"); case PType::MDNS:
case PType::WSDD : return PSTR("WSDD"); return PSTR("MDNS");
case PType::NETBIOS: return PSTR("NBIO"); case PType::DNS:
case PType::SMB : return PSTR("SMB"); return PSTR("DNS");
case PType::OTA : return PSTR("OTA"); case PType::SSDP:
case PType::TCP : return PSTR("TCP"); return PSTR("SSDP");
case PType::HTTP : return PSTR("HTTP"); case PType::DHCP:
case PType::ICMP : return PSTR("ICMP"); return PSTR("DHCP");
case PType::IGMP : return PSTR("IGMP"); case PType::WSDD:
case PType::IPv4: return PSTR("IPv4"); return PSTR("WSDD");
case PType::IPv6: return PSTR("IPv6"); case PType::NETBIOS:
case PType::UKNW : return PSTR("UKNW"); return PSTR("NBIO");
default : return PSTR("ERR"); case PType::SMB:
return PSTR("SMB");
case PType::OTA:
return PSTR("OTA");
case PType::TCP:
return PSTR("TCP");
case PType::HTTP:
return PSTR("HTTP");
case PType::ICMP:
return PSTR("ICMP");
case PType::IGMP:
return PSTR("IGMP");
case PType::IPv4:
return PSTR("IPv4");
case PType::IPv6:
return PSTR("IPv6");
case PType::UKNW:
return PSTR("UKNW");
default:
return PSTR("ERR");
}; };
} }

View File

@ -15,7 +15,6 @@ namespace NetCapture
class PacketType class PacketType
{ {
public: public:
enum PType : int enum PType : int
{ {
ARP, ARP,

View File

@ -48,9 +48,7 @@ void loop() {
for (int analogPin = 0; analogPin < 3; analogPin++) { for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin); int sensor = analogRead(analogPin);
dataString += String(sensor); dataString += String(sensor);
if (analogPin < 2) { if (analogPin < 2) { dataString += ","; }
dataString += ",";
}
} }
// open the file. note that only one file can be open at a time, // open the file. note that only one file can be open at a time,
@ -65,16 +63,5 @@ void loop() {
Serial.println(dataString); Serial.println(dataString);
} }
// if the file isn't open, pop up an error: // if the file isn't open, pop up an error:
else { else { Serial.println("error opening datalog.txt"); }
Serial.println("error opening datalog.txt");
}
} }

View File

@ -45,17 +45,11 @@ void setup() {
// if the file is available, write to it: // if the file is available, write to it:
if (dataFile) { if (dataFile) {
while (dataFile.available()) { while (dataFile.available()) { Serial.write(dataFile.read()); }
Serial.write(dataFile.read());
}
dataFile.close(); dataFile.close();
} }
// if the file isn't open, pop up an error: // if the file isn't open, pop up an error:
else { else { Serial.println("error opening datalog.txt"); }
Serial.println("error opening datalog.txt");
}
}
void loop() {
} }
void loop() {}

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