TinyRobotics
Loading...
Searching...
No Matches
UDPStream.h
1#pragma once
2#include <WiFi.h>
3#include <WiFiUdp.h>
4#if defined(ESP32)
5# include <esp_wifi.h>
6#endif
7#include "TinyRobotics/utils/BaseStream.h"
8
9namespace tinyrobotics {
10
11/**
12 * @class UDPStream
13 * @ingroup communication
14 * @brief A UDP class which makes sure that we can use UDP as
15 * AudioSource and AudioSink. By default the WiFiUDP object is used and we login
16 * to wifi if the ssid and password is provided and we are not already
17 * connected.
18 * @author Phil Schatzmann
19 */
20
21class UDPStream : public BaseStream {
22public:
23 /// Default Constructor
24 UDPStream() = default;
25
26 /// @brief Convinience constructor which defines the optional ssid and
27 /// password
28 /// @param ssid
29 /// @param password
30 UDPStream(const char *ssid, const char *password) {
31 setSSID(ssid);
32 setPassword(password);
33 }
34
35 /// @brief Constructor which defines an alternative UDP object. By default we
36 /// use WiFiUDP
37 /// @param udp
38 UDPStream(UDP &udp) { setUDP(udp); }
39
40 /// @brief Defines an alternative UDP object. By default we use WiFiUDP
41 /// @param udp
42 void setUDP(UDP &udp) { p_udp = &udp; };
43
44 /// Always return 1492 (MTU 1500 - 8 byte header) as UDP packet available to
45 /// write
46 int availableForWrite() { return 1492; }
47
48 /**
49 * Provides the available size of the current package and if this is used up
50 * of the next package
51 */
52 int available() override {
53 int size = p_udp->available();
54 // if the curren package is used up we prvide the info for the next
55 if (size == 0) {
56 size = p_udp->parsePacket();
57 }
58 return size;
59 }
60
61 /// Starts to send data to the indicated address / port
62 bool begin(IPAddress a, uint16_t port) {
64 remote_address_ext = a;
65 remote_port_ext = port;
66 return p_udp->begin(port);
67 }
68
69 /// Starts to receive data from/with the indicated port
70 bool begin(uint16_t port, uint16_t port_ext = 0) {
72 remote_address_ext = IPAddress((uint32_t)0);
73 remote_port_ext = port_ext != 0 ? port_ext : port;
74 printIP();
75 return p_udp->begin(port);
76 }
77
78 /// Starts to receive data in multicast from/with the indicated address / port
79 bool beginMulticast(IPAddress address, uint16_t port) {
81 return p_udp->beginMulticast(address,port);
82 }
83
84 /// We use the same remote port as defined in begin for write
85 uint16_t remotePort() {
86 uint16_t result = p_udp->remotePort();
87 return result != 0 ? result : remote_port_ext;
88 }
89
90 /// We use the same remote ip as defined in begin for write
92 // Determine address if it has not been specified
93 if ((uint32_t)remote_address_ext == 0) {
94 remote_address_ext = p_udp->remoteIP();
95 }
96 // IPAddress result = p_udp->remoteIP();
97 // LOGI("ip: %u", result);
98 return remote_address_ext;
99 }
100
101 /// Replys will be sent to the initial remote caller
102 size_t write(const uint8_t *data, size_t len) override {
103 p_udp->beginPacket(remoteIP(), remotePort());
104 size_t result = p_udp->write(data, len);
105 p_udp->endPacket();
106 return result;
107 }
108
109 /// Reads bytes using WiFi::readBytes
110 size_t readBytes(uint8_t *data, size_t len) override {
111 size_t avail = available();
112 size_t bytes_read = 0;
113 if (avail > 0) {
114 // get the data now
115 bytes_read = p_udp->readBytes((uint8_t *)data, len);
116 }
117 return bytes_read;
118 }
119
120 void setSSID(const char *ssid) { this->ssid = ssid; }
121
122 void setPassword(const char *pwd) { this->password = pwd; }
123
124protected:
125 WiFiUDP default_udp;
126 UDP *p_udp = &default_udp;
127 uint16_t remote_port_ext = 0;
128 IPAddress remote_address_ext;
129 const char *ssid = nullptr;
130 const char *password = nullptr;
131
132 void printIP(){
133 Serial.print(WiFi.localIP());
134 Serial.print(":");
135 Serial.println(remote_port_ext);
136 }
137
138 /// connect to WIFI if necessary
139 void connect() {
140 if (WiFi.status() != WL_CONNECTED && ssid != nullptr &&
141 password != nullptr) {
142 WiFi.begin(ssid, password);
143 while (WiFi.status() != WL_CONNECTED) {
144 delay(500);
145 }
146 }
147#if defined(ESP32)
148 if (WiFi.status() == WL_CONNECTED) {
149 esp_wifi_set_ps(WIFI_PS_NONE);
150 // Performance Hack
151 // client.setNoDelay(true);
152 }
153#endif
154 }
155};
156
157} // namespace audio_tools
Base class for all Streams. It relies on write(const uint8_t *buffer, size_t size) and readBytes(uint...
Definition: BaseStream.h:20
A UDP class which makes sure that we can use UDP as AudioSource and AudioSink. By default the WiFiUDP...
Definition: UDPStream.h:21
IPAddress remoteIP()
We use the same remote ip as defined in begin for write.
Definition: UDPStream.h:91
void connect()
connect to WIFI if necessary
Definition: UDPStream.h:139
uint16_t remotePort()
We use the same remote port as defined in begin for write.
Definition: UDPStream.h:85
size_t readBytes(uint8_t *data, size_t len) override
Reads bytes using WiFi::readBytes.
Definition: UDPStream.h:110
int available() override
Definition: UDPStream.h:52
size_t write(const uint8_t *data, size_t len) override
Replys will be sent to the initial remote caller.
Definition: UDPStream.h:102
int availableForWrite()
Definition: UDPStream.h:46
UDPStream()=default
Default Constructor.
void setUDP(UDP &udp)
Defines an alternative UDP object. By default we use WiFiUDP.
Definition: UDPStream.h:42
bool beginMulticast(IPAddress address, uint16_t port)
Starts to receive data in multicast from/with the indicated address / port.
Definition: UDPStream.h:79
UDPStream(UDP &udp)
Constructor which defines an alternative UDP object. By default we use WiFiUDP.
Definition: UDPStream.h:38
bool begin(uint16_t port, uint16_t port_ext=0)
Starts to receive data from/with the indicated port.
Definition: UDPStream.h:70
bool begin(IPAddress a, uint16_t port)
Starts to send data to the indicated address / port.
Definition: UDPStream.h:62
UDPStream(const char *ssid, const char *password)
Convinience constructor which defines the optional ssid and password.
Definition: UDPStream.h:30