root / arduino-1.0 / libraries / Ethernet / EthernetUdp.cpp @ 58d82c77
History | View | Annotate | Download (4.5 KB)
1 | 58d82c77 | Tom Mullins | /*
|
---|---|---|---|
2 | * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||
3 | * This version only offers minimal wrapping of socket.c/socket.h
|
||
4 | * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
|
||
5 | *
|
||
6 | * MIT License:
|
||
7 | * Copyright (c) 2008 Bjoern Hartmann
|
||
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
9 | * of this software and associated documentation files (the "Software"), to deal
|
||
10 | * in the Software without restriction, including without limitation the rights
|
||
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
12 | * copies of the Software, and to permit persons to whom the Software is
|
||
13 | * furnished to do so, subject to the following conditions:
|
||
14 | *
|
||
15 | * The above copyright notice and this permission notice shall be included in
|
||
16 | * all copies or substantial portions of the Software.
|
||
17 | *
|
||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
24 | * THE SOFTWARE.
|
||
25 | *
|
||
26 | * bjoern@cs.stanford.edu 12/30/2008
|
||
27 | */
|
||
28 | |||
29 | #include "w5100.h" |
||
30 | #include "socket.h" |
||
31 | #include "Ethernet.h" |
||
32 | #include "Udp.h" |
||
33 | #include "Dns.h" |
||
34 | |||
35 | /* Constructor */
|
||
36 | EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {} |
||
37 | |||
38 | /* Start EthernetUDP socket, listening at local port PORT */
|
||
39 | uint8_t EthernetUDP::begin(uint16_t port) { |
||
40 | if (_sock != MAX_SOCK_NUM)
|
||
41 | return 0; |
||
42 | |||
43 | for (int i = 0; i < MAX_SOCK_NUM; i++) { |
||
44 | uint8_t s = W5100.readSnSR(i); |
||
45 | if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
|
||
46 | _sock = i; |
||
47 | break;
|
||
48 | } |
||
49 | } |
||
50 | |||
51 | if (_sock == MAX_SOCK_NUM)
|
||
52 | return 0; |
||
53 | |||
54 | _port = port; |
||
55 | socket(_sock, SnMR::UDP, _port, 0);
|
||
56 | |||
57 | return 1; |
||
58 | } |
||
59 | |||
60 | /* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
|
||
61 | * returned value includes 8 byte UDP header!*/
|
||
62 | int EthernetUDP::available() {
|
||
63 | return W5100.getRXReceivedSize(_sock);
|
||
64 | } |
||
65 | |||
66 | /* Release any resources being used by this EthernetUDP instance */
|
||
67 | void EthernetUDP::stop()
|
||
68 | { |
||
69 | if (_sock == MAX_SOCK_NUM)
|
||
70 | return;
|
||
71 | |||
72 | close(_sock); |
||
73 | |||
74 | EthernetClass::_server_port[_sock] = 0;
|
||
75 | _sock = MAX_SOCK_NUM; |
||
76 | } |
||
77 | |||
78 | int EthernetUDP::beginPacket(const char *host, uint16_t port) |
||
79 | { |
||
80 | // Look up the host first
|
||
81 | int ret = 0; |
||
82 | DNSClient dns; |
||
83 | IPAddress remote_addr; |
||
84 | |||
85 | dns.begin(Ethernet.dnsServerIP()); |
||
86 | ret = dns.getHostByName(host, remote_addr); |
||
87 | if (ret == 1) { |
||
88 | return beginPacket(remote_addr, port);
|
||
89 | } else {
|
||
90 | return ret;
|
||
91 | } |
||
92 | } |
||
93 | |||
94 | int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
|
||
95 | { |
||
96 | _offset = 0;
|
||
97 | return startUDP(_sock, rawIPAddress(ip), port);
|
||
98 | } |
||
99 | |||
100 | int EthernetUDP::endPacket()
|
||
101 | { |
||
102 | return sendUDP(_sock);
|
||
103 | } |
||
104 | |||
105 | size_t EthernetUDP::write(uint8_t byte) |
||
106 | { |
||
107 | return write(&byte, 1); |
||
108 | } |
||
109 | |||
110 | size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
|
||
111 | { |
||
112 | uint16_t bytes_written = bufferData(_sock, _offset, buffer, size); |
||
113 | _offset += bytes_written; |
||
114 | return bytes_written;
|
||
115 | } |
||
116 | |||
117 | int EthernetUDP::parsePacket()
|
||
118 | { |
||
119 | if (available() > 0) |
||
120 | { |
||
121 | //HACK - hand-parse the UDP packet using TCP recv method
|
||
122 | uint8_t tmpBuf[8];
|
||
123 | int ret =0; |
||
124 | //read 8 header bytes and get IP and port from it
|
||
125 | ret = recv(_sock,tmpBuf,8);
|
||
126 | if (ret > 0) |
||
127 | { |
||
128 | _remoteIP = tmpBuf; |
||
129 | _remotePort = tmpBuf[4];
|
||
130 | _remotePort = (_remotePort << 8) + tmpBuf[5]; |
||
131 | // When we get here, any remaining bytes are the data
|
||
132 | ret = available(); |
||
133 | } |
||
134 | return ret;
|
||
135 | } |
||
136 | // There aren't any packets available
|
||
137 | return 0; |
||
138 | } |
||
139 | |||
140 | int EthernetUDP::read()
|
||
141 | { |
||
142 | uint8_t byte; |
||
143 | if (recv(_sock, &byte, 1) > 0) |
||
144 | { |
||
145 | // We read things without any problems
|
||
146 | return byte;
|
||
147 | } |
||
148 | // If we get here, there's no data available
|
||
149 | return -1; |
||
150 | } |
||
151 | |||
152 | int EthernetUDP::read(unsigned char* buffer, size_t len) |
||
153 | { |
||
154 | /* In the readPacket that copes with truncating packets, the buffer was
|
||
155 | filled with this code. Not sure why it loops round reading out a byte
|
||
156 | at a time.
|
||
157 | int i;
|
||
158 | for(i=0;i<(int)bufLen;i++) {
|
||
159 | recv(_sock,tmpBuf,1);
|
||
160 | buf[i]=tmpBuf[0];
|
||
161 | }
|
||
162 | */
|
||
163 | return recv(_sock, buffer, len);
|
||
164 | } |
||
165 | |||
166 | int EthernetUDP::peek()
|
||
167 | { |
||
168 | uint8_t b; |
||
169 | // Unlike recv, peek doesn't check to see if there's any data available, so we must
|
||
170 | if (!available())
|
||
171 | return -1; |
||
172 | ::peek(_sock, &b); |
||
173 | return b;
|
||
174 | } |
||
175 | |||
176 | void EthernetUDP::flush()
|
||
177 | { |
||
178 | while (available())
|
||
179 | { |
||
180 | read(); |
||
181 | } |
||
182 | } |