123
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; +}