/*-------------------------------------------------------------------- This file is part of the Arduino WiFiEsp library. The Arduino WiFiEsp library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The Arduino WiFiEsp library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with The Arduino WiFiEsp library. If not, see . --------------------------------------------------------------------*/ #include #include "WiFiEsp.h" #include "WiFiEspClient.h" #include "WiFiEspServer.h" #include "utility/EspDrv.h" #include "utility/debug.h" WiFiEspClient::WiFiEspClient() : _sock(255) { } WiFiEspClient::WiFiEspClient(uint8_t sock) : _sock(sock) { } //////////////////////////////////////////////////////////////////////////////// // Overrided Print methods //////////////////////////////////////////////////////////////////////////////// // the standard print method will call write for each character in the buffer // this is very slow on ESP size_t WiFiEspClient::print(const __FlashStringHelper *ifsh) { printFSH(ifsh, false); } // if we do override this, the standard println will call the print // method twice size_t WiFiEspClient::println(const __FlashStringHelper *ifsh) { printFSH(ifsh, true); } //////////////////////////////////////////////////////////////////////////////// // Implementation of Client virtual methods //////////////////////////////////////////////////////////////////////////////// int WiFiEspClient::connectSSL(const char* host, uint16_t port) { return connect(host, port, SSL_MODE); } int WiFiEspClient::connectSSL(IPAddress ip, uint16_t port) { char s[16]; sprintf_P(s, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); return connect(s, port, SSL_MODE); } int WiFiEspClient::connect(const char* host, uint16_t port) { return connect(host, port, TCP_MODE); } int WiFiEspClient::connect(IPAddress ip, uint16_t port) { char s[16]; sprintf_P(s, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); return connect(s, port, TCP_MODE); } /* Private method */ int WiFiEspClient::connect(const char* host, uint16_t port, uint8_t protMode) { LOGINFO1(F("Connecting to"), host); _sock = WiFiEspClass::getFreeSocket(); if (_sock != NO_SOCKET_AVAIL) { if (!EspDrv::startClient(host, port, _sock, protMode)) return 0; WiFiEspClass::allocateSocket(_sock); } else { LOGERROR(F("No socket available")); return 0; } return 1; } size_t WiFiEspClient::write(uint8_t b) { return write(&b, 1); } size_t WiFiEspClient::write(const uint8_t *buf, size_t size) { if (_sock >= MAX_SOCK_NUM or size==0) { setWriteError(); return 0; } bool r = EspDrv::sendData(_sock, buf, size); if (!r) { setWriteError(); LOGERROR1(F("Failed to write to socket"), _sock); delay(4000); stop(); return 0; } return size; } int WiFiEspClient::available() { if (_sock != 255) { int bytes = EspDrv::availData(_sock); if (bytes>0) { return bytes; } } return 0; } int WiFiEspClient::read() { uint8_t b; if (!available()) return -1; bool connClose = false; EspDrv::getData(_sock, &b, false, &connClose); if (connClose) { WiFiEspClass::releaseSocket(_sock); _sock = 255; } return b; } int WiFiEspClient::read(uint8_t* buf, size_t size) { if (!available()) return -1; return EspDrv::getDataBuf(_sock, buf, size); } int WiFiEspClient::peek() { uint8_t b; if (!available()) return -1; bool connClose = false; EspDrv::getData(_sock, &b, true, &connClose); if (connClose) { WiFiEspClass::releaseSocket(_sock); _sock = 255; } return b; } void WiFiEspClient::flush() { while (available()) read(); } void WiFiEspClient::stop() { if (_sock == 255) return; LOGINFO1(F("Disconnecting "), _sock); EspDrv::stopClient(_sock); WiFiEspClass::releaseSocket(_sock); _sock = 255; } uint8_t WiFiEspClient::connected() { return (status() == ESTABLISHED); } WiFiEspClient::operator bool() { return _sock != 255; } //////////////////////////////////////////////////////////////////////////////// // Additional WiFi standard methods //////////////////////////////////////////////////////////////////////////////// uint8_t WiFiEspClient::status() { if (_sock == 255) { return CLOSED; } if (EspDrv::availData(_sock)) { return ESTABLISHED; } if (EspDrv::getClientState(_sock)) { return ESTABLISHED; } WiFiEspClass::releaseSocket(_sock); _sock = 255; return CLOSED; } IPAddress WiFiEspClient::remoteIP() { IPAddress ret; EspDrv::getRemoteIpAddress(ret); return ret; } //////////////////////////////////////////////////////////////////////////////// // Private Methods //////////////////////////////////////////////////////////////////////////////// size_t WiFiEspClient::printFSH(const __FlashStringHelper *ifsh, bool appendCrLf) { size_t size = strlen_P((char*)ifsh); if (_sock >= MAX_SOCK_NUM or size==0) { setWriteError(); return 0; } bool r = EspDrv::sendData(_sock, ifsh, size, appendCrLf); if (!r) { setWriteError(); LOGERROR1(F("Failed to write to socket"), _sock); delay(4000); stop(); return 0; } return size; }