Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: UdpSocket.cpp
- Revision:
- 14:7648334eb41b
- Parent:
- 11:647d53d146f1
- Child:
- 15:53715cc81c63
--- a/UdpSocket.cpp Sat Aug 31 20:34:52 2019 +0000
+++ b/UdpSocket.cpp Tue Sep 03 09:16:55 2019 +0000
@@ -30,13 +30,47 @@
#define UIP_ARPHDRSIZE 42
#define UDPBUF ((struct uip_udpip_hdr*) &uip_buf[UIP_LLH_LEN])
-// Constructor
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
UdpSocket::UdpSocket() :
- _uip_udp_conn(NULL)
+ _uip_udp_conn(NULL),
+ _timeout_ms(1000)
{
memset(&appdata, 0, sizeof(appdata));
}
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+UdpSocket::UdpSocket(int timeout_ms) :
+ _uip_udp_conn(NULL),
+ _timeout_ms(timeout_ms)
+{
+ memset(&appdata, 0, sizeof(appdata));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+UdpSocket::UdpSocket(UipEthernet* net, int timeout_ms /*= 1000*/ ) :
+ _uip_udp_conn(NULL),
+ _timeout_ms(timeout_ms)
+{
+ memset(&appdata, 0, sizeof(appdata));
+ if (UipEthernet::ethernet != net)
+ UipEthernet::ethernet = net;
+}
+
// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
uint8_t UdpSocket::begin(uint16_t port)
{
@@ -67,6 +101,17 @@
}
}
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UdpSocket::close()
+{
+ stop();
+}
+
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
@@ -222,13 +267,13 @@
}
// Number of bytes remaining in the current packet
-int UdpSocket::available()
+size_t UdpSocket::available()
{
UipEthernet::ethernet->tick();
return UipEthernet::ethernet->enc28j60Eth.blockSize(appdata.packet_in);
}
-// Read a single byte from the current packet
+// Read a single byte from the current packet. Returns -1 if no byte is available.
int UdpSocket::read()
{
static unsigned char c;
@@ -242,7 +287,7 @@
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
-int UdpSocket::read(unsigned char* buffer, size_t len)
+size_t UdpSocket::read(unsigned char* buffer, size_t len)
{
UipEthernet::ethernet->tick();
if (appdata.packet_in != NOBLOCK) {
@@ -372,3 +417,116 @@
UipEthernet::ethernet->network_send();
}
#endif
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+nsapi_size_or_error_t UdpSocket::sendto(const char* host, uint16_t port, const void* data, size_t size)
+{
+ DnsClient dns;
+ IpAddress address;
+ uint32_t address_bytes;
+
+ dns.begin(UipEthernet::ethernet->dnsServerIP());
+ if (dns.getHostByName(host, address) == 1) {
+ address_bytes = address;
+ _remote_addr = SocketAddress(&address_bytes, NSAPI_IPv4, port);
+ }
+ else {
+ _remote_addr = SocketAddress(host, port);
+ }
+
+ if (beginPacket(host, port) == 0) {
+ stop();
+ return NSAPI_ERROR_NO_ADDRESS;
+ }
+
+ if (write((uint8_t*)data, size) == 0) {
+ stop();
+ return NSAPI_ERROR_WOULD_BLOCK;
+ };
+
+ if (endPacket() <= 0) {
+ stop();
+ return NSAPI_ERROR_WOULD_BLOCK;
+ }
+
+ return NSAPI_ERROR_OK;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+nsapi_size_or_error_t UdpSocket::sendto(const SocketAddress& address, const void* data, size_t size)
+{
+ IpAddress ip_addr(address.get_addr().bytes);
+ uint16_t port = address.get_port();
+
+ _remote_addr = address;
+
+ if (beginPacket(ip_addr, port) == 0) {
+ stop();
+ return NSAPI_ERROR_NO_ADDRESS;
+ }
+
+ if (write((uint8_t*)data, size) == 0) {
+ stop();
+ return NSAPI_ERROR_WOULD_BLOCK;
+ };
+
+ if (endPacket() <= 0) {
+ stop();
+ return NSAPI_ERROR_WOULD_BLOCK;
+ }
+
+ return NSAPI_ERROR_OK;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+nsapi_size_or_error_t UdpSocket::recvfrom(SocketAddress* address, void* data, size_t size)
+{
+ *address = _remote_addr;
+
+ Timer timer;
+ int success;
+
+ timer.start();
+ do {
+ success = parsePacket();
+ } while (!success && (timer.read_ms() < _timeout_ms));
+
+ if (!success) {
+ stop();
+ return NSAPI_ERROR_WOULD_BLOCK;
+ }
+
+ size_t n;
+ size_t recv_count = 0;
+ uint8_t* pos = (uint8_t*)data;
+
+ do {
+ if (recv_count + available() <= size) {
+ n = read(pos, available());
+ pos += n;
+ recv_count += n;
+ }
+ else {
+ return NSAPI_ERROR_NO_MEMORY;
+ }
+ } while ((available() > 0) && (recv_count < size));
+
+ flush();
+
+ return NSAPI_ERROR_OK;
+}