31
31
#include " Ethernet.h"
32
32
#include " Udp.h"
33
33
34
+ /* Constructor */
35
+ UDP::UDP () : _sock(MAX_SOCK_NUM) {}
36
+
34
37
/* Start UDP socket, listening at local port PORT */
35
- void UdpClass::begin (uint16_t port) {
38
+ uint8_t UDP::begin (uint16_t port) {
39
+ if (_sock != MAX_SOCK_NUM)
40
+ return 0 ;
41
+
42
+ for (int i = 0 ; i < MAX_SOCK_NUM; i++) {
43
+ uint8_t s = W5100.readSnSR (i);
44
+ if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
45
+ _sock = i;
46
+ break ;
47
+ }
48
+ }
49
+
50
+ if (_sock == MAX_SOCK_NUM)
51
+ return 0 ;
52
+
36
53
_port = port;
37
- _sock = 0 ; // TODO: should not be hardcoded
38
54
socket (_sock, SnMR::UDP, _port, 0 );
55
+
56
+ return 1 ;
39
57
}
40
58
41
59
/* Send packet contained in buf of length len to peer at specified ip, and port */
42
60
/* Use this function to transmit binary data that might contain 0x00 bytes*/
43
61
/* This function returns sent data size for success else -1. */
44
- uint16_t UdpClass ::sendPacket (uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
62
+ uint16_t UDP ::sendPacket (uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
45
63
return sendto (_sock,(const uint8_t *)buf,len,ip,port);
46
64
}
47
65
48
66
/* Send zero-terminated string str as packet to peer at specified ip, and port */
49
67
/* This function returns sent data size for success else -1. */
50
- uint16_t UdpClass ::sendPacket (const char str[], uint8_t * ip, uint16_t port){
68
+ uint16_t UDP ::sendPacket (const char str[], uint8_t * ip, uint16_t port){
51
69
// compute strlen
52
70
const char *s;
53
71
for (s = str; *s; ++s);
@@ -57,7 +75,7 @@ uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
57
75
}
58
76
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
59
77
* returned value includes 8 byte UDP header!*/
60
- int UdpClass ::available () {
78
+ int UDP ::available () {
61
79
return W5100.getRXReceivedSize (_sock);
62
80
}
63
81
@@ -67,7 +85,7 @@ int UdpClass::available() {
67
85
/* NOTE: I don't believe len is ever checked in implementation of recvfrom(),*/
68
86
/* so it's easy to overflow buffer. so we check and truncate. */
69
87
/* returns number of bytes read, or negative number of bytes we would have needed if we truncated */
70
- int UdpClass ::readPacket (uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
88
+ int UDP ::readPacket (uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
71
89
int packetLen = available ()-8 ; // skip UDP header;
72
90
if (packetLen < 0 ) return 0 ; // no real data here
73
91
if (packetLen > (int )bufLen) {
@@ -116,21 +134,28 @@ int UdpClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *
116
134
}
117
135
118
136
/* Read a received packet, throw away peer's ip and port. See note above. */
119
- int UdpClass ::readPacket (uint8_t * buf, uint16_t len) {
137
+ int UDP ::readPacket (uint8_t * buf, uint16_t len) {
120
138
uint8_t ip[4 ];
121
139
uint16_t port[1 ];
122
140
return recvfrom (_sock,buf,len,ip,port);
123
141
}
124
142
125
- int UdpClass ::readPacket (char * buf, uint16_t bufLen, uint8_t *ip, uint16_t &port) {
143
+ int UDP ::readPacket (char * buf, uint16_t bufLen, uint8_t *ip, uint16_t &port) {
126
144
uint16_t myPort;
127
145
uint16_t ret = readPacket ( (byte*)buf, bufLen, ip, &myPort);
128
146
port = myPort;
129
147
return ret;
130
148
}
131
149
150
+ /* Release any resources being used by this UDP instance */
151
+ void UDP::stop ()
152
+ {
153
+ if (_sock == MAX_SOCK_NUM)
154
+ return ;
132
155
156
+ close (_sock);
133
157
158
+ EthernetClass::_server_port[_sock] = 0 ;
159
+ _sock = MAX_SOCK_NUM;
160
+ }
134
161
135
- /* Create one global object */
136
- UdpClass Udp;
0 commit comments