EthernetClient.cpp 3.4 KB

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