Skip to content

Commit 71de447

Browse files
committed
Bridge: Added UDP packet support.
Fix #1716
1 parent e016835 commit 71de447

File tree

2 files changed

+252
-0
lines changed

2 files changed

+252
-0
lines changed

libraries/Bridge/src/BridgeUdp.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
Copyright (c) 2015 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#include "BridgeUdp.h"
20+
21+
BridgeUDP::BridgeUDP(BridgeClass &_b) :
22+
bridge(_b), opened(false), avail(0), buffered(0), readPos(0) {
23+
}
24+
25+
/* Start BridgeUDP socket, listening at local port PORT */
26+
uint8_t BridgeUDP::begin(uint16_t port) {
27+
if (opened)
28+
return 0;
29+
uint8_t cmd[] = {'e', (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
30+
uint8_t res[2];
31+
bridge.transfer(cmd, 3, res, 2);
32+
if (res[1] == 1) // Error...
33+
return 0;
34+
handle = res[0];
35+
opened = true;
36+
return 1;
37+
}
38+
39+
/* Release any resources being used by this BridgeUDP instance */
40+
void BridgeUDP::stop()
41+
{
42+
if (!opened)
43+
return;
44+
uint8_t cmd[] = {'q', handle};
45+
bridge.transfer(cmd, 2);
46+
opened = false;
47+
}
48+
49+
int BridgeUDP::beginPacket(const char *host, uint16_t port)
50+
{
51+
if (!opened)
52+
return 0;
53+
uint8_t cmd[] = {'E', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
54+
uint8_t res[1];
55+
bridge.transfer(cmd, 4, (const uint8_t *)host, strlen(host), res, 1);
56+
return res[0]; // 1=Success, 0=Error
57+
}
58+
59+
int BridgeUDP::beginPacket(IPAddress ip, uint16_t port)
60+
{
61+
if (!opened)
62+
return 0;
63+
String address;
64+
address.reserve(18);
65+
address += ip[0];
66+
address += '.';
67+
address += ip[1];
68+
address += '.';
69+
address += ip[2];
70+
address += '.';
71+
address += ip[3];
72+
return beginPacket(address.c_str(), port);
73+
}
74+
75+
int BridgeUDP::endPacket()
76+
{
77+
if (!opened)
78+
return 0;
79+
uint8_t cmd[] = {'H', handle};
80+
uint8_t res[1];
81+
bridge.transfer(cmd, 2, res, 1);
82+
return res[0]; // 1=Success, 0=Error
83+
}
84+
85+
size_t BridgeUDP::write(const uint8_t *buffer, size_t size)
86+
{
87+
if (!opened)
88+
return 0;
89+
uint8_t cmd[] = {'h', handle};
90+
uint8_t res[1];
91+
bridge.transfer(cmd, 2, buffer, size, res, 1);
92+
return res[0]; // 1=Success, 0=Error
93+
}
94+
95+
int BridgeUDP::parsePacket()
96+
{
97+
if (!opened)
98+
return 0;
99+
buffered = 0;
100+
readPos = 0;
101+
uint8_t cmd[] = {'Q', handle};
102+
uint8_t res[3];
103+
bridge.transfer(cmd, 2, res, 3);
104+
if (res[0] == 0) {
105+
// There aren't any packets available
106+
return 0;
107+
}
108+
avail = (res[1] << 8) + res[2];
109+
return 1;
110+
}
111+
112+
void BridgeUDP::doBuffer() {
113+
// If there are already char in buffer exit
114+
if (buffered > 0)
115+
return;
116+
if (avail == 0)
117+
return;
118+
119+
// Try to buffer up to 32 characters
120+
readPos = 0;
121+
uint8_t cmd[] = {'u', handle, sizeof(buffer)};
122+
buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
123+
}
124+
125+
int BridgeUDP::read()
126+
{
127+
if (!opened)
128+
return -1;
129+
doBuffer();
130+
if (buffered == 0) {
131+
return -1; // no chars available
132+
}
133+
buffered--;
134+
avail--;
135+
return buffer[readPos++];
136+
}
137+
138+
int BridgeUDP::read(unsigned char* buff, size_t size)
139+
{
140+
if (!opened)
141+
return -1;
142+
size_t readed = 0;
143+
do {
144+
if (buffered == 0) {
145+
doBuffer();
146+
if (buffered == 0)
147+
return readed;
148+
}
149+
buff[readed++] = buffer[readPos++];
150+
buffered--;
151+
avail--;
152+
} while (readed < size);
153+
return readed;
154+
}
155+
156+
int BridgeUDP::peek()
157+
{
158+
if (!opened)
159+
return -1;
160+
doBuffer();
161+
if (buffered == 0)
162+
return -1; // no chars available
163+
return buffer[readPos];
164+
}
165+
166+
IPAddress BridgeUDP::remoteIP()
167+
{
168+
if (!opened)
169+
return -1;
170+
uint8_t cmd[] = {'T', handle};
171+
uint8_t res[7];
172+
uint16_t l = bridge.transfer(cmd, 2, res, 7);
173+
if (res[0] == 0)
174+
return IPAddress(0,0,0,0);
175+
return IPAddress(res[1], res[2], res[3], res[4]);
176+
}
177+
178+
uint16_t BridgeUDP::remotePort()
179+
{
180+
if (!opened)
181+
return -1;
182+
uint8_t cmd[] = {'T', handle};
183+
uint8_t res[7];
184+
uint16_t l = bridge.transfer(cmd, 2, res, 7);
185+
if (res[0] == 0)
186+
return 0;
187+
return (res[5] << 8) + res[6];
188+
}

libraries/Bridge/src/BridgeUdp.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
Copyright (c) 2015 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#pragma once
20+
21+
#include <Udp.h>
22+
#include "Bridge.h"
23+
24+
class BridgeUDP : public UDP {
25+
26+
public:
27+
BridgeUDP(BridgeClass &_b = Bridge);
28+
virtual uint8_t begin(uint16_t);
29+
virtual void stop();
30+
31+
virtual int beginPacket(IPAddress ip, uint16_t port);
32+
virtual int beginPacket(const char *host, uint16_t port);
33+
virtual int endPacket();
34+
virtual size_t write(uint8_t d) { return write(&d, 1); }
35+
virtual size_t write(const uint8_t *buffer, size_t size);
36+
37+
using Print::write;
38+
39+
virtual int parsePacket();
40+
/* return number of bytes available in the current packet,
41+
will return zero if parsePacket hasn't been called yet */
42+
virtual int available() { return avail; }
43+
virtual int read();
44+
virtual int read(unsigned char* buffer, size_t len);
45+
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
46+
virtual int peek();
47+
virtual void flush() { avail = 0; }
48+
49+
virtual IPAddress remoteIP();
50+
virtual uint16_t remotePort();
51+
52+
private:
53+
BridgeClass &bridge;
54+
uint8_t handle;
55+
boolean opened;
56+
57+
private:
58+
void doBuffer();
59+
uint16_t avail;
60+
uint8_t buffered;
61+
uint8_t readPos;
62+
static const int BUFFER_SIZE = 64;
63+
uint8_t buffer[BUFFER_SIZE];
64+
};

0 commit comments

Comments
 (0)