W5500 driver for mbed OS 5

Dependents:   http-webserver-example mbed-os-example-sockets

Fork of W5500Interface by Sergei G

Committer:
sgnezdov
Date:
Thu Jul 06 04:51:34 2017 +0000
Revision:
4:80e302a610fd
Parent:
3:61ff27ed8355
Child:
5:41393623ead4
added missing socket_bind on socket_sendto; ; Built-in mbed dns code does not bind explicitly.   This results in a missing socket_bind call, which makes dns messages to fail to send.; ; Exposed W5500 socket_closed to adapter.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgriffin65 0:77e050d1fb12 1 // EthernetInterface for W5500 2014/8/20
dgriffin65 0:77e050d1fb12 2 /*
dgriffin65 0:77e050d1fb12 3 // sample usgae.
dgriffin65 0:77e050d1fb12 4 // copy below code block to main code.
dgriffin65 0:77e050d1fb12 5
dgriffin65 0:77e050d1fb12 6 #if defined(TARGET_LPC1114)
dgriffin65 0:77e050d1fb12 7 SPI spi(dp2, dp1, dp6); // mosi, miso, sclk
dgriffin65 0:77e050d1fb12 8 EthernetInterface eth(&spi, dp25, dp26); // spi, cs, reset
dgriffin65 0:77e050d1fb12 9 wait(1); // 1 second for stable state
dgriffin65 0:77e050d1fb12 10 #elif defined(TARGET_LPC1768)
dgriffin65 0:77e050d1fb12 11 SPI spi(p11, p12, p13); // mosi, miso, sclk
dgriffin65 0:77e050d1fb12 12 EthernetInterface eth(&spi, p14, p15); // spi, cs, reset
dgriffin65 0:77e050d1fb12 13 wait(1); // 1 second for stable state
dgriffin65 0:77e050d1fb12 14 #elif defined(TARGET_LPC11U68)
dgriffin65 0:77e050d1fb12 15 SPI spi(P0_9, P0_8, P1_29); // mosi, miso, sclk
dgriffin65 0:77e050d1fb12 16 EthernetInterface eth(&spi, P0_2, P1_28);//, nRESET(p9); // reset pin is dummy, don't affect any pin of WIZ550io
dgriffin65 0:77e050d1fb12 17 spi.format(8,0); // 8bit, mode 0
dgriffin65 0:77e050d1fb12 18 spi.frequency(7000000); // 7MHz
dgriffin65 0:77e050d1fb12 19 wait(1); // 1 second for stable state
dgriffin65 0:77e050d1fb12 20 #endif
dgriffin65 0:77e050d1fb12 21
dgriffin65 0:77e050d1fb12 22 eth.init(); //Use DHCP
dgriffin65 0:77e050d1fb12 23 dbg.printf("init\r\n");
dgriffin65 0:77e050d1fb12 24 eth.connect();
dgriffin65 0:77e050d1fb12 25 dbg.printf("IP address: %s\r\n", eth.getIPAddress());
dgriffin65 0:77e050d1fb12 26
dgriffin65 0:77e050d1fb12 27 */
dgriffin65 0:77e050d1fb12 28
dgriffin65 0:77e050d1fb12 29 #include "mbed.h"
dgriffin65 0:77e050d1fb12 30 #include "W5500Interface.h"
dgriffin65 0:77e050d1fb12 31
dgriffin65 0:77e050d1fb12 32 static int udp_local_port = 0;
dgriffin65 0:77e050d1fb12 33
dgriffin65 1:2dee44ea52a9 34 DigitalOut led1(LED1);
dgriffin65 1:2dee44ea52a9 35
dgriffin65 0:77e050d1fb12 36 #define SKT(h) ((w5500_socket*)h)
sgnezdov 4:80e302a610fd 37 #define w5500_WAIT_TIMEOUT 5000
dgriffin65 0:77e050d1fb12 38 #define w5500_ACCEPT_TIMEOUT 3000
sgnezdov 4:80e302a610fd 39 #define w5500_INTF_DBG 1
dgriffin65 0:77e050d1fb12 40
dgriffin65 0:77e050d1fb12 41 /* Interface implementation */
dgriffin65 0:77e050d1fb12 42
dgriffin65 0:77e050d1fb12 43 W5500Interface::W5500Interface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset) :
dgriffin65 0:77e050d1fb12 44 WIZnet_Chip(mosi, miso, sclk, cs, reset)
dgriffin65 0:77e050d1fb12 45 {
dgriffin65 0:77e050d1fb12 46 ip_set = false;
dgriffin65 0:77e050d1fb12 47 }
dgriffin65 0:77e050d1fb12 48
dgriffin65 0:77e050d1fb12 49 W5500Interface::W5500Interface(SPI* spi, PinName cs, PinName reset) :
dgriffin65 0:77e050d1fb12 50 WIZnet_Chip(spi, cs, reset)
dgriffin65 0:77e050d1fb12 51 {
dgriffin65 0:77e050d1fb12 52 ip_set = false;
dgriffin65 0:77e050d1fb12 53 }
dgriffin65 0:77e050d1fb12 54
dgriffin65 1:2dee44ea52a9 55 w5500_socket* W5500Interface::get_sock(int fd)
dgriffin65 1:2dee44ea52a9 56 {
dgriffin65 1:2dee44ea52a9 57 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 58 if (w5500_sockets[i].fd == -1) {
dgriffin65 1:2dee44ea52a9 59 w5500_sockets[i].fd = fd;
dgriffin65 1:2dee44ea52a9 60 w5500_sockets[i].proto = NSAPI_TCP;
dgriffin65 1:2dee44ea52a9 61 w5500_sockets[i].connected = false;
dgriffin65 1:2dee44ea52a9 62 w5500_sockets[i].callback = NULL;
dgriffin65 1:2dee44ea52a9 63 w5500_sockets[i].callback_data = NULL;
dgriffin65 1:2dee44ea52a9 64 return &w5500_sockets[i];
dgriffin65 1:2dee44ea52a9 65 }
dgriffin65 1:2dee44ea52a9 66 }
dgriffin65 1:2dee44ea52a9 67 return NULL;
dgriffin65 1:2dee44ea52a9 68 }
dgriffin65 1:2dee44ea52a9 69
dgriffin65 1:2dee44ea52a9 70 void W5500Interface::init_socks()
dgriffin65 1:2dee44ea52a9 71 {
dgriffin65 1:2dee44ea52a9 72 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 73 w5500_sockets[i].fd = -1;
dgriffin65 1:2dee44ea52a9 74 w5500_sockets[i].proto = NSAPI_TCP;
dgriffin65 1:2dee44ea52a9 75 w5500_sockets[i].callback = NULL;
dgriffin65 1:2dee44ea52a9 76 w5500_sockets[i].callback_data = NULL;
dgriffin65 1:2dee44ea52a9 77 w5500_sockets[i].connected = false;
dgriffin65 1:2dee44ea52a9 78 }
dgriffin65 1:2dee44ea52a9 79
dgriffin65 1:2dee44ea52a9 80 //initialize the socket isr
dgriffin65 1:2dee44ea52a9 81 _daemon = new Thread(osPriorityNormal, 1024);
dgriffin65 1:2dee44ea52a9 82 _daemon->start(callback(this, &W5500Interface::daemon));
dgriffin65 1:2dee44ea52a9 83 }
dgriffin65 1:2dee44ea52a9 84
dgriffin65 0:77e050d1fb12 85 int W5500Interface::init()
dgriffin65 0:77e050d1fb12 86 {
dgriffin65 0:77e050d1fb12 87 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
dgriffin65 1:2dee44ea52a9 88 //WIZnet_Chip::reg_wr<uint8_t>(SIMR, 0xFF); //
dgriffin65 0:77e050d1fb12 89 reset();
dgriffin65 1:2dee44ea52a9 90 init_socks();
dgriffin65 0:77e050d1fb12 91 return 0;
dgriffin65 0:77e050d1fb12 92 }
dgriffin65 0:77e050d1fb12 93
dgriffin65 0:77e050d1fb12 94 int W5500Interface::init(uint8_t * mac)
dgriffin65 0:77e050d1fb12 95 {
sgnezdov 2:06b6f9f7c071 96 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
dgriffin65 0:77e050d1fb12 97 for (int i =0; i < 6; i++) this->mac[i] = mac[i];
dgriffin65 0:77e050d1fb12 98 setmac();
sgnezdov 2:06b6f9f7c071 99 reset(); // sets buffers; does not alter MAC
dgriffin65 1:2dee44ea52a9 100 init_socks();
dgriffin65 0:77e050d1fb12 101 return 0;
dgriffin65 0:77e050d1fb12 102 }
dgriffin65 0:77e050d1fb12 103
dgriffin65 0:77e050d1fb12 104 // add this function, because sometimes no needed MAC address in init calling.
dgriffin65 0:77e050d1fb12 105 int W5500Interface::init(const char* ip, const char* mask, const char* gateway)
dgriffin65 0:77e050d1fb12 106 {
dgriffin65 0:77e050d1fb12 107 this->ip = str_to_ip(ip);
dgriffin65 0:77e050d1fb12 108 strcpy(ip_string, ip);
dgriffin65 0:77e050d1fb12 109 ip_set = true;
dgriffin65 0:77e050d1fb12 110 this->netmask = str_to_ip(mask);
dgriffin65 0:77e050d1fb12 111 this->gateway = str_to_ip(gateway);
dgriffin65 0:77e050d1fb12 112 reset();
dgriffin65 0:77e050d1fb12 113
dgriffin65 0:77e050d1fb12 114 // @Jul. 8. 2014 add code. should be called to write chip.
dgriffin65 0:77e050d1fb12 115 setip();
dgriffin65 1:2dee44ea52a9 116 init_socks();
dgriffin65 0:77e050d1fb12 117
dgriffin65 0:77e050d1fb12 118 return 0;
dgriffin65 0:77e050d1fb12 119 }
dgriffin65 0:77e050d1fb12 120
dgriffin65 0:77e050d1fb12 121 int W5500Interface::init(uint8_t * mac, const char* ip, const char* mask, const char* gateway)
dgriffin65 0:77e050d1fb12 122 {
dgriffin65 0:77e050d1fb12 123 //
dgriffin65 0:77e050d1fb12 124 for (int i =0; i < 6; i++) this->mac[i] = mac[i];
dgriffin65 0:77e050d1fb12 125 //
dgriffin65 0:77e050d1fb12 126 this->ip = str_to_ip(ip);
dgriffin65 0:77e050d1fb12 127 strcpy(ip_string, ip);
dgriffin65 0:77e050d1fb12 128 ip_set = true;
dgriffin65 0:77e050d1fb12 129 this->netmask = str_to_ip(mask);
dgriffin65 0:77e050d1fb12 130 this->gateway = str_to_ip(gateway);
dgriffin65 0:77e050d1fb12 131 reset();
dgriffin65 0:77e050d1fb12 132
dgriffin65 0:77e050d1fb12 133 // @Jul. 8. 2014 add code. should be called to write chip.
dgriffin65 0:77e050d1fb12 134 setmac();
dgriffin65 0:77e050d1fb12 135 setip();
dgriffin65 1:2dee44ea52a9 136 init_socks();
dgriffin65 0:77e050d1fb12 137
dgriffin65 0:77e050d1fb12 138 return 0;
dgriffin65 0:77e050d1fb12 139 }
dgriffin65 0:77e050d1fb12 140
dgriffin65 1:2dee44ea52a9 141 void W5500Interface::daemon () {
dgriffin65 1:2dee44ea52a9 142 for (;;) {
dgriffin65 1:2dee44ea52a9 143 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 144 if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) {
dgriffin65 1:2dee44ea52a9 145 int size = sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR);
dgriffin65 1:2dee44ea52a9 146 if (size > 0) {
dgriffin65 1:2dee44ea52a9 147 led1 = !led1;
dgriffin65 1:2dee44ea52a9 148 w5500_sockets[i].callback(w5500_sockets[i].callback_data);
dgriffin65 1:2dee44ea52a9 149 }
dgriffin65 1:2dee44ea52a9 150 }
dgriffin65 1:2dee44ea52a9 151 }
dgriffin65 1:2dee44ea52a9 152 wait(0.2);
dgriffin65 1:2dee44ea52a9 153 }
dgriffin65 1:2dee44ea52a9 154 }
dgriffin65 1:2dee44ea52a9 155
dgriffin65 0:77e050d1fb12 156 int W5500Interface::connect()
dgriffin65 0:77e050d1fb12 157 {
dgriffin65 0:77e050d1fb12 158 if (WIZnet_Chip::setip() == false) return NSAPI_ERROR_DHCP_FAILURE;
dgriffin65 0:77e050d1fb12 159 return 0;
dgriffin65 0:77e050d1fb12 160 }
dgriffin65 0:77e050d1fb12 161
dgriffin65 0:77e050d1fb12 162 int W5500Interface::disconnect()
dgriffin65 0:77e050d1fb12 163 {
dgriffin65 0:77e050d1fb12 164 WIZnet_Chip::disconnect();
dgriffin65 0:77e050d1fb12 165 return 0;
dgriffin65 0:77e050d1fb12 166 }
dgriffin65 0:77e050d1fb12 167
dgriffin65 0:77e050d1fb12 168 const char *W5500Interface::get_ip_address()
dgriffin65 0:77e050d1fb12 169 {
dgriffin65 0:77e050d1fb12 170 uint32_t ip = reg_rd<uint32_t>(SIPR);
dgriffin65 0:77e050d1fb12 171 snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
dgriffin65 0:77e050d1fb12 172 return ip_string;
dgriffin65 0:77e050d1fb12 173 }
dgriffin65 0:77e050d1fb12 174
dgriffin65 0:77e050d1fb12 175 const char *W5500Interface::get_mac_address()
dgriffin65 0:77e050d1fb12 176 {
dgriffin65 0:77e050d1fb12 177 uint8_t mac[6];
dgriffin65 0:77e050d1fb12 178 reg_rd_mac(SHAR, mac);
dgriffin65 0:77e050d1fb12 179 snprintf(mac_string, sizeof(mac_string), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
dgriffin65 0:77e050d1fb12 180 return mac_string;
dgriffin65 0:77e050d1fb12 181 }
dgriffin65 0:77e050d1fb12 182
sgnezdov 2:06b6f9f7c071 183 void W5500Interface::get_mac(uint8_t mac[6])
sgnezdov 2:06b6f9f7c071 184 {
sgnezdov 2:06b6f9f7c071 185 reg_rd_mac(SHAR, mac);
sgnezdov 2:06b6f9f7c071 186 }
sgnezdov 2:06b6f9f7c071 187
dgriffin65 0:77e050d1fb12 188 nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
dgriffin65 0:77e050d1fb12 189 {
dgriffin65 0:77e050d1fb12 190 //a socket is created the same way regardless of the protocol
dgriffin65 0:77e050d1fb12 191 int sock_fd = WIZnet_Chip::new_socket();
dgriffin65 0:77e050d1fb12 192 if (sock_fd < 0) {
dgriffin65 0:77e050d1fb12 193 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 194 }
dgriffin65 0:77e050d1fb12 195
dgriffin65 1:2dee44ea52a9 196 w5500_socket *h = get_sock(sock_fd);
dgriffin65 0:77e050d1fb12 197
dgriffin65 1:2dee44ea52a9 198 if (!h) {
dgriffin65 1:2dee44ea52a9 199 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 1:2dee44ea52a9 200 }
dgriffin65 1:2dee44ea52a9 201
dgriffin65 1:2dee44ea52a9 202 h->proto = proto;
dgriffin65 1:2dee44ea52a9 203 h->connected = false;
dgriffin65 1:2dee44ea52a9 204 h->callback = NULL;
dgriffin65 1:2dee44ea52a9 205 h->callback_data = NULL;
dgriffin65 0:77e050d1fb12 206
dgriffin65 0:77e050d1fb12 207 //new up an int to store the socket fd
dgriffin65 0:77e050d1fb12 208 *handle = h;
sgnezdov 4:80e302a610fd 209 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 210 debug("[socket_open] fd: %d\n", sock_fd);
sgnezdov 4:80e302a610fd 211 #endif
dgriffin65 0:77e050d1fb12 212 return 0;
dgriffin65 0:77e050d1fb12 213 }
dgriffin65 0:77e050d1fb12 214
dgriffin65 1:2dee44ea52a9 215 void W5500Interface::signal_event(nsapi_socket_t handle)
dgriffin65 1:2dee44ea52a9 216 {
sgnezdov 4:80e302a610fd 217 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 218 debug("[signal_event] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 219 #endif
dgriffin65 1:2dee44ea52a9 220 if (SKT(handle)->callback != NULL) {
dgriffin65 1:2dee44ea52a9 221 SKT(handle)->callback(SKT(handle)->callback_data);
dgriffin65 1:2dee44ea52a9 222 }
dgriffin65 1:2dee44ea52a9 223 }
dgriffin65 1:2dee44ea52a9 224
dgriffin65 0:77e050d1fb12 225 nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle)
dgriffin65 0:77e050d1fb12 226 {
dgriffin65 0:77e050d1fb12 227 if (handle == NULL) return 0;
sgnezdov 4:80e302a610fd 228 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 229 debug("[socket_close] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 230 #endif
dgriffin65 0:77e050d1fb12 231 WIZnet_Chip::close(SKT(handle)->fd);
dgriffin65 1:2dee44ea52a9 232
dgriffin65 1:2dee44ea52a9 233 SKT(handle)->fd = -1;
dgriffin65 1:2dee44ea52a9 234
dgriffin65 0:77e050d1fb12 235 return 0;
dgriffin65 0:77e050d1fb12 236 }
dgriffin65 0:77e050d1fb12 237
dgriffin65 0:77e050d1fb12 238 nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address)
dgriffin65 0:77e050d1fb12 239 {
dgriffin65 0:77e050d1fb12 240 if (handle < 0) {
dgriffin65 0:77e050d1fb12 241 return NSAPI_ERROR_DEVICE_ERROR;
dgriffin65 0:77e050d1fb12 242 }
sgnezdov 4:80e302a610fd 243 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 244 debug("[socket_bind] fd: %d, port: %d\n", SKT(handle)->fd, address.get_port());
sgnezdov 4:80e302a610fd 245 #endif
dgriffin65 0:77e050d1fb12 246
dgriffin65 0:77e050d1fb12 247 switch (SKT(handle)->proto) {
dgriffin65 0:77e050d1fb12 248 case NSAPI_UDP:
dgriffin65 0:77e050d1fb12 249 // set local port
dgriffin65 0:77e050d1fb12 250 if (address.get_port() != 0) {
dgriffin65 0:77e050d1fb12 251 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port());
dgriffin65 0:77e050d1fb12 252 } else {
dgriffin65 0:77e050d1fb12 253 udp_local_port++;
dgriffin65 0:77e050d1fb12 254 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, udp_local_port);
dgriffin65 0:77e050d1fb12 255 }
dgriffin65 0:77e050d1fb12 256 // set udp protocol
dgriffin65 0:77e050d1fb12 257 WIZnet_Chip::setProtocol(SKT(handle)->fd, UDP);
dgriffin65 0:77e050d1fb12 258 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN);
dgriffin65 0:77e050d1fb12 259 return 0;
dgriffin65 0:77e050d1fb12 260 case NSAPI_TCP:
dgriffin65 0:77e050d1fb12 261 listen_port = address.get_port();
dgriffin65 0:77e050d1fb12 262 // set TCP protocol
dgriffin65 0:77e050d1fb12 263 WIZnet_Chip::setProtocol(SKT(handle)->fd, TCP);
dgriffin65 0:77e050d1fb12 264 // set local port
dgriffin65 0:77e050d1fb12 265 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port());
dgriffin65 0:77e050d1fb12 266 // connect the network
dgriffin65 0:77e050d1fb12 267 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN);
dgriffin65 0:77e050d1fb12 268 return 0;
dgriffin65 0:77e050d1fb12 269 }
dgriffin65 0:77e050d1fb12 270
dgriffin65 0:77e050d1fb12 271 return NSAPI_ERROR_DEVICE_ERROR;
dgriffin65 0:77e050d1fb12 272 }
dgriffin65 0:77e050d1fb12 273
dgriffin65 0:77e050d1fb12 274 nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog)
dgriffin65 0:77e050d1fb12 275 {
sgnezdov 4:80e302a610fd 276 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 277 debug("[socket_listen] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 278 #endif
dgriffin65 0:77e050d1fb12 279 if (SKT(handle)->fd < 0) {
dgriffin65 0:77e050d1fb12 280 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 281 }
dgriffin65 0:77e050d1fb12 282 if (backlog != 1) {
dgriffin65 0:77e050d1fb12 283 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 284 }
dgriffin65 0:77e050d1fb12 285 WIZnet_Chip::scmd(SKT(handle)->fd, LISTEN);
dgriffin65 0:77e050d1fb12 286 return 0;
dgriffin65 0:77e050d1fb12 287 }
dgriffin65 0:77e050d1fb12 288
dgriffin65 0:77e050d1fb12 289 nsapi_size_or_error_t W5500Interface::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
dgriffin65 0:77e050d1fb12 290 {
sgnezdov 4:80e302a610fd 291 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 292 debug("[socket_connect] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 293 #endif
dgriffin65 0:77e050d1fb12 294 //check for a valid socket
dgriffin65 0:77e050d1fb12 295 if (SKT(handle)->fd < 0) {
dgriffin65 0:77e050d1fb12 296 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 297 }
dgriffin65 0:77e050d1fb12 298
dgriffin65 0:77e050d1fb12 299 //before we attempt to connect, we are not connected
dgriffin65 0:77e050d1fb12 300 SKT(handle)->connected = false;
dgriffin65 0:77e050d1fb12 301
dgriffin65 0:77e050d1fb12 302 //try to connect
dgriffin65 0:77e050d1fb12 303 if (!WIZnet_Chip::connect(SKT(handle)->fd, address.get_ip_address(), address.get_port(), 0)) {
dgriffin65 0:77e050d1fb12 304 return -1;
dgriffin65 0:77e050d1fb12 305 }
dgriffin65 0:77e050d1fb12 306
dgriffin65 0:77e050d1fb12 307 //we are now connected
dgriffin65 0:77e050d1fb12 308 SKT(handle)->connected = true;
dgriffin65 0:77e050d1fb12 309
dgriffin65 0:77e050d1fb12 310 return 0;
dgriffin65 0:77e050d1fb12 311 }
dgriffin65 0:77e050d1fb12 312
dgriffin65 0:77e050d1fb12 313 nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
dgriffin65 0:77e050d1fb12 314 {
sgnezdov 4:80e302a610fd 315 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 316 debug("[socket_accept] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 317 #endif
dgriffin65 0:77e050d1fb12 318 if (SKT(server)->fd < 0) {
dgriffin65 0:77e050d1fb12 319 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 320 }
dgriffin65 0:77e050d1fb12 321
dgriffin65 0:77e050d1fb12 322 SKT(server)->connected = false;
dgriffin65 0:77e050d1fb12 323
dgriffin65 0:77e050d1fb12 324 Timer t;
dgriffin65 0:77e050d1fb12 325 t.reset();
dgriffin65 0:77e050d1fb12 326 t.start();
dgriffin65 1:2dee44ea52a9 327
dgriffin65 0:77e050d1fb12 328 while(1) {
dgriffin65 1:2dee44ea52a9 329 //if (t.read_ms() > w5500_ACCEPT_TIMEOUT) {
dgriffin65 1:2dee44ea52a9 330 // printf("W5500Interface::socket_accept, timed out\r\n");
dgriffin65 1:2dee44ea52a9 331 // return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 1:2dee44ea52a9 332 //}
dgriffin65 1:2dee44ea52a9 333
dgriffin65 1:2dee44ea52a9 334 nsapi_error_t err = WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR);
dgriffin65 1:2dee44ea52a9 335
dgriffin65 1:2dee44ea52a9 336 if (err == SOCK_ESTABLISHED) {
dgriffin65 0:77e050d1fb12 337 break;
dgriffin65 0:77e050d1fb12 338 }
dgriffin65 0:77e050d1fb12 339 }
dgriffin65 0:77e050d1fb12 340
dgriffin65 1:2dee44ea52a9 341 //get socket for the connection
dgriffin65 1:2dee44ea52a9 342 *handle = get_sock(SKT(server)->fd);
dgriffin65 1:2dee44ea52a9 343
dgriffin65 1:2dee44ea52a9 344 if (!(*handle)) {
dgriffin65 1:2dee44ea52a9 345 error("No more socketa for binding");
dgriffin65 1:2dee44ea52a9 346 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 1:2dee44ea52a9 347 }
dgriffin65 1:2dee44ea52a9 348
dgriffin65 0:77e050d1fb12 349 //give it all of the socket info from the server
dgriffin65 0:77e050d1fb12 350 SKT(*handle)->proto = SKT(server)->proto;
dgriffin65 0:77e050d1fb12 351 SKT(*handle)->connected = true;
dgriffin65 1:2dee44ea52a9 352
dgriffin65 0:77e050d1fb12 353 //create a new tcp socket for the server
dgriffin65 0:77e050d1fb12 354 SKT(server)->fd = WIZnet_Chip::new_socket();
dgriffin65 0:77e050d1fb12 355 if (SKT(server)->fd < 0) {
dgriffin65 0:77e050d1fb12 356 error("Unable to open a new socket");
dgriffin65 0:77e050d1fb12 357 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 358 }
dgriffin65 0:77e050d1fb12 359
dgriffin65 0:77e050d1fb12 360 SKT(server)->proto = NSAPI_TCP;
dgriffin65 0:77e050d1fb12 361 SKT(server)->connected = false;
dgriffin65 0:77e050d1fb12 362
dgriffin65 0:77e050d1fb12 363 SocketAddress _addr;
dgriffin65 0:77e050d1fb12 364 _addr.set_port(listen_port);
dgriffin65 0:77e050d1fb12 365
dgriffin65 0:77e050d1fb12 366 // and then, for the next connection, server socket should be assigned new one.
dgriffin65 0:77e050d1fb12 367 if (socket_bind(server, _addr) < 0) {
sgnezdov 4:80e302a610fd 368 error("No more sockets for binding");
dgriffin65 0:77e050d1fb12 369 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 370 }
dgriffin65 0:77e050d1fb12 371
dgriffin65 0:77e050d1fb12 372 if (socket_listen(server, 1) < 0) {
dgriffin65 1:2dee44ea52a9 373 error("No more sockets for listening");
dgriffin65 0:77e050d1fb12 374 }
dgriffin65 0:77e050d1fb12 375
dgriffin65 0:77e050d1fb12 376 if (address) {
dgriffin65 0:77e050d1fb12 377 uint32_t ip = WIZnet_Chip::sreg<uint32_t>(SKT(*handle)->fd, Sn_DIPR);
dgriffin65 0:77e050d1fb12 378 char host[17];
dgriffin65 0:77e050d1fb12 379 snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
dgriffin65 0:77e050d1fb12 380 int port = WIZnet_Chip::sreg<uint16_t>(SKT(*handle)->fd, Sn_DPORT);
dgriffin65 0:77e050d1fb12 381
dgriffin65 0:77e050d1fb12 382 _addr.set_ip_address(host);
dgriffin65 0:77e050d1fb12 383 _addr.set_port(port);
dgriffin65 0:77e050d1fb12 384 *address = _addr;
dgriffin65 0:77e050d1fb12 385 }
dgriffin65 0:77e050d1fb12 386
dgriffin65 0:77e050d1fb12 387 return 0;
dgriffin65 0:77e050d1fb12 388 }
dgriffin65 0:77e050d1fb12 389
dgriffin65 0:77e050d1fb12 390 nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 391 {
sgnezdov 4:80e302a610fd 392 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 393 debug("[socket_send] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 394 #endif
dgriffin65 0:77e050d1fb12 395 int writtenLen = 0;
dgriffin65 0:77e050d1fb12 396 while (writtenLen < size) {
dgriffin65 0:77e050d1fb12 397 int _size = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
dgriffin65 0:77e050d1fb12 398 if (_size < 0) {
dgriffin65 0:77e050d1fb12 399 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 400 }
dgriffin65 0:77e050d1fb12 401 if (_size > (size-writtenLen)) {
dgriffin65 0:77e050d1fb12 402 _size = (size-writtenLen);
dgriffin65 0:77e050d1fb12 403 }
dgriffin65 0:77e050d1fb12 404 int ret = WIZnet_Chip::send(SKT(handle)->fd, (char*)data, (int)_size);
dgriffin65 0:77e050d1fb12 405 if (ret < 0) {
sgnezdov 4:80e302a610fd 406 debug("[socket_send] returned error -1\n");
dgriffin65 0:77e050d1fb12 407 return -1;
dgriffin65 0:77e050d1fb12 408 }
dgriffin65 0:77e050d1fb12 409 writtenLen += ret;
dgriffin65 0:77e050d1fb12 410 }
dgriffin65 0:77e050d1fb12 411 return writtenLen;
dgriffin65 0:77e050d1fb12 412 }
dgriffin65 0:77e050d1fb12 413
dgriffin65 0:77e050d1fb12 414 nsapi_size_or_error_t W5500Interface::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 415 {
sgnezdov 4:80e302a610fd 416 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 417 debug("[socket_recv] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 418 #endif
dgriffin65 0:77e050d1fb12 419 // add to cover exception.
dgriffin65 0:77e050d1fb12 420 if ((SKT(handle)->fd < 0) || !SKT(handle)->connected) {
dgriffin65 0:77e050d1fb12 421 return -1;
dgriffin65 0:77e050d1fb12 422 }
dgriffin65 0:77e050d1fb12 423
dgriffin65 0:77e050d1fb12 424 int _size = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
dgriffin65 0:77e050d1fb12 425
dgriffin65 0:77e050d1fb12 426 if (_size < 0) {
dgriffin65 0:77e050d1fb12 427 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 428 }
dgriffin65 0:77e050d1fb12 429
dgriffin65 0:77e050d1fb12 430 if (_size > size) {
dgriffin65 0:77e050d1fb12 431 _size = size;
dgriffin65 0:77e050d1fb12 432 }
dgriffin65 0:77e050d1fb12 433 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)data, (int)_size);
dgriffin65 0:77e050d1fb12 434 }
dgriffin65 0:77e050d1fb12 435
dgriffin65 0:77e050d1fb12 436 nsapi_size_or_error_t W5500Interface::socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
dgriffin65 0:77e050d1fb12 437 const void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 438 {
sgnezdov 4:80e302a610fd 439 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 440 debug("[socket_sendto] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 441 #endif
sgnezdov 4:80e302a610fd 442 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 443 debug("[socket_sendto] to ip: %s:%d\n", address.get_ip_address(), address.get_port());
sgnezdov 4:80e302a610fd 444 #endif
sgnezdov 4:80e302a610fd 445 if (WIZnet_Chip::is_closed(SKT(handle)->fd)) {
sgnezdov 4:80e302a610fd 446 nsapi_error_t err = socket_bind(handle, address);
sgnezdov 4:80e302a610fd 447 if (err < 0) {
sgnezdov 4:80e302a610fd 448 debug("[socket_sendto] failed to bind socket: %d\n", err);
sgnezdov 4:80e302a610fd 449 return err;
sgnezdov 4:80e302a610fd 450 }
sgnezdov 4:80e302a610fd 451 }
sgnezdov 3:61ff27ed8355 452 //compare with original: int size = eth->wait_writeable(_sock_fd, _blocking ? -1 : _timeout, length-1);
sgnezdov 3:61ff27ed8355 453 int len = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, size-1);
dgriffin65 0:77e050d1fb12 454 if (len < 0) {
sgnezdov 4:80e302a610fd 455 debug("[socket_sendto] error: NSAPI_ERROR_WOULD_BLOCK\n");
dgriffin65 0:77e050d1fb12 456 return NSAPI_ERROR_WOULD_BLOCK;;
dgriffin65 0:77e050d1fb12 457 }
dgriffin65 0:77e050d1fb12 458
dgriffin65 0:77e050d1fb12 459 // set remote host
dgriffin65 0:77e050d1fb12 460 WIZnet_Chip::sreg_ip(SKT(handle)->fd, Sn_DIPR, address.get_ip_address());
dgriffin65 0:77e050d1fb12 461 // set remote port
dgriffin65 0:77e050d1fb12 462 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_DPORT, address.get_port());
sgnezdov 3:61ff27ed8355 463
sgnezdov 4:80e302a610fd 464 nsapi_size_or_error_t err = WIZnet_Chip::send(SKT(handle)->fd, (const char*)data, size);
sgnezdov 4:80e302a610fd 465 debug("[socket_sendto] rv: %d, size: %d\n", err, size);
sgnezdov 4:80e302a610fd 466 if (err > 0) {
sgnezdov 4:80e302a610fd 467 debug("[socket_sendto] data: ");
sgnezdov 4:80e302a610fd 468 for(int i = 0; i < err; i++) {
sgnezdov 4:80e302a610fd 469 if ((i%16) == 0) {
sgnezdov 4:80e302a610fd 470 debug("\n");
sgnezdov 4:80e302a610fd 471 }
sgnezdov 4:80e302a610fd 472 uint8_t* buf = (uint8_t*)data;
sgnezdov 4:80e302a610fd 473 debug(" %02x", buf[i]);
sgnezdov 4:80e302a610fd 474 }
sgnezdov 4:80e302a610fd 475 if ((err-1%16) != 0) {
sgnezdov 4:80e302a610fd 476 debug("\n");
sgnezdov 4:80e302a610fd 477 }
sgnezdov 4:80e302a610fd 478 }
sgnezdov 4:80e302a610fd 479 return err;
dgriffin65 0:77e050d1fb12 480 }
dgriffin65 0:77e050d1fb12 481
dgriffin65 0:77e050d1fb12 482 nsapi_size_or_error_t W5500Interface::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
dgriffin65 0:77e050d1fb12 483 void *buffer, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 484 {
sgnezdov 4:80e302a610fd 485 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 486 debug("[socket_recvfrom] fd: %d\n", SKT(handle)->fd);
sgnezdov 4:80e302a610fd 487 #endif
dgriffin65 0:77e050d1fb12 488 //check for null pointers
sgnezdov 4:80e302a610fd 489 if (buffer == NULL) {
sgnezdov 4:80e302a610fd 490 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 491 debug("[socket_recvfrom] buffer is NULL; receive is ABORTED\n");
sgnezdov 4:80e302a610fd 492 #endif
sgnezdov 4:80e302a610fd 493 return -1;
sgnezdov 4:80e302a610fd 494 }
sgnezdov 4:80e302a610fd 495
dgriffin65 0:77e050d1fb12 496 uint8_t info[8];
dgriffin65 0:77e050d1fb12 497 int len = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, sizeof(info));
dgriffin65 0:77e050d1fb12 498 if (len < 0) {
sgnezdov 4:80e302a610fd 499 debug("[socket_recvfrom] error: NSAPI_ERROR_WOULD_BLOCK\n");
dgriffin65 0:77e050d1fb12 500 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 501 }
dgriffin65 0:77e050d1fb12 502
dgriffin65 0:77e050d1fb12 503 //receive endpoint information
dgriffin65 0:77e050d1fb12 504 WIZnet_Chip::recv(SKT(handle)->fd, (char*)info, sizeof(info));
dgriffin65 0:77e050d1fb12 505
dgriffin65 0:77e050d1fb12 506 char addr[17];
dgriffin65 0:77e050d1fb12 507 snprintf(addr, sizeof(addr), "%d.%d.%d.%d", info[0], info[1], info[2], info[3]);
dgriffin65 0:77e050d1fb12 508 uint16_t port = info[4]<<8|info[5];
sgnezdov 4:80e302a610fd 509 // original behavior was to terminate execution if address is NULL
sgnezdov 4:80e302a610fd 510 if (address != NULL) {
sgnezdov 4:80e302a610fd 511 //debug("[socket_recvfrom] warn: addressis NULL");
sgnezdov 4:80e302a610fd 512 address->set_ip_address(addr);
sgnezdov 4:80e302a610fd 513 address->set_port(port);
sgnezdov 4:80e302a610fd 514 }
dgriffin65 0:77e050d1fb12 515
dgriffin65 0:77e050d1fb12 516 int udp_size = info[6]<<8|info[7];
dgriffin65 0:77e050d1fb12 517
dgriffin65 0:77e050d1fb12 518 if (udp_size > (len-sizeof(info))) {
sgnezdov 4:80e302a610fd 519 debug("[socket_recvfrom] error: udp_size > (len-sizeof(info))\n");
dgriffin65 0:77e050d1fb12 520 return -1;
dgriffin65 0:77e050d1fb12 521 }
dgriffin65 0:77e050d1fb12 522
dgriffin65 0:77e050d1fb12 523 //receive from socket
sgnezdov 4:80e302a610fd 524 nsapi_size_or_error_t err = WIZnet_Chip::recv(SKT(handle)->fd, (char*)buffer, udp_size);
sgnezdov 4:80e302a610fd 525 debug("[socket_recvfrom] rv: %d\n", err);
sgnezdov 4:80e302a610fd 526 if (err > 0) {
sgnezdov 4:80e302a610fd 527 debug("[socket_recvfrom] buffer:");
sgnezdov 4:80e302a610fd 528 for(int i = 0; i < err; i++) {
sgnezdov 4:80e302a610fd 529 if ((i%16) == 0) {
sgnezdov 4:80e302a610fd 530 debug("\n");
sgnezdov 4:80e302a610fd 531 }
sgnezdov 4:80e302a610fd 532 uint8_t* buf = (uint8_t*)buffer;
sgnezdov 4:80e302a610fd 533 debug(" %02x", buf[i]);
sgnezdov 4:80e302a610fd 534 }
sgnezdov 4:80e302a610fd 535 if ((err-1%16) != 0) {
sgnezdov 4:80e302a610fd 536 debug("\n");
sgnezdov 4:80e302a610fd 537 }
sgnezdov 4:80e302a610fd 538 }
sgnezdov 4:80e302a610fd 539 return err;
dgriffin65 0:77e050d1fb12 540 }
dgriffin65 0:77e050d1fb12 541
dgriffin65 0:77e050d1fb12 542 void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
dgriffin65 0:77e050d1fb12 543 {
dgriffin65 1:2dee44ea52a9 544 if (handle == NULL) return;
sgnezdov 4:80e302a610fd 545 #ifdef w5500_INTF_DBG
sgnezdov 4:80e302a610fd 546 debug("[socket_attach] fd: %d, callback: %p\n", SKT(handle)->fd, callback);
sgnezdov 4:80e302a610fd 547 #endif
dgriffin65 1:2dee44ea52a9 548 SKT(handle)->callback = callback;
dgriffin65 1:2dee44ea52a9 549 SKT(handle)->callback_data = data;
dgriffin65 0:77e050d1fb12 550 }