~ubuntu-branches/debian/experimental/arduino/experimental

« back to all changes in this revision

Viewing changes to libraries/Ethernet/EthernetClient.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Howard
  • Date: 2012-03-11 18:19:42 UTC
  • mfrom: (1.1.5) (5.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20120311181942-be2clnbz1gcehixb
Tags: 1:1.0.1~rc1+dfsg-1
New upstream release, experimental.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "w5100.h"
 
2
#include "socket.h"
 
3
 
 
4
extern "C" {
 
5
  #include "string.h"
 
6
}
 
7
 
 
8
#include "Arduino.h"
 
9
 
 
10
#include "Ethernet.h"
 
11
#include "EthernetClient.h"
 
12
#include "EthernetServer.h"
 
13
#include "Dns.h"
 
14
 
 
15
uint16_t EthernetClient::_srcport = 1024;
 
16
 
 
17
EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) {
 
18
}
 
19
 
 
20
EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) {
 
21
}
 
22
 
 
23
int EthernetClient::connect(const char* host, uint16_t port) {
 
24
  // Look up the host first
 
25
  int ret = 0;
 
26
  DNSClient dns;
 
27
  IPAddress remote_addr;
 
28
 
 
29
  dns.begin(Ethernet.dnsServerIP());
 
30
  ret = dns.getHostByName(host, remote_addr);
 
31
  if (ret == 1) {
 
32
    return connect(remote_addr, port);
 
33
  } else {
 
34
    return ret;
 
35
  }
 
36
}
 
37
 
 
38
int EthernetClient::connect(IPAddress ip, 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
 
 
53
  _srcport++;
 
54
  if (_srcport == 0) _srcport = 1024;
 
55
  socket(_sock, SnMR::TCP, _srcport, 0);
 
56
 
 
57
  if (!::connect(_sock, rawIPAddress(ip), port)) {
 
58
    _sock = MAX_SOCK_NUM;
 
59
    return 0;
 
60
  }
 
61
 
 
62
  while (status() != SnSR::ESTABLISHED) {
 
63
    delay(1);
 
64
    if (status() == SnSR::CLOSED) {
 
65
      _sock = MAX_SOCK_NUM;
 
66
      return 0;
 
67
    }
 
68
  }
 
69
 
 
70
  return 1;
 
71
}
 
72
 
 
73
size_t EthernetClient::write(uint8_t b) {
 
74
  return write(&b, 1);
 
75
}
 
76
 
 
77
size_t EthernetClient::write(const uint8_t *buf, size_t size) {
 
78
  if (_sock == MAX_SOCK_NUM) {
 
79
    setWriteError();
 
80
    return 0;
 
81
  }
 
82
  if (!send(_sock, buf, size)) {
 
83
    setWriteError();
 
84
    return 0;
 
85
  }
 
86
  return size;
 
87
}
 
88
 
 
89
int EthernetClient::available() {
 
90
  if (_sock != MAX_SOCK_NUM)
 
91
    return W5100.getRXReceivedSize(_sock);
 
92
  return 0;
 
93
}
 
94
 
 
95
int EthernetClient::read() {
 
96
  uint8_t b;
 
97
  if ( recv(_sock, &b, 1) > 0 )
 
98
  {
 
99
    // recv worked
 
100
    return b;
 
101
  }
 
102
  else
 
103
  {
 
104
    // No data available
 
105
    return -1;
 
106
  }
 
107
}
 
108
 
 
109
int EthernetClient::read(uint8_t *buf, size_t size) {
 
110
  return recv(_sock, buf, size);
 
111
}
 
112
 
 
113
int EthernetClient::peek() {
 
114
  uint8_t b;
 
115
  // Unlike recv, peek doesn't check to see if there's any data available, so we must
 
116
  if (!available())
 
117
    return -1;
 
118
  ::peek(_sock, &b);
 
119
  return b;
 
120
}
 
121
 
 
122
void EthernetClient::flush() {
 
123
  while (available())
 
124
    read();
 
125
}
 
126
 
 
127
void EthernetClient::stop() {
 
128
  if (_sock == MAX_SOCK_NUM)
 
129
    return;
 
130
 
 
131
  // attempt to close the connection gracefully (send a FIN to other side)
 
132
  disconnect(_sock);
 
133
  unsigned long start = millis();
 
134
 
 
135
  // wait a second for the connection to close
 
136
  while (status() != SnSR::CLOSED && millis() - start < 1000)
 
137
    delay(1);
 
138
 
 
139
  // if it hasn't closed, close it forcefully
 
140
  if (status() != SnSR::CLOSED)
 
141
    close(_sock);
 
142
 
 
143
  EthernetClass::_server_port[_sock] = 0;
 
144
  _sock = MAX_SOCK_NUM;
 
145
}
 
146
 
 
147
uint8_t EthernetClient::connected() {
 
148
  if (_sock == MAX_SOCK_NUM) return 0;
 
149
  
 
150
  uint8_t s = status();
 
151
  return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
 
152
    (s == SnSR::CLOSE_WAIT && !available()));
 
153
}
 
154
 
 
155
uint8_t EthernetClient::status() {
 
156
  if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
 
157
  return W5100.readSnSR(_sock);
 
158
}
 
159
 
 
160
// the next function allows us to use the client returned by
 
161
// EthernetServer::available() as the condition in an if-statement.
 
162
 
 
163
EthernetClient::operator bool() {
 
164
  return _sock != MAX_SOCK_NUM;
 
165
}