source: rtos_arduino/trunk/arduino_lib/libraries/Ethernet2/src/EthernetUdp2.cpp@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 5.2 KB
Line 
1/*
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 * - 10 Apr. 2015
29 * Added support for Arduino Ethernet Shield 2
30 * by Arduino.org team
31 */
32
33#include "utility/w5500.h"
34#include "utility/socket.h"
35#include "Ethernet2.h"
36#include "Udp.h"
37#include "Dns.h"
38
39/* Constructor */
40EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}
41
42/* Start EthernetUDP socket, listening at local port PORT */
43uint8_t EthernetUDP::begin(uint16_t port) {
44 if (_sock != MAX_SOCK_NUM)
45 return 0;
46
47 for (int i = 0; i < MAX_SOCK_NUM; i++) {
48 uint8_t s = w5500.readSnSR(i);
49 if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
50 _sock = i;
51 break;
52 }
53 }
54
55 if (_sock == MAX_SOCK_NUM)
56 return 0;
57
58 _port = port;
59 _remaining = 0;
60 socket(_sock, SnMR::UDP, _port, 0);
61
62 return 1;
63}
64
65/* return number of bytes available in the current packet,
66 will return zero if parsePacket hasn't been called yet */
67int EthernetUDP::available() {
68 return _remaining;
69}
70
71/* Release any resources being used by this EthernetUDP instance */
72void EthernetUDP::stop()
73{
74 if (_sock == MAX_SOCK_NUM)
75 return;
76
77 close(_sock);
78
79 EthernetClass::_server_port[_sock] = 0;
80 _sock = MAX_SOCK_NUM;
81}
82
83int EthernetUDP::beginPacket(const char *host, uint16_t port)
84{
85 // Look up the host first
86 int ret = 0;
87 DNSClient dns;
88 IPAddress remote_addr;
89
90 dns.begin(Ethernet.dnsServerIP());
91 ret = dns.getHostByName(host, remote_addr);
92 if (ret == 1) {
93 return beginPacket(remote_addr, port);
94 } else {
95 return ret;
96 }
97}
98
99int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
100{
101 _offset = 0;
102 return startUDP(_sock, rawIPAddress(ip), port);
103}
104
105int EthernetUDP::endPacket()
106{
107 return sendUDP(_sock);
108}
109
110size_t EthernetUDP::write(uint8_t byte)
111{
112 return write(&byte, 1);
113}
114
115size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
116{
117 uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
118 _offset += bytes_written;
119 return bytes_written;
120}
121
122int EthernetUDP::parsePacket()
123{
124 // discard any remaining bytes in the last packet
125 flush();
126
127 if (w5500.getRXReceivedSize(_sock) > 0)
128 {
129 //HACK - hand-parse the UDP packet using TCP recv method
130 uint8_t tmpBuf[8];
131 int ret =0;
132 //read 8 header bytes and get IP and port from it
133 ret = recv(_sock,tmpBuf,8);
134 if (ret > 0)
135 {
136 _remoteIP = tmpBuf;
137 _remotePort = tmpBuf[4];
138 _remotePort = (_remotePort << 8) + tmpBuf[5];
139 _remaining = tmpBuf[6];
140 _remaining = (_remaining << 8) + tmpBuf[7];
141
142 // When we get here, any remaining bytes are the data
143 ret = _remaining;
144 }
145 return ret;
146 }
147 // There aren't any packets available
148 return 0;
149}
150
151int EthernetUDP::read()
152{
153 uint8_t byte;
154
155 if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
156 {
157 // We read things without any problems
158 _remaining--;
159 return byte;
160 }
161
162 // If we get here, there's no data available
163 return -1;
164}
165
166int EthernetUDP::read(unsigned char* buffer, size_t len)
167{
168
169 if (_remaining > 0)
170 {
171
172 int got;
173
174 if (_remaining <= len)
175 {
176 // data should fit in the buffer
177 got = recv(_sock, buffer, _remaining);
178 }
179 else
180 {
181 // too much data for the buffer,
182 // grab as much as will fit
183 got = recv(_sock, buffer, len);
184 }
185
186 if (got > 0)
187 {
188 _remaining -= got;
189 return got;
190 }
191
192 }
193
194 // If we get here, there's no data available or recv failed
195 return -1;
196
197}
198
199int EthernetUDP::peek()
200{
201 uint8_t b;
202 // Unlike recv, peek doesn't check to see if there's any data available, so we must.
203 // If the user hasn't called parsePacket yet then return nothing otherwise they
204 // may get the UDP header
205 if (!_remaining)
206 return -1;
207 ::peek(_sock, &b);
208 return b;
209}
210
211void EthernetUDP::flush()
212{
213 // could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
214 // should only occur if recv fails after telling us the data is there, lets
215 // hope the w5500 always behaves :)
216
217 while (_remaining)
218 {
219 read();
220 }
221}
222
Note: See TracBrowser for help on using the repository browser.