/* This file is part of the WiFiEspAT library for Arduino https://github.com/jandrassy/WiFiEspAT Copyright 2019 Juraj Andrassy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include "WiFiEspAtBuffStream.h" #include "utility/EspAtDrv.h" void WiFiEspAtBuffStream::setUdpPort(const char* _udpHost, uint16_t _udpPort) { udpHost = _udpHost; port = _udpPort; } bool WiFiEspAtBuffStream::connected() { if (linkId != NO_LINK && !EspAtDrv.connected(linkId)) { linkId = NO_LINK; } return (linkId != NO_LINK); } void WiFiEspAtBuffStream::free() { assigned = false; linkId = NO_LINK; rxBufferLength = 0; rxBufferIndex = 0; txBufferLength = 0; port = 0; } void WiFiEspAtBuffStream::close(bool abort) { if (linkId != NO_LINK) { EspAtDrv.close(linkId, abort); } free(); } size_t WiFiEspAtBuffStream::write(uint8_t b) { txBuffer[txBufferLength++] = b; if (txBufferLength == txBufferSize) { flush(); if (getWriteError()) return 0; } return 1; } size_t WiFiEspAtBuffStream::write(const uint8_t *data, size_t length) { if (linkId == NO_LINK) { setWriteError(); return 0; } if (length == 0) return 0; if (txBufferLength == 0 && length > txBufferSize) // if internal buffer is empty and provided buffer is large return EspAtDrv.sendData(linkId, data, length, udpHost, port); // send it right away size_t a = txBufferSize - txBufferLength; // available space in internal buffer for (size_t i = 0; i < a && i < length; i++) { // copy data to internal buffer txBuffer[txBufferLength++] = data[i]; } int d = length - a; // left to write if (d >= 0) { // internal buffer is full flush(); } if (d <= 0) // nothing more to write return length; return a + write(data + a, d); // handle the rest of the provided buffer } void WiFiEspAtBuffStream::flush() { if (txBufferLength == 0) return; size_t res = EspAtDrv.sendData(linkId, txBuffer, txBufferLength, udpHost, port); setWriteError(res != txBufferLength); txBufferLength = 0; } int WiFiEspAtBuffStream::availableForWrite() { return txBufferSize - txBufferLength; } size_t WiFiEspAtBuffStream::write(Stream& file) { flush(); return EspAtDrv.sendData(linkId, file, udpHost, port); } size_t WiFiEspAtBuffStream::write(SendCallbackFnc callback) { flush(); return EspAtDrv.sendData(linkId, callback, udpHost, port); } int WiFiEspAtBuffStream::available() { size_t a = (rxBufferLength - rxBufferIndex); if (linkId == NO_LINK) return a; if (a == 0) { a = EspAtDrv.availData(linkId); } if (a == 0) { flush(); // maybe sketch is waiting for response without flushing the request } return a; } void WiFiEspAtBuffStream::fillRXbuffer() { if (rxBufferIndex < rxBufferLength || !available()) return; rxBufferIndex = 0; rxBufferLength = EspAtDrv.recvData(linkId, rxBuffer, rxBufferSize); } int WiFiEspAtBuffStream::read() { if (!available()) return -1; uint8_t b; if (!read(&b, 1)) return -1; return b; } int WiFiEspAtBuffStream::read(uint8_t* data, size_t size) { if (size == 0 || !available()) return 0; size_t l = rxBufferLength - rxBufferIndex; if (l == 0 && size > rxBufferSize) // internal buffer is empty and provided buffer is large return EspAtDrv.recvData(linkId, data, size); // fill the large provided buffer directly // copy from internal buffer fillRXbuffer(); for (size_t i = 0; i < l && i < size; i++) { data[i] = rxBuffer[rxBufferIndex++]; } if (size <= l) // provided buffer was filled return size; return l + read(data + l, size - l); // handle the rest of provided buffer } int WiFiEspAtBuffStream::peek() { if (!available()) return -1; fillRXbuffer(); return rxBuffer[rxBufferIndex]; }