forked from PaulStoffregen/Ethernet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EthernetClient.cpp
141 lines (118 loc) · 3.37 KB
/
EthernetClient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "Ethernet.h"
#include "Dns.h"
#include "w5100.h"
int EthernetClient::connect(const char * host, uint16_t port)
{
DNSClient dns; // Look up the host first
IPAddress remote_addr;
if (sockindex < MAX_SOCK_NUM) {
if (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {
Ethernet.socketDisconnect(sockindex);
}
sockindex = MAX_SOCK_NUM;
}
dns.begin(Ethernet.dnsServerIP());
if (!dns.getHostByName(host, remote_addr)) return 0;
return connect(remote_addr, port);
}
int EthernetClient::connect(IPAddress ip, uint16_t port)
{
if (sockindex < MAX_SOCK_NUM) {
if (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {
Ethernet.socketDisconnect(sockindex);
}
sockindex = MAX_SOCK_NUM;
}
#ifdef ESP8266
if (ip == IPAddress((uint32_t)0) || ip == IPAddress(0xFFFFFFFFul)) return 0;
#else
if (ip == IPAddress(0ul) || ip == IPAddress(0xFFFFFFFFul)) return 0;
#endif
sockindex = Ethernet.socketBegin(SnMR::TCP, 0);
if (sockindex >= MAX_SOCK_NUM) return 0;
Ethernet.socketConnect(sockindex, rawIPAddress(ip), port);
while (1) {
uint8_t stat = Ethernet.socketStatus(sockindex);
if (stat == SnSR::ESTABLISHED) return 1;
if (stat == SnSR::CLOSE_WAIT) return 1;
if (stat == SnSR::CLOSED) return 0;
delay(1);
}
}
size_t EthernetClient::write(uint8_t b)
{
return write(&b, 1);
}
size_t EthernetClient::write(const uint8_t *buf, size_t size)
{
if (sockindex >= MAX_SOCK_NUM) return 0;
if (Ethernet.socketSend(sockindex, buf, size)) return size;
setWriteError();
return 0;
}
int EthernetClient::available()
{
if (sockindex >= MAX_SOCK_NUM) return 0;
return Ethernet.socketRecvAvailable(sockindex);
}
int EthernetClient::read(uint8_t *buf, size_t size)
{
if (sockindex >= MAX_SOCK_NUM) return 0;
return Ethernet.socketRecv(sockindex, buf, size);
}
int EthernetClient::peek()
{
if (sockindex >= MAX_SOCK_NUM) return -1;
if (!available()) return -1;
return Ethernet.socketPeek(sockindex);
}
int EthernetClient::read()
{
uint8_t b;
if (Ethernet.socketRecv(sockindex, &b, 1) > 0) return b;
return -1;
}
void EthernetClient::flush()
{
// TODO: Wait for transmission to complete
}
void EthernetClient::stop()
{
if (sockindex >= MAX_SOCK_NUM) return;
// attempt to close the connection gracefully (send a FIN to other side)
Ethernet.socketDisconnect(sockindex);
unsigned long start = millis();
// wait up to a second for the connection to close
do {
if (Ethernet.socketStatus(sockindex) == SnSR::CLOSED)
{
sockindex = MAX_SOCK_NUM;
return; // exit the loop
}
delay(1);
} while (millis() - start < 1000);
// if it hasn't closed, close it forcefully
Ethernet.socketClose(sockindex);
sockindex = MAX_SOCK_NUM;
}
uint8_t EthernetClient::connected()
{
if (sockindex >= MAX_SOCK_NUM) return 0;
uint8_t s = Ethernet.socketStatus(sockindex);
return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
(s == SnSR::CLOSE_WAIT && !available()));
}
uint8_t EthernetClient::status()
{
if (sockindex >= MAX_SOCK_NUM) return SnSR::CLOSED;
return Ethernet.socketStatus(sockindex);
}
// the next function allows us to use the client returned by
// EthernetServer::available() as the condition in an if-statement.
bool EthernetClient::operator==(const EthernetClient& rhs)
{
if (sockindex != rhs.sockindex) return false;
if (sockindex >= MAX_SOCK_NUM) return false;
if (rhs.sockindex >= MAX_SOCK_NUM) return false;
return true;
}