mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-31 20:52:13 +01:00
199 lines
4.4 KiB
C++
199 lines
4.4 KiB
C++
/*
|
|
Copyright (c) 2015 Arduino LLC. All right reserved.
|
|
|
|
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, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "BridgeUdp.h"
|
|
|
|
BridgeUDP::BridgeUDP(BridgeClass &_b) :
|
|
bridge(_b), opened(false), avail(0), buffered(0), readPos(0) {
|
|
}
|
|
|
|
/* Start BridgeUDP socket, listening at local port PORT */
|
|
uint8_t BridgeUDP::begin(uint16_t port) {
|
|
if (opened)
|
|
return 0;
|
|
uint8_t cmd[] = {'e', (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
|
|
uint8_t res[2];
|
|
bridge.transfer(cmd, 3, res, 2);
|
|
if (res[1] == 1) // Error...
|
|
return 0;
|
|
handle = res[0];
|
|
opened = true;
|
|
return 1;
|
|
}
|
|
|
|
/* Release any resources being used by this BridgeUDP instance */
|
|
void BridgeUDP::stop()
|
|
{
|
|
if (!opened)
|
|
return;
|
|
uint8_t cmd[] = {'q', handle};
|
|
bridge.transfer(cmd, 2);
|
|
opened = false;
|
|
}
|
|
|
|
int BridgeUDP::beginPacket(const char *host, uint16_t port)
|
|
{
|
|
if (!opened)
|
|
return 0;
|
|
uint8_t cmd[] = {'E', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
|
|
uint8_t res[1];
|
|
bridge.transfer(cmd, 4, (const uint8_t *)host, strlen(host), res, 1);
|
|
return res[0]; // 1=Success, 0=Error
|
|
}
|
|
|
|
int BridgeUDP::beginBroadcastPacket(uint16_t port)
|
|
{
|
|
if (!opened)
|
|
return 0;
|
|
uint8_t cmd[] = {'v', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
|
|
uint8_t res[1];
|
|
bridge.transfer(cmd, 4, res, 1);
|
|
return res[0]; // 1=Success, 0=Error
|
|
}
|
|
|
|
int BridgeUDP::beginPacket(IPAddress ip, uint16_t port)
|
|
{
|
|
if (!opened)
|
|
return 0;
|
|
String address;
|
|
address.reserve(18);
|
|
address += ip[0];
|
|
address += '.';
|
|
address += ip[1];
|
|
address += '.';
|
|
address += ip[2];
|
|
address += '.';
|
|
address += ip[3];
|
|
return beginPacket(address.c_str(), port);
|
|
}
|
|
|
|
int BridgeUDP::endPacket()
|
|
{
|
|
if (!opened)
|
|
return 0;
|
|
uint8_t cmd[] = {'H', handle};
|
|
uint8_t res[1];
|
|
bridge.transfer(cmd, 2, res, 1);
|
|
return res[0]; // 1=Success, 0=Error
|
|
}
|
|
|
|
size_t BridgeUDP::write(const uint8_t *buffer, size_t size)
|
|
{
|
|
if (!opened)
|
|
return 0;
|
|
uint8_t cmd[] = {'h', handle};
|
|
uint8_t res[1];
|
|
bridge.transfer(cmd, 2, buffer, size, res, 1);
|
|
return res[0]; // 1=Success, 0=Error
|
|
}
|
|
|
|
int BridgeUDP::parsePacket()
|
|
{
|
|
if (!opened)
|
|
return 0;
|
|
buffered = 0;
|
|
readPos = 0;
|
|
uint8_t cmd[] = {'Q', handle};
|
|
uint8_t res[3];
|
|
bridge.transfer(cmd, 2, res, 3);
|
|
if (res[0] == 0) {
|
|
// There aren't any packets available
|
|
return 0;
|
|
}
|
|
avail = (res[1] << 8) + res[2];
|
|
return 1;
|
|
}
|
|
|
|
void BridgeUDP::doBuffer() {
|
|
// If there are already char in buffer exit
|
|
if (buffered > 0)
|
|
return;
|
|
if (avail == 0)
|
|
return;
|
|
|
|
// Try to buffer up to 32 characters
|
|
readPos = 0;
|
|
uint8_t cmd[] = {'u', handle, sizeof(buffer)};
|
|
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
|
|
}
|
|
|
|
int BridgeUDP::read()
|
|
{
|
|
if (!opened)
|
|
return -1;
|
|
doBuffer();
|
|
if (buffered == 0) {
|
|
return -1; // no chars available
|
|
}
|
|
buffered--;
|
|
avail--;
|
|
return buffer[readPos++];
|
|
}
|
|
|
|
int BridgeUDP::read(unsigned char* buff, size_t size)
|
|
{
|
|
if (!opened)
|
|
return -1;
|
|
size_t readed = 0;
|
|
do {
|
|
if (buffered == 0) {
|
|
doBuffer();
|
|
if (buffered == 0)
|
|
return readed;
|
|
}
|
|
buff[readed++] = buffer[readPos++];
|
|
buffered--;
|
|
avail--;
|
|
} while (readed < size);
|
|
return readed;
|
|
}
|
|
|
|
int BridgeUDP::peek()
|
|
{
|
|
if (!opened)
|
|
return -1;
|
|
doBuffer();
|
|
if (buffered == 0)
|
|
return -1; // no chars available
|
|
return buffer[readPos];
|
|
}
|
|
|
|
IPAddress BridgeUDP::remoteIP()
|
|
{
|
|
if (!opened)
|
|
return -1;
|
|
uint8_t cmd[] = {'T', handle};
|
|
uint8_t res[7];
|
|
bridge.transfer(cmd, 2, res, 7);
|
|
if (res[0] == 0)
|
|
return IPAddress(0,0,0,0);
|
|
return IPAddress(res[1], res[2], res[3], res[4]);
|
|
}
|
|
|
|
uint16_t BridgeUDP::remotePort()
|
|
{
|
|
if (!opened)
|
|
return -1;
|
|
uint8_t cmd[] = {'T', handle};
|
|
uint8_t res[7];
|
|
bridge.transfer(cmd, 2, res, 7);
|
|
if (res[0] == 0)
|
|
return 0;
|
|
return (res[5] << 8) + res[6];
|
|
}
|