From a2bbb983d30fec5a8eb24310c1facaed53ff7976 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 23 Dec 2018 19:07:56 +0100 Subject: [PATCH 01/10] use newlib api in new mDNS, fix host using mDNS --- libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp | 6 +-- libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp | 46 +++++++++--------- libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp | 48 +++++++++---------- tests/host/Makefile | 1 + 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp index 483d1a2577..81d517f806 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp @@ -203,7 +203,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea u8HostOrServiceReplies |= (pService->m_u8ReplyMask |= u8ReplyMaskForQuestion); DEBUG_EX_INFO(if (u8ReplyMaskForQuestion) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Service reply needed for (%s.%s.%s): %u (%s)\n"), (pService->m_pcName ?: m_pcHostname), pService->m_pcService, pService->m_pcProtocol, u8ReplyMaskForQuestion, IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()); } ); /*if ((u8ReplyMaskForQuestion) && - (0 == os_strcmp("hap", pService->m_pcService))) { + (0 == strcmp("hap", pService->m_pcService))) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Service reply needed for (%s.%s.%s): %u (%s)\n"), (pService->m_pcName ?: m_pcHostname), pService->m_pcService, pService->m_pcProtocol, u8ReplyMaskForQuestion, IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()); }*/ @@ -386,7 +386,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea if ((u8ServiceMatchMask) && // The RR in the known answer matches an RR we are planning to send, AND ((MDNS_SERVICE_TTL / 2) <= pKnownRRAnswer->m_u32TTL)) { // The TTL of the known answer is longer than half of the new service TTL (4500s) - /*if ((0 == os_strcmp("hap", pService->m_pcService))) { + /*if ((0 == strcmp("hap", pService->m_pcService))) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Known answer for (%s.%s.%s): %u (%s) %u\n"), (pService->m_pcName ?: m_pcHostname), pService->m_pcService, pService->m_pcProtocol, pKnownRRAnswer->answerType(), IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str(), pKnownRRAnswer->m_u32TTL); }*/ @@ -484,7 +484,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea u8ReplyNeeded |= pService->m_u8ReplyMask; if ((u8ReplyNeeded) && - (0 == os_strcmp("hap", pService->m_pcService))) { + (0 == strcmp("hap", pService->m_pcService))) { DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Sending service reply for (%s.%s.%s): %u (%s)\n"), (pService->m_pcName ?: m_pcHostname), pService->m_pcService, pService->m_pcProtocol, u8ReplyNeeded, IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str());); } } diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp index e8a555e4cb..c2503142dc 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp @@ -102,19 +102,19 @@ namespace MDNSImplementation { const char* pFoundDivider = strrstr(p_rpcDomain, pcDivider); if (pFoundDivider) { // maybe already extended char* pEnd = 0; - unsigned long ulIndex = strtoul((pFoundDivider + os_strlen(pcDivider)), &pEnd, 10); + unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10); if ((ulIndex) && - ((pEnd - p_rpcDomain) == os_strlen(p_rpcDomain)) && + ((pEnd - p_rpcDomain) == strlen(p_rpcDomain)) && (!*pEnd)) { // Valid (old) index found char acIndexBuffer[16]; sprintf(acIndexBuffer, "%lu", (++ulIndex)); - size_t stLength = ((pFoundDivider - p_rpcDomain + os_strlen(pcDivider)) + os_strlen(acIndexBuffer) + 1); + size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider)) + strlen(acIndexBuffer) + 1); char* pNewHostname = new char[stLength]; if (pNewHostname) { - memcpy(pNewHostname, p_rpcDomain, (pFoundDivider - p_rpcDomain + os_strlen(pcDivider))); - pNewHostname[pFoundDivider - p_rpcDomain + os_strlen(pcDivider)] = 0; - os_strcat(pNewHostname, acIndexBuffer); + memcpy(pNewHostname, p_rpcDomain, (pFoundDivider - p_rpcDomain + strlen(pcDivider))); + pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0; + strcat(pNewHostname, acIndexBuffer); delete[] p_rpcDomain; p_rpcDomain = pNewHostname; @@ -131,7 +131,7 @@ namespace MDNSImplementation { } if (!pFoundDivider) { // not yet extended (or failed to increment extension) -> start indexing - size_t stLength = os_strlen(p_rpcDomain) + (os_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]; if (pNewHostname) { sprintf(pNewHostname, "%s%s2", p_rpcDomain, pcDivider); @@ -150,10 +150,10 @@ namespace MDNSImplementation { // No given host domain, use base or default const char* cpcDefaultName = (p_pcDefaultDomain ?: "esp8266"); - size_t stLength = os_strlen(cpcDefaultName) + 1; // '\0' + size_t stLength = strlen(cpcDefaultName) + 1; // '\0' p_rpcDomain = new char[stLength]; if (p_rpcDomain) { - os_strncpy(p_rpcDomain, cpcDefaultName, stLength); + strncpy(p_rpcDomain, cpcDefaultName, stLength); bResult = true; } else { @@ -365,7 +365,7 @@ bool MDNSResponder::_setHostname(const char* p_pcHostname) { size_t stLength = 0; if ((p_pcHostname) && - (MDNS_DOMAIN_LABEL_MAXLENGTH >= (stLength = os_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 if ((bResult = (0 != (m_pcHostname = new char[stLength + 1])))) { #ifdef MDNS_FORCE_LOWERCASE_HOSTNAME @@ -375,7 +375,7 @@ bool MDNSResponder::_setHostname(const char* p_pcHostname) { } m_pcHostname[i] = 0; #else - os_strncpy(m_pcHostname, p_pcHostname, (stLength + 1)); + strncpy(m_pcHostname, p_pcHostname, (stLength + 1)); #endif } } @@ -409,11 +409,11 @@ MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName stcMDNSService* pService = 0; if (((!p_pcName) || - (MDNS_DOMAIN_LABEL_MAXLENGTH >= os_strlen(p_pcName))) && + (MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcName))) && (p_pcService) && - (MDNS_SERVICE_NAME_LENGTH >= os_strlen(p_pcService)) && + (MDNS_SERVICE_NAME_LENGTH >= strlen(p_pcService)) && (p_pcProtocol) && - (MDNS_SERVICE_PROTOCOL_LENGTH >= os_strlen(p_pcProtocol)) && + (MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) && (p_u16Port) && (0 != (pService = new stcMDNSService)) && (pService->setName(p_pcName ?: m_pcHostname)) && @@ -529,23 +529,23 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder: (p_pcKey) && (MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() + 1 + // Length byte - (p_pcKey ? os_strlen(p_pcKey) : 0) + + (p_pcKey ? strlen(p_pcKey) : 0) + 1 + // '=' - (p_pcValue ? os_strlen(p_pcValue) : 0)))) { + (p_pcValue ? strlen(p_pcValue) : 0)))) { pTxt = new stcMDNSServiceTxt; if (pTxt) { - size_t stLength = (p_pcKey ? os_strlen(p_pcKey) : 0); + size_t stLength = (p_pcKey ? strlen(p_pcKey) : 0); pTxt->m_pcKey = new char[stLength + 1]; if (pTxt->m_pcKey) { - os_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) { - stLength = (p_pcValue ? os_strlen(p_pcValue) : 0); + stLength = (p_pcValue ? strlen(p_pcValue) : 0); pTxt->m_pcValue = new char[stLength + 1]; if (pTxt->m_pcValue) { - os_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; @@ -579,8 +579,8 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_updateServiceTxt(MDNSResponder if ((p_pService) && (p_pTxt) && (MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() - - (p_pTxt->m_pcValue ? os_strlen(p_pTxt->m_pcValue) : 0) + - (p_pcValue ? os_strlen(p_pcValue) : 0)))) { + (p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0) + + (p_pcValue ? strlen(p_pcValue) : 0)))) { p_pTxt->update(p_pcValue); p_pTxt->m_bTemp = p_bTemp; } @@ -616,7 +616,7 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::s if ((p_pService) && (p_pcKey) && - (os_strlen(p_pcKey))) { + (strlen(p_pcKey))) { stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey); if (pTxt) { diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp index c8ceeb62ac..c30094f580 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp @@ -126,7 +126,7 @@ bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey, releaseKey(); if (p_stLength) { if (allocKey(p_stLength)) { - os_strncpy(m_pcKey, p_pcKey, p_stLength); + strncpy(m_pcKey, p_pcKey, p_stLength); m_pcKey[p_stLength] = 0; bResult = true; } @@ -139,7 +139,7 @@ bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey, */ bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey) { - return setKey(p_pcKey, (p_pcKey ? os_strlen(p_pcKey) : 0)); + return setKey(p_pcKey, (p_pcKey ? strlen(p_pcKey) : 0)); } /* @@ -177,7 +177,7 @@ bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue, releaseValue(); if (p_stLength) { if (allocValue(p_stLength)) { - os_strncpy(m_pcValue, p_pcValue, p_stLength); + strncpy(m_pcValue, p_pcValue, p_stLength); m_pcValue[p_stLength] = 0; bResult = true; } @@ -193,7 +193,7 @@ bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue, */ bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue) { - return setValue(p_pcValue, (p_pcValue ? os_strlen(p_pcValue) : 0)); + return setValue(p_pcValue, (p_pcValue ? strlen(p_pcValue) : 0)); } /* @@ -237,9 +237,9 @@ size_t MDNSResponder::stcMDNSServiceTxt::length(void) const { size_t stLength = 0; if (m_pcKey) { - stLength += os_strlen(m_pcKey); // Key + stLength += strlen(m_pcKey); // Key stLength += 1; // '=' - stLength += (m_pcValue ? os_strlen(m_pcValue) : 0); // Value + stLength += (m_pcValue ? strlen(m_pcValue) : 0); // Value } return stLength; } @@ -461,15 +461,15 @@ bool MDNSResponder::stcMDNSServiceTxts::c_str(char* p_pcBuffer) { *p_pcBuffer = 0; for (stcMDNSServiceTxt* pTxt=m_pTxts; ((bResult) && (pTxt)); pTxt = pTxt->m_pNext) { size_t stLength; - if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? os_strlen(pTxt->m_pcKey) : 0))))) { + if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? strlen(pTxt->m_pcKey) : 0))))) { if (pTxt != m_pTxts) { *p_pcBuffer++ = ';'; } - os_strncpy(p_pcBuffer, pTxt->m_pcKey, stLength); p_pcBuffer[stLength] = 0; + strncpy(p_pcBuffer, pTxt->m_pcKey, stLength); p_pcBuffer[stLength] = 0; p_pcBuffer += stLength; *p_pcBuffer++ = '='; - if ((stLength = (pTxt->m_pcValue ? os_strlen(pTxt->m_pcValue) : 0))) { - os_strncpy(p_pcBuffer, pTxt->m_pcValue, stLength); p_pcBuffer[stLength] = 0; + if ((stLength = (pTxt->m_pcValue ? strlen(pTxt->m_pcValue) : 0))) { + strncpy(p_pcBuffer, pTxt->m_pcValue, stLength); p_pcBuffer[stLength] = 0; p_pcBuffer += stLength; } } @@ -503,12 +503,12 @@ bool MDNSResponder::stcMDNSServiceTxts::buffer(char* p_pcBuffer) { for (stcMDNSServiceTxt* pTxt=m_pTxts; ((bResult) && (pTxt)); pTxt = pTxt->m_pNext) { *(unsigned char*)p_pcBuffer++ = pTxt->length(); size_t stLength; - if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? os_strlen(pTxt->m_pcKey) : 0))))) { - os_memcpy(p_pcBuffer, pTxt->m_pcKey, stLength); + if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? strlen(pTxt->m_pcKey) : 0))))) { + memcpy(p_pcBuffer, pTxt->m_pcKey, stLength); p_pcBuffer += stLength; *p_pcBuffer++ = '='; - if ((stLength = (pTxt->m_pcValue ? os_strlen(pTxt->m_pcValue) : 0))) { - os_memcpy(p_pcBuffer, pTxt->m_pcValue, stLength); + if ((stLength = (pTxt->m_pcValue ? strlen(pTxt->m_pcValue) : 0))) { + memcpy(p_pcBuffer, pTxt->m_pcValue, stLength); p_pcBuffer += stLength; } } @@ -532,7 +532,7 @@ bool MDNSResponder::stcMDNSServiceTxts::compare(const MDNSResponder::stcMDNSServ bResult = ((pOtherTxt) && (pTxt->m_pcValue) && (pOtherTxt->m_pcValue) && - (os_strlen(pTxt->m_pcValue) == os_strlen(pOtherTxt->m_pcValue)) && + (strlen(pTxt->m_pcValue) == strlen(pOtherTxt->m_pcValue)) && (0 == strcmp(pTxt->m_pcValue, pOtherTxt->m_pcValue))); } // Compare B->A @@ -541,7 +541,7 @@ bool MDNSResponder::stcMDNSServiceTxts::compare(const MDNSResponder::stcMDNSServ bResult = ((pTxt) && (pOtherTxt->m_pcValue) && (pTxt->m_pcValue) && - (os_strlen(pOtherTxt->m_pcValue) == os_strlen(pTxt->m_pcValue)) && + (strlen(pOtherTxt->m_pcValue) == strlen(pTxt->m_pcValue)) && (0 == strcmp(pOtherTxt->m_pcValue, pTxt->m_pcValue))); } } @@ -660,7 +660,7 @@ bool MDNSResponder::stcMDNS_RRDomain::addLabel(const char* p_pcLabel, bool bResult = false; size_t stLength = (p_pcLabel - ? (os_strlen(p_pcLabel) + (p_bPrependUnderline ? 1 : 0)) + ? (strlen(p_pcLabel) + (p_bPrependUnderline ? 1 : 0)) : 0); if ((MDNS_DOMAIN_LABEL_MAXLENGTH >= stLength) && (MDNS_DOMAIN_MAXLENGTH >= (m_u16NameLength + (1 + stLength)))) { @@ -673,7 +673,7 @@ bool MDNSResponder::stcMDNS_RRDomain::addLabel(const char* p_pcLabel, m_acName[m_u16NameLength++] = '_'; --stLength; } - os_strncpy(&(m_acName[m_u16NameLength]), p_pcLabel, stLength); m_acName[m_u16NameLength + stLength] = 0; + strncpy(&(m_acName[m_u16NameLength]), p_pcLabel, stLength); m_acName[m_u16NameLength + stLength] = 0; m_u16NameLength += stLength; } bResult = true; @@ -1235,10 +1235,10 @@ bool MDNSResponder::stcMDNSService::setName(const char* p_pcName) { bool bResult = false; releaseName(); - size_t stLength = (p_pcName ? os_strlen(p_pcName) : 0); + size_t stLength = (p_pcName ? strlen(p_pcName) : 0); if (stLength) { if ((bResult = (0 != (m_pcName = new char[stLength + 1])))) { - os_strncpy(m_pcName, p_pcName, stLength); + strncpy(m_pcName, p_pcName, stLength); m_pcName[stLength] = 0; } } @@ -1268,10 +1268,10 @@ bool MDNSResponder::stcMDNSService::setService(const char* p_pcService) { bool bResult = false; releaseService(); - size_t stLength = (p_pcService ? os_strlen(p_pcService) : 0); + size_t stLength = (p_pcService ? strlen(p_pcService) : 0); if (stLength) { if ((bResult = (0 != (m_pcService = new char[stLength + 1])))) { - os_strncpy(m_pcService, p_pcService, stLength); + strncpy(m_pcService, p_pcService, stLength); m_pcService[stLength] = 0; } } @@ -1301,10 +1301,10 @@ bool MDNSResponder::stcMDNSService::setProtocol(const char* p_pcProtocol) { bool bResult = false; releaseProtocol(); - size_t stLength = (p_pcProtocol ? os_strlen(p_pcProtocol) : 0); + size_t stLength = (p_pcProtocol ? strlen(p_pcProtocol) : 0); if (stLength) { if ((bResult = (0 != (m_pcProtocol = new char[stLength + 1])))) { - os_strncpy(m_pcProtocol, p_pcProtocol, stLength); + strncpy(m_pcProtocol, p_pcProtocol, stLength); m_pcProtocol[stLength] = 0; } } diff --git a/tests/host/Makefile b/tests/host/Makefile index 2c5d6c7cbd..a795dcc68c 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -237,6 +237,7 @@ ARDUINO_LIBS := \ ESP8266mDNS/src/LEAmDNS_Helpers.cpp \ ESP8266mDNS/src/LEAmDNS_Structs.cpp \ ESP8266mDNS/src/LEAmDNS_Transfer.cpp \ + ESP8266mDNS/src/ESP8266mDNS.cpp \ ArduinoOTA/ArduinoOTA.cpp \ DNSServer/src/DNSServer.cpp \ ESP8266AVRISP/src/ESP8266AVRISP.cpp \ From 6d993b5d09fbb245e6871809f0e07db4d8d6ebbc Mon Sep 17 00:00:00 2001 From: david gauchard Date: Tue, 25 Dec 2018 23:40:21 +0100 Subject: [PATCH 02/10] fix comparison --- libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp index c2503142dc..d4d0c3edf7 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp @@ -104,7 +104,7 @@ namespace MDNSImplementation { char* pEnd = 0; unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10); if ((ulIndex) && - ((pEnd - p_rpcDomain) == strlen(p_rpcDomain)) && + ((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain)) && (!*pEnd)) { // Valid (old) index found char acIndexBuffer[16]; From 88296f3db05b0508463de6ad3b546691c8564a3e Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Tue, 8 Jan 2019 16:53:34 +0100 Subject: [PATCH 03/10] host: udp fixes (seek) --- tests/host/common/UdpContextSocket.cpp | 11 ++++++++--- tests/host/common/esp8266_peri.h | 2 ++ tests/host/common/include/UdpContext.h | 10 +--------- tests/host/common/mock.h | 7 ++++++- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/host/common/UdpContextSocket.cpp b/tests/host/common/UdpContextSocket.cpp index d30a6c1246..f257c57c94 100644 --- a/tests/host/common/UdpContextSocket.cpp +++ b/tests/host/common/UdpContextSocket.cpp @@ -150,12 +150,17 @@ size_t mockUDPPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, c return retsize; } -size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize) +void mockUDPSwallow (size_t copied, char* ccinbuf, size_t& ccinbufsize) { - size_t copied = mockUDPPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize); - // swallow (XXX use a circular buffer?) + // poor man buffer memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied); ccinbufsize -= copied; +} + +size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize) +{ + size_t copied = mockUDPPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize); + mockUDPSwallow(copied, ccinbuf, ccinbufsize); return copied; } diff --git a/tests/host/common/esp8266_peri.h b/tests/host/common/esp8266_peri.h index b7b17675b8..d9dfd50ed4 100644 --- a/tests/host/common/esp8266_peri.h +++ b/tests/host/common/esp8266_peri.h @@ -3,5 +3,7 @@ #define FAKE_ESP8266_PERI_H const int GPI = 0; +const int GPO = 0; +const int GP16I = 0; #endif \ No newline at end of file diff --git a/tests/host/common/include/UdpContext.h b/tests/host/common/include/UdpContext.h index 572decbb3a..ebeedb0907 100644 --- a/tests/host/common/include/UdpContext.h +++ b/tests/host/common/include/UdpContext.h @@ -79,20 +79,12 @@ class UdpContext _sock = -1; } -#if 0 void setMulticastInterface(const ip_addr_t& addr) { (void)addr; // user multicast, and this is how it works with posix: send to multicast address: _dst.addr = staticMCastAddr; } -#endif - void setMulticastInterface(const ip_addr_t* addr) - { - (void)addr; - // user multicast, and this is how it works with posix: send to multicast address: - _dst.addr = staticMCastAddr; - } void setMulticastTTL(int ttl) { @@ -118,12 +110,12 @@ class UdpContext void seek(const size_t pos) { - fprintf(stderr, MOCK "TODO: implement UDP offset\n"); if (!isValidOffset(pos)) { fprintf(stderr, MOCK "UDPContext::seek too far (%zd >= %zd)\n", pos, _inbufsize); exit(EXIT_FAILURE); } + mockUDPSwallow(pos, _inbuf, _inbufsize); } bool isValidOffset(const size_t pos) const { diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index d9c6cc3b87..e940cec49f 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -91,7 +91,7 @@ extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to #ifdef __cplusplus #ifndef CCBUFSIZE -#define CCBUFSIZE 8192 +#define CCBUFSIZE 65536 #endif // tcp @@ -109,6 +109,7 @@ size_t mockUDPFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& size_t mockUDPPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize); size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize); size_t mockUDPWrite (int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4, uint16_t port); +void mockUDPSwallow (size_t copied, char* ccinbuf, size_t& ccinbufsize); class UdpContext; void register_udp (int sock, UdpContext* udp = nullptr); @@ -142,4 +143,8 @@ class InterruptLock { }; // +#include + +// + #endif // __cplusplus From cdbb75cd1bdea7ae5008c10fcba0a371ad6c23ec Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 9 Jan 2019 19:03:56 +0100 Subject: [PATCH 04/10] persistent spiffs + fixes --- tests/host/Makefile | 2 + tests/host/common/ArduinoMain.cpp | 83 ++++++++++++------------- tests/host/common/ArduinoMainSpiffs.cpp | 22 +++++++ tests/host/common/ArduinoMainUdp.cpp | 65 +++++++++++++++++++ tests/host/common/MockSerial.cpp | 1 + tests/host/common/mock.h | 6 ++ tests/host/common/spiffs_mock.cpp | 44 ++++++++++--- tests/host/common/spiffs_mock.h | 8 +-- 8 files changed, 174 insertions(+), 57 deletions(-) create mode 100644 tests/host/common/ArduinoMainSpiffs.cpp create mode 100644 tests/host/common/ArduinoMainUdp.cpp diff --git a/tests/host/Makefile b/tests/host/Makefile index a795dcc68c..09babd21d4 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -82,6 +82,8 @@ MOCK_CPP_FILES := $(MOCK_CPP_FILES_COMMON) $(addprefix common/,\ MOCK_CPP_FILES_EMU := $(MOCK_CPP_FILES_COMMON) $(addprefix common/,\ ArduinoMain.cpp \ + ArduinoMainUdp.cpp \ + ArduinoMainSpiffs.cpp \ user_interface.cpp \ ) diff --git a/tests/host/common/ArduinoMain.cpp b/tests/host/common/ArduinoMain.cpp index 900b865aef..0f06b17260 100644 --- a/tests/host/common/ArduinoMain.cpp +++ b/tests/host/common/ArduinoMain.cpp @@ -32,37 +32,13 @@ #include #include // wifi_get_ip_info() -#include -#include "lwip/opt.h" -#include "lwip/udp.h" -#include "lwip/inet.h" -#include "lwip/igmp.h" -#include "lwip/mem.h" -#include -#include - +#include #include // usleep #include -#include - -#if 0 -#include "../common/spiffs_mock.h" -#include -SPIFFS_MOCK_DECLARE(/*size_kb*/1024, /(blovk_kb*/8, /*page_b*/512); -#endif - -std::map udps; - -void register_udp (int sock, UdpContext* udp) -{ - if (udp) - udps[sock] = udp; - else - udps.erase(sock); -} - +bool user_exit = false; const char* host_interface = nullptr; +size_t spiffs_kb = 1024; void help (const char* argv0, int exitcode) { @@ -73,7 +49,9 @@ void help (const char* argv0, int exitcode) " -i - use this interface for IP address\n" " -l - bind tcp/udp servers to interface only (not 0.0.0.0)\n" " -f - no throttle (possibly 100%%CPU)\n" - , argv0); + " -S - spiffs size in KBytes (default: %zd)\n" + " (negative value will force mismatched size)\n" + , argv0, spiffs_kb); exit(exitcode); } @@ -83,15 +61,38 @@ static struct option options[] = { "fast", no_argument, NULL, 'f' }, { "local", no_argument, NULL, 'l' }, { "interface", required_argument, NULL, 'i' }, + { "spiffskb", required_argument, NULL, 'S' }, }; +void save () +{ + mock_stop_spiffs(); +} + + +void control_c (int sig) +{ + (void)sig; + + if (user_exit) + { + fprintf(stderr, MOCK "stuck, killing\n"); + save(); + abort(); + } + user_exit = true; +} + int main (int argc, char* const argv []) { + signal(SIGINT, control_c); + bool fast = false; + for (;;) { - int n = getopt_long(argc, argv, "hlfi:", options, NULL); + int n = getopt_long(argc, argv, "hlfi:S:", options, NULL); if (n < 0) break; switch (n) @@ -108,36 +109,32 @@ int main (int argc, char* const argv []) case 'f': fast = true; break; + case 'S': + spiffs_kb = atoi(optarg); + break; default: fprintf(stderr, MOCK "bad option '%c'\n", n); exit(EXIT_FAILURE); } } + mock_start_spiffs(spiffs_kb); + // setup global global_ipv4_netfmt wifi_get_ip_info(0, nullptr); setup(); - while (true) + while (!user_exit) { if (!fast) usleep(10000); // not 100% cpu loop(); - // check incoming udp - for (auto& udp: udps) - { - pollfd p; - p.fd = udp.first; - p.events = POLLIN; - if (poll(&p, 1, 0) && p.revents == POLLIN) - { - fprintf(stderr, MOCK "UDP poll(%d) -> cb\r", p.fd); - udp.second->mock_cb(); - } - } + check_incoming_udp(); } + + save(); + return 0; } - diff --git a/tests/host/common/ArduinoMainSpiffs.cpp b/tests/host/common/ArduinoMainSpiffs.cpp new file mode 100644 index 0000000000..9b47c56f4f --- /dev/null +++ b/tests/host/common/ArduinoMainSpiffs.cpp @@ -0,0 +1,22 @@ + +#include "spiffs_mock.h" + +#if 0 +#include "../common/spiffs_mock.h" +#include +SPIFFS_MOCK_DECLARE(/*size_kb*/64, /*block_kb*/8, /*page_b*/512, true); +#endif + +SpiffsMock* spiffs_mock = nullptr; + +void mock_start_spiffs (size_t size_kb, size_t block_kb, size_t page_b) +{ + spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, true); +} + +void mock_stop_spiffs () +{ + delete spiffs_mock; + spiffs_mock = nullptr; +} + diff --git a/tests/host/common/ArduinoMainUdp.cpp b/tests/host/common/ArduinoMainUdp.cpp new file mode 100644 index 0000000000..99f567fe50 --- /dev/null +++ b/tests/host/common/ArduinoMainUdp.cpp @@ -0,0 +1,65 @@ +/* + Arduino emulator main loop + Copyright (c) 2018 david gauchard. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal with the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + - The names of its contributors may not be used to endorse or promote + products derived from this Software without specific prior written + permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS WITH THE SOFTWARE. +*/ + +#include "lwip/opt.h" +#include "lwip/udp.h" +#include "lwip/inet.h" +#include "lwip/igmp.h" +#include "lwip/mem.h" +#include +#include +#include + +std::map udps; + +void register_udp (int sock, UdpContext* udp) +{ + if (udp) + udps[sock] = udp; + else + udps.erase(sock); +} + +void check_incoming_udp () +{ + // check incoming udp + for (auto& udp: udps) + { + pollfd p; + p.fd = udp.first; + p.events = POLLIN; + if (poll(&p, 1, 0) && p.revents == POLLIN) + { + fprintf(stderr, MOCK "UDP poll(%d) -> cb\r", p.fd); + udp.second->mock_cb(); + } + } +} diff --git a/tests/host/common/MockSerial.cpp b/tests/host/common/MockSerial.cpp index 19790dc48b..eedcaed115 100644 --- a/tests/host/common/MockSerial.cpp +++ b/tests/host/common/MockSerial.cpp @@ -40,6 +40,7 @@ HardwareSerial::HardwareSerial (int uart_nr) { if (uart_nr != 0) fprintf(stderr, MOCK "FIXME HardwareSerial::HardwareSerial(%d)\n", uart_nr); + _uart = (decltype(_uart))1; // not used, for 'while (!Serial);' to pass } void HardwareSerial::begin (unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin) diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index e940cec49f..db686f953c 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -103,6 +103,7 @@ size_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms int serverAccept (int sock); // udp +void check_incoming_udp (); int mockUDPSocket (); bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast = 0); size_t mockUDPFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize, uint8_t addr[16], uint16_t& port); @@ -118,6 +119,11 @@ class InterruptLock { }; // +void mock_start_spiffs (size_t size_kb, size_t block_kb = 8, size_t page_b = 512); +void mock_stop_spiffs (); + +// + #define CORE_MOCK 1 #define ARDUINO 267 diff --git a/tests/host/common/spiffs_mock.cpp b/tests/host/common/spiffs_mock.cpp index e63abae179..90623c62c0 100644 --- a/tests/host/common/spiffs_mock.cpp +++ b/tests/host/common/spiffs_mock.cpp @@ -27,8 +27,6 @@ #include #include -#define SPIFFS_FILE_NAME "spiffs.bin" - extern "C" { static uint32_t s_phys_addr = 0; @@ -40,11 +38,14 @@ extern "C" FS SPIFFS(nullptr); -SpiffsMock::SpiffsMock(size_t fs_size, size_t fs_block, size_t fs_page, bool storage) +SpiffsMock::SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, bool storage) { + m_storage = storage; + if ((m_overwrite = (fs_size < 0))) + fs_size = -fs_size; + fprintf(stderr, "SPIFFS: %zd bytes\n", fs_size); - m_storage = storage; m_fs = new uint8_t[m_fs_size = fs_size]; memset(&m_fs[0], 0xff, m_fs_size); @@ -82,19 +83,42 @@ void SpiffsMock::load () { if (!m_fs_size) return; - + const char* fname = getenv("SPIFFS_PATH"); if (!fname) fname = DEFAULT_SPIFFS_FILE_NAME; - int fs = ::open(SPIFFS_FILE_NAME, O_RDONLY); + int fs = ::open(fname, O_RDONLY); if (fs == -1) { fprintf(stderr, "SPIFFS: loading '%s': %s\n", fname, strerror(errno)); return; } - fprintf(stderr, "SPIFFS: loading %zi bytes from '%s'\n", m_fs_size, fname); - if (::read(fs, &m_fs[0], m_fs_size) != (ssize_t)m_fs_size) - fprintf(stderr, "SPIFFS: reading %zi bytes: %s\n", m_fs_size, strerror(errno)); + + off_t flen = lseek(fs, 0, SEEK_END); + if (flen == (off_t)-1) + { + fprintf(stderr, "SPIFFS: checking size of '%s': %s\n", fname, strerror(errno)); + return; + } + lseek(fs, 0, SEEK_SET); + + if (flen != (off_t)m_fs_size) + { + fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n", fname, (int)flen, m_fs_size); + if (!m_overwrite) + { + fprintf(stderr, "SPIFFS: aborting at user request\n"); + abort(); + } + fprintf(stderr, "SPIFFS: continuing without loading at user request, '%s' will be overwritten\n", fname); + } + else + { + fprintf(stderr, "SPIFFS: loading %zi bytes from '%s'\n", m_fs_size, fname); + ssize_t r = ::read(fs, &m_fs[0], m_fs_size); + if (r != (ssize_t)m_fs_size) + fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs_size, r, strerror(errno)); + } ::close(fs); } @@ -106,7 +130,7 @@ void SpiffsMock::save () const char* fname = getenv("SPIFFS_PATH"); if (!fname) fname = DEFAULT_SPIFFS_FILE_NAME; - int fs = ::open(SPIFFS_FILE_NAME, O_CREAT | O_TRUNC | O_WRONLY, 0644); + int fs = ::open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644); if (fs == -1) { fprintf(stderr, "SPIFFS: saving '%s': %s\n", fname, strerror(errno)); diff --git a/tests/host/common/spiffs_mock.h b/tests/host/common/spiffs_mock.h index 6b0c2c5102..44e76a0305 100644 --- a/tests/host/common/spiffs_mock.h +++ b/tests/host/common/spiffs_mock.h @@ -25,7 +25,7 @@ class SpiffsMock { public: - SpiffsMock(size_t fs_size, size_t fs_block, size_t fs_page, bool storage = true); + SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, bool storage = true); void reset(); ~SpiffsMock(); @@ -44,10 +44,10 @@ class SpiffsMock { uint8_t* m_fs; size_t m_fs_size; bool m_storage; + bool m_overwrite; }; -#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage) -#define SPIFFS_MOCK_RESET() spiffs_mock.reset() - +//#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage) +//#define SPIFFS_MOCK_RESET() spiffs_mock.reset() #endif /* spiffs_mock_hpp */ From d220591f294c9b8c54b73e845c940c70b000a4af Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 9 Jan 2019 19:12:10 +0100 Subject: [PATCH 05/10] fix local CI tester --- tests/run_CI_locally.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/run_CI_locally.sh b/tests/run_CI_locally.sh index 90b2d77c34..5b23a2e4b5 100755 --- a/tests/run_CI_locally.sh +++ b/tests/run_CI_locally.sh @@ -112,6 +112,12 @@ elif [ "$BUILD_TYPE" = "platformio_even" ]; then elif [ "$BUILD_TYPE" = "platformio_odd" ]; then BUILD_PARITY=odd tests/platformio-custom.sh +elif [ "$BUILD_TYPE" = host ]; then + tests/ci/host_test.sh + +elif [ "$BUILD_TYPE" = style ]; then + tests/ci/install_astyle.sh + else echo "BUILD_TYPE not set or invalid" exit 1 From c049f4ab6aa2652a42b735105f59826158b8898d Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 9 Jan 2019 19:13:15 +0100 Subject: [PATCH 06/10] restore commented macros --- tests/host/common/spiffs_mock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/host/common/spiffs_mock.h b/tests/host/common/spiffs_mock.h index 44e76a0305..736f882389 100644 --- a/tests/host/common/spiffs_mock.h +++ b/tests/host/common/spiffs_mock.h @@ -47,7 +47,7 @@ class SpiffsMock { bool m_overwrite; }; -//#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage) -//#define SPIFFS_MOCK_RESET() spiffs_mock.reset() +#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage) +#define SPIFFS_MOCK_RESET() spiffs_mock.reset() #endif /* spiffs_mock_hpp */ From 85138ea815152e257341e27f741d5ee2b37a4fd8 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 11 Jan 2019 14:54:44 +0100 Subject: [PATCH 07/10] host: spiffs: restore use of a vector, file name based on executable name and spiffs size host: fix nasty bug returning value (read(): -1 != 0xff) FSBrowser example: fix comment --- .../examples/FSBrowser/FSBrowser.ino | 2 +- tests/host/Makefile | 4 +- tests/host/common/ArduinoMain.cpp | 15 +++-- tests/host/common/ArduinoMainSpiffs.cpp | 13 ++-- tests/host/common/include/ClientContext.h | 2 +- tests/host/common/mock.h | 2 +- tests/host/common/spiffs_mock.cpp | 63 +++++++------------ tests/host/common/spiffs_mock.h | 15 +---- tests/host/fs/test_fs.cpp | 22 +++---- 9 files changed, 56 insertions(+), 82 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino b/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino index ff4204476f..cf1c3786d9 100644 --- a/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino +++ b/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino @@ -17,7 +17,7 @@ upload the contents of the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE) or you can upload the contents of a folder if you CD in that folder and run the following command: - for file in `ls -A1`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done + for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done access the sample web page at http://esp8266fs.local edit the page by going to http://esp8266fs.local/edit diff --git a/tests/host/Makefile b/tests/host/Makefile index 09babd21d4..5f8285374e 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -19,8 +19,8 @@ LCOV ?= lcov GENHTML ?= genhtml ifeq ($(FORCE32),1) -ABILITY32 = $(shell echo 'int main(){return sizeof(long);}'|$(CXX) -m32 -x c++ - -o sizeoflong 2>/dev/null && ./sizeoflong; echo $$?; rm -f sizeoflong;) -ifneq ($(ABILITY32),4) +SIZEOFLONG = $(shell echo 'int main(){return sizeof(long);}'|$(CXX) -m32 -x c++ - -o sizeoflong 2>/dev/null && ./sizeoflong; echo $$?; rm -f sizeoflong;) +ifneq ($(SIZEOFLONG),4) $(warning Cannot compile in 32 bit mode, switching to native mode) else N32 = 32 diff --git a/tests/host/common/ArduinoMain.cpp b/tests/host/common/ArduinoMain.cpp index 0f06b17260..54420d9e2a 100644 --- a/tests/host/common/ArduinoMain.cpp +++ b/tests/host/common/ArduinoMain.cpp @@ -69,7 +69,6 @@ void save () mock_stop_spiffs(); } - void control_c (int sig) { (void)sig; @@ -78,7 +77,7 @@ void control_c (int sig) { fprintf(stderr, MOCK "stuck, killing\n"); save(); - abort(); + exit(1); } user_exit = true; } @@ -89,7 +88,6 @@ int main (int argc, char* const argv []) bool fast = false; - for (;;) { int n = getopt_long(argc, argv, "hlfi:S:", options, NULL); @@ -118,7 +116,14 @@ int main (int argc, char* const argv []) } } - mock_start_spiffs(spiffs_kb); + if (spiffs_kb) + { + String name = argv[0]; + name += "-spiffs"; + name += String(spiffs_kb > 0? spiffs_kb: -spiffs_kb, DEC); + name += "KB"; + mock_start_spiffs(name, spiffs_kb); + } // setup global global_ipv4_netfmt wifi_get_ip_info(0, nullptr); @@ -128,9 +133,7 @@ int main (int argc, char* const argv []) { if (!fast) usleep(10000); // not 100% cpu - loop(); - check_incoming_udp(); } diff --git a/tests/host/common/ArduinoMainSpiffs.cpp b/tests/host/common/ArduinoMainSpiffs.cpp index 9b47c56f4f..1e5099d0ff 100644 --- a/tests/host/common/ArduinoMainSpiffs.cpp +++ b/tests/host/common/ArduinoMainSpiffs.cpp @@ -1,22 +1,17 @@ #include "spiffs_mock.h" -#if 0 -#include "../common/spiffs_mock.h" -#include -SPIFFS_MOCK_DECLARE(/*size_kb*/64, /*block_kb*/8, /*page_b*/512, true); -#endif - SpiffsMock* spiffs_mock = nullptr; -void mock_start_spiffs (size_t size_kb, size_t block_kb, size_t page_b) +void mock_start_spiffs (const String& fname, size_t size_kb, size_t block_kb, size_t page_b) { - spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, true); + spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, fname); } void mock_stop_spiffs () { - delete spiffs_mock; + if (spiffs_mock) + delete spiffs_mock; spiffs_mock = nullptr; } diff --git a/tests/host/common/include/ClientContext.h b/tests/host/common/include/ClientContext.h index 8db6c1df0d..f0898cece4 100644 --- a/tests/host/common/include/ClientContext.h +++ b/tests/host/common/include/ClientContext.h @@ -162,7 +162,7 @@ class ClientContext int read() { char c; - return read(&c, 1)? c: -1; + return read(&c, 1)? (unsigned char)c: -1; } size_t read (char* dst, size_t size) diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index db686f953c..3c31c9e6fe 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -119,7 +119,7 @@ class InterruptLock { }; // -void mock_start_spiffs (size_t size_kb, size_t block_kb = 8, size_t page_b = 512); +void mock_start_spiffs (const String& fname, size_t size_kb, size_t block_kb = 8, size_t page_b = 512); void mock_stop_spiffs (); // diff --git a/tests/host/common/spiffs_mock.cpp b/tests/host/common/spiffs_mock.cpp index 90623c62c0..1df43a180b 100644 --- a/tests/host/common/spiffs_mock.cpp +++ b/tests/host/common/spiffs_mock.cpp @@ -38,7 +38,7 @@ extern "C" FS SPIFFS(nullptr); -SpiffsMock::SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, bool storage) +SpiffsMock::SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage) { m_storage = storage; if ((m_overwrite = (fs_size < 0))) @@ -46,105 +46,90 @@ SpiffsMock::SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, bool st fprintf(stderr, "SPIFFS: %zd bytes\n", fs_size); - m_fs = new uint8_t[m_fs_size = fs_size]; - memset(&m_fs[0], 0xff, m_fs_size); - + m_fs.resize(fs_size, 0xff); s_phys_addr = 0; s_phys_size = static_cast(fs_size); s_phys_page = static_cast(fs_page); s_phys_block = static_cast(fs_block); - s_phys_data = &m_fs[0]; + s_phys_data = m_fs.data(); reset(); } void SpiffsMock::reset() { SPIFFS = FS(FSImplPtr(new SPIFFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5))); - if (m_storage) - load(); + load(); } SpiffsMock::~SpiffsMock() { - if (m_storage) - save(); + save(); s_phys_addr = 0; s_phys_size = 0; s_phys_page = 0; s_phys_block = 0; s_phys_data = nullptr; - delete [] m_fs; - m_fs = nullptr; - m_fs_size = 0; + m_fs.resize(0); SPIFFS = FS(FSImplPtr(nullptr)); } void SpiffsMock::load () { - if (!m_fs_size) + if (!m_fs.size() || !m_storage.length()) return; - const char* fname = getenv("SPIFFS_PATH"); - if (!fname) - fname = DEFAULT_SPIFFS_FILE_NAME; - int fs = ::open(fname, O_RDONLY); + int fs = ::open(m_storage.c_str(), O_RDONLY); if (fs == -1) { - fprintf(stderr, "SPIFFS: loading '%s': %s\n", fname, strerror(errno)); + fprintf(stderr, "SPIFFS: loading '%s': %s\n", m_storage.c_str(), strerror(errno)); return; } off_t flen = lseek(fs, 0, SEEK_END); if (flen == (off_t)-1) { - fprintf(stderr, "SPIFFS: checking size of '%s': %s\n", fname, strerror(errno)); + fprintf(stderr, "SPIFFS: checking size of '%s': %s\n", m_storage.c_str(), strerror(errno)); return; } lseek(fs, 0, SEEK_SET); - if (flen != (off_t)m_fs_size) + if (flen != (off_t)m_fs.size()) { - fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n", fname, (int)flen, m_fs_size); + fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n", m_storage.c_str(), (int)flen, m_fs.size()); if (!m_overwrite) { fprintf(stderr, "SPIFFS: aborting at user request\n"); abort(); } - fprintf(stderr, "SPIFFS: continuing without loading at user request, '%s' will be overwritten\n", fname); + fprintf(stderr, "SPIFFS: continuing without loading at user request, '%s' will be overwritten\n", m_storage.c_str()); } else { - fprintf(stderr, "SPIFFS: loading %zi bytes from '%s'\n", m_fs_size, fname); - ssize_t r = ::read(fs, &m_fs[0], m_fs_size); - if (r != (ssize_t)m_fs_size) - fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs_size, r, strerror(errno)); + fprintf(stderr, "SPIFFS: loading %zi bytes from '%s'\n", m_fs.size(), m_storage.c_str()); + ssize_t r = ::read(fs, m_fs.data(), m_fs.size()); + if (r != (ssize_t)m_fs.size()) + fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r, strerror(errno)); } ::close(fs); } void SpiffsMock::save () { - if (!m_fs_size) + if (!m_fs.size() || !m_storage.length()) return; - const char* fname = getenv("SPIFFS_PATH"); - if (!fname) - fname = DEFAULT_SPIFFS_FILE_NAME; - int fs = ::open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644); + int fs = ::open(m_storage.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); if (fs == -1) { - fprintf(stderr, "SPIFFS: saving '%s': %s\n", fname, strerror(errno)); + fprintf(stderr, "SPIFFS: saving '%s': %s\n", m_storage.c_str(), strerror(errno)); return; } - fprintf(stderr, "SPIFFS: saving %zi bytes to '%s'\n", m_fs_size, fname); - -// this can be a valgrind error, I don't understand how it happens -//for (size_t i = 0; i < m_fs_size; i++) printf("\r%zd:%d ", i, (int)m_fs[i]); + fprintf(stderr, "SPIFFS: saving %zi bytes to '%s'\n", m_fs.size(), m_storage.c_str()); - if (::write(fs, &m_fs[0], m_fs_size) != (ssize_t)m_fs_size) - fprintf(stderr, "SPIFFS: writing %zi bytes: %s\n", m_fs_size, strerror(errno)); + if (::write(fs, m_fs.data(), m_fs.size()) != (ssize_t)m_fs.size()) + fprintf(stderr, "SPIFFS: writing %zi bytes: %s\n", m_fs.size(), strerror(errno)); if (::close(fs) == -1) - fprintf(stderr, "SPIFFS: closing %s: %s\n", fname, strerror(errno)); + fprintf(stderr, "SPIFFS: closing %s: %s\n", m_storage.c_str(), strerror(errno)); } int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { diff --git a/tests/host/common/spiffs_mock.h b/tests/host/common/spiffs_mock.h index 736f882389..a38fd820e3 100644 --- a/tests/host/common/spiffs_mock.h +++ b/tests/host/common/spiffs_mock.h @@ -25,7 +25,7 @@ class SpiffsMock { public: - SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, bool storage = true); + SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString); void reset(); ~SpiffsMock(); @@ -33,17 +33,8 @@ class SpiffsMock { void load (); void save (); - // it was a vector, but CI tests & valgrind complain with: - // Syscall param write(buf) points to uninitialised byte(s) - // by 0x43E9FF: SpiffsMock::save() (spiffs_mock.cpp:116) - // = if (::write(fs, &m_fs[0], m_fs_size) != (ssize_t)m_fs_size) - // so switched to a regular array - // and that bug is still here - // XXXWIPTODO - - uint8_t* m_fs; - size_t m_fs_size; - bool m_storage; + std::vector m_fs; + String m_storage; bool m_overwrite; }; diff --git a/tests/host/fs/test_fs.cpp b/tests/host/fs/test_fs.cpp index c97e0f718b..70103a244c 100644 --- a/tests/host/fs/test_fs.cpp +++ b/tests/host/fs/test_fs.cpp @@ -50,25 +50,25 @@ static std::set listDir (const char* path) TEST_CASE("FS can begin","[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); } TEST_CASE("FS can't begin with zero size","[fs]") { - SPIFFS_MOCK_DECLARE(0, 8, 512, false); + SPIFFS_MOCK_DECLARE(0, 8, 512, ""); REQUIRE_FALSE(SPIFFS.begin()); } TEST_CASE("Before begin is called, open will fail","[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE_FALSE(SPIFFS.open("/foo", "w")); } TEST_CASE("FS can create file","[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); createFile("/test", ""); REQUIRE(SPIFFS.exists("/test")); @@ -76,7 +76,7 @@ TEST_CASE("FS can create file","[fs]") TEST_CASE("Files can be written and appended to","[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); { File f = SPIFFS.open("config1.txt", "w"); @@ -100,7 +100,7 @@ TEST_CASE("Files can be written and appended to","[fs]") TEST_CASE("Files persist after reset", "[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); createFile("config1.txt", "file 1"); @@ -112,7 +112,7 @@ TEST_CASE("Files persist after reset", "[fs]") TEST_CASE("Filesystem is empty after format", "[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.format()); REQUIRE(SPIFFS.begin()); createFile("/1", "first"); @@ -128,7 +128,7 @@ TEST_CASE("Filesystem is empty after format", "[fs]") TEST_CASE("Dir lists all files", "[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); createFile("/empty", ""); createFile("/not_empty", "some text"); @@ -146,7 +146,7 @@ TEST_CASE("Dir lists all files", "[fs]") TEST_CASE("File names which are too long are rejected", "[fs]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); const char* emptyName = ""; const char* longName_31 = "/234567890123456789012345678901"; @@ -164,7 +164,7 @@ TEST_CASE("File names which are too long are rejected", "[fs]") TEST_CASE("#1685 Duplicate files", "[fs][bugreport]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); createFile("/config", "some text"); createFile("/data", ""); @@ -175,7 +175,7 @@ TEST_CASE("#1685 Duplicate files", "[fs][bugreport]") TEST_CASE("#1819 Can list all files with openDir(\"\")", "[fs][bugreport]") { - SPIFFS_MOCK_DECLARE(64, 8, 512, false); + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); REQUIRE(SPIFFS.begin()); createFile("/file1", "some text"); createFile("/file2", "other text"); From 4e2874e0b2a808cee75b1c0e22d190da99e51e2c Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 11 Jan 2019 15:44:04 +0100 Subject: [PATCH 08/10] host: propagate posix read/write errors --- tests/host/common/ClientContextSocket.cpp | 23 +++++++++++++++-------- tests/host/common/include/ClientContext.h | 18 +++++++++++++++--- tests/host/common/mock.h | 10 +++++----- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/tests/host/common/ClientContextSocket.cpp b/tests/host/common/ClientContextSocket.cpp index 8dd55ee62e..f8a52cf756 100644 --- a/tests/host/common/ClientContextSocket.cpp +++ b/tests/host/common/ClientContextSocket.cpp @@ -66,20 +66,24 @@ int mockConnect (uint32_t ipv4, int& sock, int port) return 1; } -size_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize) +ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize) { size_t maxread = CCBUFSIZE - ccinbufsize; ssize_t ret = ::read(sock, ccinbuf + ccinbufsize, maxread); if (ret == -1) { if (errno != EAGAIN) + { fprintf(stderr, MOCK "ClientContext::(read/peek): filling buffer for %zd bytes: %s\n", maxread, strerror(errno)); + return -1; + } ret = 0; } - return ccinbufsize += ret; + ccinbufsize += ret; + return ret; } -size_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize) +ssize_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize) { if (usersize > CCBUFSIZE) fprintf(stderr, MOCK "CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE, usersize - CCBUFSIZE, usersize); @@ -96,7 +100,8 @@ size_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char } // check incoming data data - mockFillInBuf(sock, ccinbuf, ccinbufsize); + if (mockFillInBuf(sock, ccinbuf, ccinbufsize) < 0) + return -1; if (usersize <= ccinbufsize) { // data just received @@ -113,16 +118,18 @@ size_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char return retsize; } -size_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize) +ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize) { - size_t copied = mockPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize); + ssize_t copied = mockPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize); + if (copied < 0) + return -1; // swallow (XXX use a circular buffer) memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied); ccinbufsize -= copied; return copied; } -size_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms) +ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms) { struct pollfd p; p.fd = sock; @@ -140,7 +147,7 @@ size_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms) if (ret == -1) { fprintf(stderr, MOCK "ClientContext::read: write(%d): %s\n", sock, strerror(errno)); - return 0; + return -1; } if (ret != (int)size) { diff --git a/tests/host/common/include/ClientContext.h b/tests/host/common/include/ClientContext.h index f0898cece4..e5f8bc20d2 100644 --- a/tests/host/common/include/ClientContext.h +++ b/tests/host/common/include/ClientContext.h @@ -167,7 +167,13 @@ class ClientContext size_t read (char* dst, size_t size) { - return mockRead(_sock, dst, size, 0, _inbuf, _inbufsize); + ssize_t ret = mockRead(_sock, dst, size, 0, _inbuf, _inbufsize); + if (ret < 0) + { + abort(); // close, CLOSED + return 0; + } + return ret; } int peek() @@ -198,7 +204,13 @@ class ClientContext size_t write(const uint8_t* data, size_t size) { - return mockWrite(_sock, data, size, _timeout_ms); + ssize_t ret = mockWrite(_sock, data, size, _timeout_ms); + if (ret < 0) + { + abort(); // close, CLOSED + return 0; + } + return ret; } size_t write(Stream& stream) @@ -208,7 +220,7 @@ class ClientContext avail = stream.readBytes(buf, avail); size_t totwrote = 0; uint8_t* w = buf; - while (avail) + while (avail && _sock >= 0) { size_t wrote = write(w, avail); w += wrote; diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index 3c31c9e6fe..b48c0eda30 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -95,11 +95,11 @@ extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to #endif // tcp -int mockConnect (uint32_t addr, int& sock, int port); -size_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize); -size_t mockPeekBytes (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize); -size_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize); -size_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms); +int mockConnect (uint32_t addr, int& sock, int port); +ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize); +ssize_t mockPeekBytes (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize); +ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize); +ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms); int serverAccept (int sock); // udp From 98b2e81ac2f4016d2e2c12779dcb04ed426e2aa1 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 11 Jan 2019 15:59:28 +0100 Subject: [PATCH 09/10] don't use ::abort() --- tests/host/common/spiffs_mock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/host/common/spiffs_mock.cpp b/tests/host/common/spiffs_mock.cpp index 1df43a180b..004b15fb9a 100644 --- a/tests/host/common/spiffs_mock.cpp +++ b/tests/host/common/spiffs_mock.cpp @@ -99,7 +99,7 @@ void SpiffsMock::load () if (!m_overwrite) { fprintf(stderr, "SPIFFS: aborting at user request\n"); - abort(); + exit(1); } fprintf(stderr, "SPIFFS: continuing without loading at user request, '%s' will be overwritten\n", m_storage.c_str()); } From bf0b994da4ca6e1cbcb44a3411cc0bffe55749bf Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 12 Jan 2019 12:18:55 +0100 Subject: [PATCH 10/10] extra check to avoid noise --- tests/host/common/ClientContextSocket.cpp | 2 +- tests/host/common/include/ClientContext.h | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/host/common/ClientContextSocket.cpp b/tests/host/common/ClientContextSocket.cpp index f8a52cf756..8778a1f49f 100644 --- a/tests/host/common/ClientContextSocket.cpp +++ b/tests/host/common/ClientContextSocket.cpp @@ -74,7 +74,7 @@ ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize) { if (errno != EAGAIN) { - fprintf(stderr, MOCK "ClientContext::(read/peek): filling buffer for %zd bytes: %s\n", maxread, strerror(errno)); + fprintf(stderr, MOCK "ClientContext::(read/peek fd=%i): filling buffer for %zd bytes: %s\n", sock, maxread, strerror(errno)); return -1; } ret = 0; diff --git a/tests/host/common/include/ClientContext.h b/tests/host/common/include/ClientContext.h index e5f8bc20d2..bbd3b06882 100644 --- a/tests/host/common/include/ClientContext.h +++ b/tests/host/common/include/ClientContext.h @@ -156,7 +156,11 @@ class ClientContext size_t getSize() { - return _inbufsize?: mockFillInBuf(_sock, _inbuf, _inbufsize); + if (_sock < 0) + return 0; + if (_inbufsize) + return _inbufsize; + return mockFillInBuf(_sock, _inbuf, _inbufsize); } int read()