mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-17 06:52:18 +01:00
parent
e016835289
commit
71de447620
188
libraries/Bridge/src/BridgeUdp.cpp
Normal file
188
libraries/Bridge/src/BridgeUdp.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
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::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];
|
||||
uint16_t l = 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];
|
||||
uint16_t l = bridge.transfer(cmd, 2, res, 7);
|
||||
if (res[0] == 0)
|
||||
return 0;
|
||||
return (res[5] << 8) + res[6];
|
||||
}
|
64
libraries/Bridge/src/BridgeUdp.h
Normal file
64
libraries/Bridge/src/BridgeUdp.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Udp.h>
|
||||
#include "Bridge.h"
|
||||
|
||||
class BridgeUDP : public UDP {
|
||||
|
||||
public:
|
||||
BridgeUDP(BridgeClass &_b = Bridge);
|
||||
virtual uint8_t begin(uint16_t);
|
||||
virtual void stop();
|
||||
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port);
|
||||
virtual int beginPacket(const char *host, uint16_t port);
|
||||
virtual int endPacket();
|
||||
virtual size_t write(uint8_t d) { return write(&d, 1); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
using Print::write;
|
||||
|
||||
virtual int parsePacket();
|
||||
/* return number of bytes available in the current packet,
|
||||
will return zero if parsePacket hasn't been called yet */
|
||||
virtual int available() { return avail; }
|
||||
virtual int read();
|
||||
virtual int read(unsigned char* buffer, size_t len);
|
||||
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
|
||||
virtual int peek();
|
||||
virtual void flush() { avail = 0; }
|
||||
|
||||
virtual IPAddress remoteIP();
|
||||
virtual uint16_t remotePort();
|
||||
|
||||
private:
|
||||
BridgeClass &bridge;
|
||||
uint8_t handle;
|
||||
boolean opened;
|
||||
|
||||
private:
|
||||
void doBuffer();
|
||||
uint16_t avail;
|
||||
uint8_t buffered;
|
||||
uint8_t readPos;
|
||||
static const int BUFFER_SIZE = 64;
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user