W5500 driver for mbed OS 5

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

Fork of W5500Interface by Sergei G

Committer:
Bongjun
Date:
Thu Aug 09 08:10:27 2018 +0000
Revision:
6:e2ab76b2be07
Parent:
5:41393623ead4
Child:
7:1877881f3516
changes for mbed OS 5 web server example; - add internal W5500 instance; - changes for web server example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Bongjun 6:e2ab76b2be07 1
Bongjun 6:e2ab76b2be07 2 /**
Bongjun 6:e2ab76b2be07 3 ******************************************************************************
Bongjun 6:e2ab76b2be07 4 * @file W5500Interface.h
Bongjun 6:e2ab76b2be07 5 * @author Bongjun Hur (modified version from Sergei G (https://os.mbed.com/users/sgnezdov/))
Bongjun 6:e2ab76b2be07 6 * @brief Implementation file of the NetworkStack for the W5500 Device
Bongjun 6:e2ab76b2be07 7 ******************************************************************************
Bongjun 6:e2ab76b2be07 8 * @attention
Bongjun 6:e2ab76b2be07 9 *
Bongjun 6:e2ab76b2be07 10 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
Bongjun 6:e2ab76b2be07 11 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
Bongjun 6:e2ab76b2be07 12 * TIME. AS A RESULT, WIZnet SHALL NOT BE HELD LIABLE FOR ANY
Bongjun 6:e2ab76b2be07 13 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
Bongjun 6:e2ab76b2be07 14 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
Bongjun 6:e2ab76b2be07 15 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
Bongjun 6:e2ab76b2be07 16 *
Bongjun 6:e2ab76b2be07 17 * <h2><center>&copy; COPYRIGHT 2017 WIZnet Co.,Ltd.</center></h2>
Bongjun 6:e2ab76b2be07 18 ******************************************************************************
Bongjun 6:e2ab76b2be07 19 */
Bongjun 6:e2ab76b2be07 20
Bongjun 6:e2ab76b2be07 21 #include "mbed.h"
Bongjun 6:e2ab76b2be07 22 #include "W5500Interface.h"
Bongjun 6:e2ab76b2be07 23
Bongjun 6:e2ab76b2be07 24 static int udp_local_port = 0;
Bongjun 6:e2ab76b2be07 25
Bongjun 6:e2ab76b2be07 26 //DigitalOut led1(LED1);
Bongjun 6:e2ab76b2be07 27
Bongjun 6:e2ab76b2be07 28 #define SKT(h) ((w5500_socket*)h)
Bongjun 6:e2ab76b2be07 29 #define w5500_WAIT_TIMEOUT 1500
Bongjun 6:e2ab76b2be07 30 #define w5500_ACCEPT_TIMEOUT 30000
Bongjun 6:e2ab76b2be07 31
Bongjun 6:e2ab76b2be07 32 #define w5500_INTF_DBG 0
Bongjun 6:e2ab76b2be07 33
Bongjun 6:e2ab76b2be07 34 #if w5500_INTF_DBG
Bongjun 6:e2ab76b2be07 35 #define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0);
Bongjun 6:e2ab76b2be07 36 #else
Bongjun 6:e2ab76b2be07 37 #define DBG(...) while(0);
Bongjun 6:e2ab76b2be07 38 #endif
Bongjun 6:e2ab76b2be07 39
Bongjun 6:e2ab76b2be07 40
Bongjun 6:e2ab76b2be07 41 /* Interface implementation */
Bongjun 6:e2ab76b2be07 42
Bongjun 6:e2ab76b2be07 43 W5500Interface::W5500Interface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset) :
Bongjun 6:e2ab76b2be07 44 _w5500(mosi, miso, sclk, cs, reset)
Bongjun 6:e2ab76b2be07 45 {
Bongjun 6:e2ab76b2be07 46 ip_set = false;
Bongjun 6:e2ab76b2be07 47 }
Bongjun 6:e2ab76b2be07 48
Bongjun 6:e2ab76b2be07 49 W5500Interface::W5500Interface(SPI* spi, PinName cs, PinName reset) :
Bongjun 6:e2ab76b2be07 50 _w5500(spi, cs, reset)
Bongjun 6:e2ab76b2be07 51 {
Bongjun 6:e2ab76b2be07 52 ip_set = false;
Bongjun 6:e2ab76b2be07 53 }
Bongjun 6:e2ab76b2be07 54
Bongjun 6:e2ab76b2be07 55 w5500_socket* W5500Interface::get_sock(int fd)
Bongjun 6:e2ab76b2be07 56 {
Bongjun 6:e2ab76b2be07 57 for (int i=0; i<MAX_SOCK_NUM ; i++) {
Bongjun 6:e2ab76b2be07 58 if (w5500_sockets[i].fd == -1) {
Bongjun 6:e2ab76b2be07 59 w5500_sockets[i].fd = fd;
Bongjun 6:e2ab76b2be07 60 w5500_sockets[i].proto = NSAPI_TCP;
Bongjun 6:e2ab76b2be07 61 w5500_sockets[i].connected = false;
Bongjun 6:e2ab76b2be07 62 w5500_sockets[i].callback = NULL;
Bongjun 6:e2ab76b2be07 63 w5500_sockets[i].callback_data = NULL;
Bongjun 6:e2ab76b2be07 64 return &w5500_sockets[i];
Bongjun 6:e2ab76b2be07 65 }
Bongjun 6:e2ab76b2be07 66 }
Bongjun 6:e2ab76b2be07 67 return NULL;
Bongjun 6:e2ab76b2be07 68 }
Bongjun 6:e2ab76b2be07 69
Bongjun 6:e2ab76b2be07 70 void W5500Interface::init_socks()
Bongjun 6:e2ab76b2be07 71 {
Bongjun 6:e2ab76b2be07 72 for (int i=0; i<MAX_SOCK_NUM ; i++) {
Bongjun 6:e2ab76b2be07 73 w5500_sockets[i].fd = -1;
Bongjun 6:e2ab76b2be07 74 w5500_sockets[i].proto = NSAPI_TCP;
Bongjun 6:e2ab76b2be07 75 w5500_sockets[i].connected = false;
Bongjun 6:e2ab76b2be07 76 w5500_sockets[i].callback = NULL;
Bongjun 6:e2ab76b2be07 77 w5500_sockets[i].callback_data = NULL;
Bongjun 6:e2ab76b2be07 78 }
Bongjun 6:e2ab76b2be07 79
Bongjun 6:e2ab76b2be07 80 //initialize the socket isr
Bongjun 6:e2ab76b2be07 81 //_daemon = new Thread(osPriorityNormal, 1024);
Bongjun 6:e2ab76b2be07 82 //_daemon->start(callback(this, &W5500Interface::daemon));
Bongjun 6:e2ab76b2be07 83 }
Bongjun 6:e2ab76b2be07 84
Bongjun 6:e2ab76b2be07 85 int W5500Interface::init()
Bongjun 6:e2ab76b2be07 86 {
Bongjun 6:e2ab76b2be07 87 _w5500.reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
Bongjun 6:e2ab76b2be07 88 //_w5500.reg_wr<uint8_t>(SIMR, 0xFF); //
Bongjun 6:e2ab76b2be07 89 _w5500.reset();
Bongjun 6:e2ab76b2be07 90 init_socks();
Bongjun 6:e2ab76b2be07 91 return 0;
Bongjun 6:e2ab76b2be07 92 }
Bongjun 6:e2ab76b2be07 93
Bongjun 6:e2ab76b2be07 94 int W5500Interface::init(uint8_t * mac)
Bongjun 6:e2ab76b2be07 95 {
Bongjun 6:e2ab76b2be07 96 _w5500.reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
Bongjun 6:e2ab76b2be07 97 for (int i =0; i < 6; i++) _w5500.mac[i] = mac[i];
Bongjun 6:e2ab76b2be07 98 _w5500.setmac();
Bongjun 6:e2ab76b2be07 99 _w5500.reset(); // sets buffers; does not alter MAC
Bongjun 6:e2ab76b2be07 100 init_socks();
Bongjun 6:e2ab76b2be07 101 return 0;
Bongjun 6:e2ab76b2be07 102 }
Bongjun 6:e2ab76b2be07 103
Bongjun 6:e2ab76b2be07 104 // add this function, because sometimes no needed MAC address in init calling.
Bongjun 6:e2ab76b2be07 105 int W5500Interface::init(const char* ip, const char* mask, const char* gateway)
Bongjun 6:e2ab76b2be07 106 {
Bongjun 6:e2ab76b2be07 107 _w5500.ip = str_to_ip(ip);
Bongjun 6:e2ab76b2be07 108 strcpy(ip_string, ip);
Bongjun 6:e2ab76b2be07 109 ip_set = true;
Bongjun 6:e2ab76b2be07 110 _w5500.netmask = str_to_ip(mask);
Bongjun 6:e2ab76b2be07 111 _w5500.gateway = str_to_ip(gateway);
Bongjun 6:e2ab76b2be07 112 _w5500.reset();
Bongjun 6:e2ab76b2be07 113
Bongjun 6:e2ab76b2be07 114 // @Jul. 8. 2014 add code. should be called to write chip.
Bongjun 6:e2ab76b2be07 115 _w5500.setip();
Bongjun 6:e2ab76b2be07 116 init_socks();
Bongjun 6:e2ab76b2be07 117
Bongjun 6:e2ab76b2be07 118 return 0;
Bongjun 6:e2ab76b2be07 119 }
Bongjun 6:e2ab76b2be07 120
Bongjun 6:e2ab76b2be07 121 int W5500Interface::init(uint8_t * mac, const char* ip, const char* mask, const char* gateway)
Bongjun 6:e2ab76b2be07 122 {
Bongjun 6:e2ab76b2be07 123 //
Bongjun 6:e2ab76b2be07 124 for (int i =0; i < 6; i++) _w5500.mac[i] = mac[i];
Bongjun 6:e2ab76b2be07 125 //
Bongjun 6:e2ab76b2be07 126 _w5500.ip = str_to_ip(ip);
Bongjun 6:e2ab76b2be07 127 strcpy(ip_string, ip);
Bongjun 6:e2ab76b2be07 128 ip_set = true;
Bongjun 6:e2ab76b2be07 129 _w5500.netmask = str_to_ip(mask);
Bongjun 6:e2ab76b2be07 130 _w5500.gateway = str_to_ip(gateway);
Bongjun 6:e2ab76b2be07 131 _w5500.reset();
Bongjun 6:e2ab76b2be07 132
Bongjun 6:e2ab76b2be07 133 // @Jul. 8. 2014 add code. should be called to write chip.
Bongjun 6:e2ab76b2be07 134 _w5500.setmac();
Bongjun 6:e2ab76b2be07 135 _w5500.setip();
Bongjun 6:e2ab76b2be07 136 init_socks();
Bongjun 6:e2ab76b2be07 137
Bongjun 6:e2ab76b2be07 138 return 0;
Bongjun 6:e2ab76b2be07 139 }
Bongjun 6:e2ab76b2be07 140
Bongjun 6:e2ab76b2be07 141 /*
Bongjun 6:e2ab76b2be07 142 void W5500Interface::daemon () {
Bongjun 6:e2ab76b2be07 143 for (;;) {
Bongjun 6:e2ab76b2be07 144 for (int i=0; i<MAX_SOCK_NUM ; i++) {
Bongjun 6:e2ab76b2be07 145 if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) {
Bongjun 6:e2ab76b2be07 146 int size = _w5500.sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR);
Bongjun 6:e2ab76b2be07 147 if (size > 0) {
Bongjun 6:e2ab76b2be07 148 led1 = !led1;
Bongjun 6:e2ab76b2be07 149 w5500_sockets[i].callback(w5500_sockets[i].callback_data);
Bongjun 6:e2ab76b2be07 150 }
Bongjun 6:e2ab76b2be07 151 }
Bongjun 6:e2ab76b2be07 152 }
Bongjun 6:e2ab76b2be07 153 wait(0.2);
Bongjun 6:e2ab76b2be07 154 }
Bongjun 6:e2ab76b2be07 155 }
Bongjun 6:e2ab76b2be07 156 */
Bongjun 6:e2ab76b2be07 157
Bongjun 6:e2ab76b2be07 158 int W5500Interface::connect()
Bongjun 6:e2ab76b2be07 159 {
Bongjun 6:e2ab76b2be07 160 /////////////////////////////
Bongjun 6:e2ab76b2be07 161 // DHCP를 여기에 추가하도록....
Bongjun 6:e2ab76b2be07 162 // 그리고 바로 register 에 접근하는 것을 없애야..
Bongjun 6:e2ab76b2be07 163 // ㅉ5500 인스턴스 하나 만들어서 사용해야함..
Bongjun 6:e2ab76b2be07 164 //일부러 에러 나오게 이렇게 적어두자....
Bongjun 6:e2ab76b2be07 165 if (_w5500.setip() == false) return NSAPI_ERROR_DHCP_FAILURE;
Bongjun 6:e2ab76b2be07 166 return 0;
Bongjun 6:e2ab76b2be07 167 }
Bongjun 6:e2ab76b2be07 168
Bongjun 6:e2ab76b2be07 169 int W5500Interface::disconnect()
Bongjun 6:e2ab76b2be07 170 {
Bongjun 6:e2ab76b2be07 171 _w5500.disconnect();
Bongjun 6:e2ab76b2be07 172 return 0;
Bongjun 6:e2ab76b2be07 173 }
Bongjun 6:e2ab76b2be07 174
Bongjun 6:e2ab76b2be07 175 const char *W5500Interface::get_ip_address()
Bongjun 6:e2ab76b2be07 176 {
Bongjun 6:e2ab76b2be07 177 uint32_t ip = _w5500.reg_rd<uint32_t>(SIPR);
Bongjun 6:e2ab76b2be07 178 snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
Bongjun 6:e2ab76b2be07 179 return ip_string;
Bongjun 6:e2ab76b2be07 180 }
Bongjun 6:e2ab76b2be07 181
Bongjun 6:e2ab76b2be07 182 const char *W5500Interface::get_mac_address()
Bongjun 6:e2ab76b2be07 183 {
Bongjun 6:e2ab76b2be07 184 uint8_t mac[6];
Bongjun 6:e2ab76b2be07 185 _w5500.reg_rd_mac(SHAR, mac);
Bongjun 6:e2ab76b2be07 186 snprintf(mac_string, sizeof(mac_string), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Bongjun 6:e2ab76b2be07 187 return mac_string;
Bongjun 6:e2ab76b2be07 188 }
Bongjun 6:e2ab76b2be07 189
Bongjun 6:e2ab76b2be07 190 void W5500Interface::get_mac(uint8_t mac[6])
Bongjun 6:e2ab76b2be07 191 {
Bongjun 6:e2ab76b2be07 192 _w5500.reg_rd_mac(SHAR, mac);
Bongjun 6:e2ab76b2be07 193 }
Bongjun 6:e2ab76b2be07 194
Bongjun 6:e2ab76b2be07 195 nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
Bongjun 6:e2ab76b2be07 196 {
Bongjun 6:e2ab76b2be07 197 //a socket is created the same way regardless of the protocol
Bongjun 6:e2ab76b2be07 198 int sock_fd = _w5500.new_socket();
Bongjun 6:e2ab76b2be07 199 if (sock_fd < 0) {
Bongjun 6:e2ab76b2be07 200 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 201 }
Bongjun 6:e2ab76b2be07 202
Bongjun 6:e2ab76b2be07 203 w5500_socket *h = get_sock(sock_fd);
Bongjun 6:e2ab76b2be07 204
Bongjun 6:e2ab76b2be07 205 if (!h) {
Bongjun 6:e2ab76b2be07 206 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 207 }
Bongjun 6:e2ab76b2be07 208
Bongjun 6:e2ab76b2be07 209 h->proto = proto;
Bongjun 6:e2ab76b2be07 210 h->connected = false;
Bongjun 6:e2ab76b2be07 211 h->callback = NULL;
Bongjun 6:e2ab76b2be07 212 h->callback_data = NULL;
Bongjun 6:e2ab76b2be07 213
Bongjun 6:e2ab76b2be07 214 //new up an int to store the socket fd
Bongjun 6:e2ab76b2be07 215 *handle = h;
Bongjun 6:e2ab76b2be07 216 DBG("fd: %d\n", sock_fd);
Bongjun 6:e2ab76b2be07 217 return 0;
Bongjun 6:e2ab76b2be07 218 }
Bongjun 6:e2ab76b2be07 219
Bongjun 6:e2ab76b2be07 220 /*
Bongjun 6:e2ab76b2be07 221 void W5500Interface::signal_event(nsapi_socket_t handle)
Bongjun 6:e2ab76b2be07 222 {
Bongjun 6:e2ab76b2be07 223 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 224 if (SKT(handle)->callback != NULL) {
Bongjun 6:e2ab76b2be07 225 SKT(handle)->callback(SKT(handle)->callback_data);
Bongjun 6:e2ab76b2be07 226 }
Bongjun 6:e2ab76b2be07 227 }
Bongjun 6:e2ab76b2be07 228 */
Bongjun 6:e2ab76b2be07 229
Bongjun 6:e2ab76b2be07 230 nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle)
Bongjun 6:e2ab76b2be07 231 {
Bongjun 6:e2ab76b2be07 232 if (handle == NULL) return 0;
Bongjun 6:e2ab76b2be07 233 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 234 _w5500.close(SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 235
Bongjun 6:e2ab76b2be07 236 SKT(handle)->fd = -1;
Bongjun 6:e2ab76b2be07 237
Bongjun 6:e2ab76b2be07 238 return 0;
Bongjun 6:e2ab76b2be07 239 }
Bongjun 6:e2ab76b2be07 240
Bongjun 6:e2ab76b2be07 241 nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address)
Bongjun 6:e2ab76b2be07 242 {
Bongjun 6:e2ab76b2be07 243 if (handle < 0) {
Bongjun 6:e2ab76b2be07 244 return NSAPI_ERROR_DEVICE_ERROR;
Bongjun 6:e2ab76b2be07 245 }
Bongjun 6:e2ab76b2be07 246 DBG("fd: %d, port: %d\n", SKT(handle)->fd, address.get_port());
Bongjun 6:e2ab76b2be07 247
Bongjun 6:e2ab76b2be07 248 switch (SKT(handle)->proto) {
Bongjun 6:e2ab76b2be07 249 case NSAPI_UDP:
Bongjun 6:e2ab76b2be07 250 // set local port
Bongjun 6:e2ab76b2be07 251 if (address.get_port() != 0) {
Bongjun 6:e2ab76b2be07 252 _w5500.setLocalPort( SKT(handle)->fd, address.get_port() );
Bongjun 6:e2ab76b2be07 253 } else {
Bongjun 6:e2ab76b2be07 254 udp_local_port++;
Bongjun 6:e2ab76b2be07 255 _w5500.setLocalPort( SKT(handle)->fd, udp_local_port );
Bongjun 6:e2ab76b2be07 256 }
Bongjun 6:e2ab76b2be07 257 // set udp protocol
Bongjun 6:e2ab76b2be07 258 _w5500.setProtocol(SKT(handle)->fd, UDP);
Bongjun 6:e2ab76b2be07 259 _w5500.scmd(SKT(handle)->fd, OPEN);
Bongjun 6:e2ab76b2be07 260 /*
Bongjun 6:e2ab76b2be07 261 uint8_t tmpSn_SR;
Bongjun 6:e2ab76b2be07 262 tmpSn_SR = _w5500.sreg<uint8_t>(SKT(handle)->fd, Sn_SR);
Bongjun 6:e2ab76b2be07 263 DBG("open socket status: %2x\n", tmpSn_SR);
Bongjun 6:e2ab76b2be07 264 */
Bongjun 6:e2ab76b2be07 265 return 0;
Bongjun 6:e2ab76b2be07 266 case NSAPI_TCP:
Bongjun 6:e2ab76b2be07 267 listen_port = address.get_port();
Bongjun 6:e2ab76b2be07 268 // set TCP protocol
Bongjun 6:e2ab76b2be07 269 _w5500.setProtocol(SKT(handle)->fd, TCP);
Bongjun 6:e2ab76b2be07 270 // set local port
Bongjun 6:e2ab76b2be07 271 _w5500.setLocalPort( SKT(handle)->fd, address.get_port() );
Bongjun 6:e2ab76b2be07 272 // connect the network
Bongjun 6:e2ab76b2be07 273 _w5500.scmd(SKT(handle)->fd, OPEN);
Bongjun 6:e2ab76b2be07 274 return 0;
Bongjun 6:e2ab76b2be07 275 }
Bongjun 6:e2ab76b2be07 276
Bongjun 6:e2ab76b2be07 277 return NSAPI_ERROR_DEVICE_ERROR;
Bongjun 6:e2ab76b2be07 278 }
Bongjun 6:e2ab76b2be07 279
Bongjun 6:e2ab76b2be07 280 nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog)
Bongjun 6:e2ab76b2be07 281 {
Bongjun 6:e2ab76b2be07 282 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 283 if (SKT(handle)->fd < 0) {
Bongjun 6:e2ab76b2be07 284 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 285 }
Bongjun 6:e2ab76b2be07 286 /* if (backlog != 1) {
Bongjun 6:e2ab76b2be07 287 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 288 }
Bongjun 6:e2ab76b2be07 289 */
Bongjun 6:e2ab76b2be07 290 _w5500.scmd(SKT(handle)->fd, LISTEN);
Bongjun 6:e2ab76b2be07 291 return 0;
Bongjun 6:e2ab76b2be07 292 }
Bongjun 6:e2ab76b2be07 293
Bongjun 6:e2ab76b2be07 294 nsapi_size_or_error_t W5500Interface::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
Bongjun 6:e2ab76b2be07 295 {
Bongjun 6:e2ab76b2be07 296 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 297 //check for a valid socket
Bongjun 6:e2ab76b2be07 298 if (SKT(handle)->fd < 0) {
Bongjun 6:e2ab76b2be07 299 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 300 }
Bongjun 6:e2ab76b2be07 301
Bongjun 6:e2ab76b2be07 302 //before we attempt to connect, we are not connected
Bongjun 6:e2ab76b2be07 303 SKT(handle)->connected = false;
Bongjun 6:e2ab76b2be07 304
Bongjun 6:e2ab76b2be07 305 //try to connect
Bongjun 6:e2ab76b2be07 306 if (!_w5500.connect(SKT(handle)->fd, address.get_ip_address(), address.get_port(), 0)) {
Bongjun 6:e2ab76b2be07 307 return -1;
Bongjun 6:e2ab76b2be07 308 }
Bongjun 6:e2ab76b2be07 309
Bongjun 6:e2ab76b2be07 310 //we are now connected
Bongjun 6:e2ab76b2be07 311 SKT(handle)->connected = true;
Bongjun 6:e2ab76b2be07 312
Bongjun 6:e2ab76b2be07 313 return 0;
Bongjun 6:e2ab76b2be07 314 }
Bongjun 6:e2ab76b2be07 315
Bongjun 6:e2ab76b2be07 316 nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
Bongjun 6:e2ab76b2be07 317 {
Bongjun 6:e2ab76b2be07 318 SocketAddress _addr;
Bongjun 6:e2ab76b2be07 319
Bongjun 6:e2ab76b2be07 320 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 321 if (SKT(server)->fd < 0) {
Bongjun 6:e2ab76b2be07 322 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 323 }
Bongjun 6:e2ab76b2be07 324
Bongjun 6:e2ab76b2be07 325 SKT(server)->connected = false;
Bongjun 6:e2ab76b2be07 326
Bongjun 6:e2ab76b2be07 327 Timer t;
Bongjun 6:e2ab76b2be07 328 t.reset();
Bongjun 6:e2ab76b2be07 329 t.start();
Bongjun 6:e2ab76b2be07 330
Bongjun 6:e2ab76b2be07 331 while(1) {
Bongjun 6:e2ab76b2be07 332 if (t.read_ms() > w5500_ACCEPT_TIMEOUT) {
Bongjun 6:e2ab76b2be07 333 printf("W5500Interface::socket_accept, timed out\r\n");
Bongjun 6:e2ab76b2be07 334 return NSAPI_ERROR_WOULD_BLOCK;
Bongjun 6:e2ab76b2be07 335 }
Bongjun 6:e2ab76b2be07 336 if (_w5500.is_connected(SKT(server)->fd)) break;
Bongjun 6:e2ab76b2be07 337 }
Bongjun 6:e2ab76b2be07 338
Bongjun 6:e2ab76b2be07 339 //get socket for the connection
Bongjun 6:e2ab76b2be07 340 *handle = get_sock(SKT(server)->fd);
Bongjun 6:e2ab76b2be07 341
Bongjun 6:e2ab76b2be07 342 if (!(*handle)) {
Bongjun 6:e2ab76b2be07 343 error("No more sockets for binding");
Bongjun 6:e2ab76b2be07 344 return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 345 }
Bongjun 6:e2ab76b2be07 346
Bongjun 6:e2ab76b2be07 347 //give it all of the socket info from the server
Bongjun 6:e2ab76b2be07 348 SKT(*handle)->proto = SKT(server)->proto;
Bongjun 6:e2ab76b2be07 349 SKT(*handle)->connected = true;
Bongjun 6:e2ab76b2be07 350
Bongjun 6:e2ab76b2be07 351 if (address) {
Bongjun 6:e2ab76b2be07 352 uint32_t ip = _w5500.sreg<uint32_t>(SKT(*handle)->fd, Sn_DIPR);
Bongjun 6:e2ab76b2be07 353 char host[17];
Bongjun 6:e2ab76b2be07 354 snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
Bongjun 6:e2ab76b2be07 355 int port = _w5500.sreg<uint16_t>(SKT(*handle)->fd, Sn_DPORT);
Bongjun 6:e2ab76b2be07 356
Bongjun 6:e2ab76b2be07 357 _addr.set_ip_address(host);
Bongjun 6:e2ab76b2be07 358 _addr.set_port(port);
Bongjun 6:e2ab76b2be07 359 *address = _addr;
Bongjun 6:e2ab76b2be07 360 }
Bongjun 6:e2ab76b2be07 361
Bongjun 6:e2ab76b2be07 362
Bongjun 6:e2ab76b2be07 363 //create a new tcp socket for the server
Bongjun 6:e2ab76b2be07 364 SKT(server)->fd = _w5500.new_socket();
Bongjun 6:e2ab76b2be07 365 if (SKT(server)->fd < 0) {
Bongjun 6:e2ab76b2be07 366 error("No more sockets for listening");
Bongjun 6:e2ab76b2be07 367 //return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 368 // already accepted socket, so return 0, but there is no listen socket anymore.
Bongjun 6:e2ab76b2be07 369 return 0;
Bongjun 6:e2ab76b2be07 370 }
Bongjun 6:e2ab76b2be07 371
Bongjun 6:e2ab76b2be07 372 SKT(server)->proto = NSAPI_TCP;
Bongjun 6:e2ab76b2be07 373 SKT(server)->connected = false;
Bongjun 6:e2ab76b2be07 374
Bongjun 6:e2ab76b2be07 375 _addr.set_port(listen_port);
Bongjun 6:e2ab76b2be07 376
Bongjun 6:e2ab76b2be07 377 // and then, for the next connection, server socket should be assigned new one.
Bongjun 6:e2ab76b2be07 378 if (socket_bind(server, _addr) < 0) {
Bongjun 6:e2ab76b2be07 379 error("No more sockets for listening");
Bongjun 6:e2ab76b2be07 380 //return NSAPI_ERROR_NO_SOCKET;
Bongjun 6:e2ab76b2be07 381 // already accepted socket, so return 0, but there is no listen socket anymore.
Bongjun 6:e2ab76b2be07 382 return 0;
Bongjun 6:e2ab76b2be07 383 }
Bongjun 6:e2ab76b2be07 384
Bongjun 6:e2ab76b2be07 385 if (socket_listen(server, 1) < 0) {
Bongjun 6:e2ab76b2be07 386 error("No more sockets for listening");
Bongjun 6:e2ab76b2be07 387 // already accepted socket, so return 0, but there is no listen socket anymore.
Bongjun 6:e2ab76b2be07 388 return 0;
Bongjun 6:e2ab76b2be07 389 }
Bongjun 6:e2ab76b2be07 390
Bongjun 6:e2ab76b2be07 391 return 0;
Bongjun 6:e2ab76b2be07 392 }
Bongjun 6:e2ab76b2be07 393
Bongjun 6:e2ab76b2be07 394 nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size)
Bongjun 6:e2ab76b2be07 395 {
Bongjun 6:e2ab76b2be07 396 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 397 int writtenLen = 0;
Bongjun 6:e2ab76b2be07 398 while (writtenLen < size) {
Bongjun 6:e2ab76b2be07 399 int _size = _w5500.wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
Bongjun 6:e2ab76b2be07 400 if (_size < 0) {
Bongjun 6:e2ab76b2be07 401 return NSAPI_ERROR_WOULD_BLOCK;
Bongjun 6:e2ab76b2be07 402 }
Bongjun 6:e2ab76b2be07 403 if (_size > (size-writtenLen)) {
Bongjun 6:e2ab76b2be07 404 _size = (size-writtenLen);
Bongjun 6:e2ab76b2be07 405 }
Bongjun 6:e2ab76b2be07 406 int ret = _w5500.send(SKT(handle)->fd, (char*)data, (int)_size);
Bongjun 6:e2ab76b2be07 407 if (ret < 0) {
Bongjun 6:e2ab76b2be07 408 DBG("returning error -1\n");
Bongjun 6:e2ab76b2be07 409 return -1;
Bongjun 6:e2ab76b2be07 410 }
Bongjun 6:e2ab76b2be07 411 writtenLen += ret;
Bongjun 6:e2ab76b2be07 412 }
Bongjun 6:e2ab76b2be07 413 return writtenLen;
Bongjun 6:e2ab76b2be07 414 }
Bongjun 6:e2ab76b2be07 415
Bongjun 6:e2ab76b2be07 416 nsapi_size_or_error_t W5500Interface::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)
Bongjun 6:e2ab76b2be07 417 {
Bongjun 6:e2ab76b2be07 418 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 419 // add to cover exception.
Bongjun 6:e2ab76b2be07 420 if ((SKT(handle)->fd < 0) || !SKT(handle)->connected) {
Bongjun 6:e2ab76b2be07 421 return -1;
Bongjun 6:e2ab76b2be07 422 }
Bongjun 6:e2ab76b2be07 423
Bongjun 6:e2ab76b2be07 424 int _size = _w5500.wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
Bongjun 6:e2ab76b2be07 425
Bongjun 6:e2ab76b2be07 426 if (_size < 0) {
Bongjun 6:e2ab76b2be07 427 return NSAPI_ERROR_WOULD_BLOCK;
Bongjun 6:e2ab76b2be07 428 }
Bongjun 6:e2ab76b2be07 429
Bongjun 6:e2ab76b2be07 430 if (_size > size) {
Bongjun 6:e2ab76b2be07 431 _size = size;
Bongjun 6:e2ab76b2be07 432 }
Bongjun 6:e2ab76b2be07 433 return _w5500.recv(SKT(handle)->fd, (char*)data, (int)_size);
Bongjun 6:e2ab76b2be07 434 }
Bongjun 6:e2ab76b2be07 435
Bongjun 6:e2ab76b2be07 436 nsapi_size_or_error_t W5500Interface::socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
Bongjun 6:e2ab76b2be07 437 const void *data, nsapi_size_t size)
Bongjun 6:e2ab76b2be07 438 {
Bongjun 6:e2ab76b2be07 439 DBG("fd: %d, ip: %s:%d\n", SKT(handle)->fd, address.get_ip_address(), address.get_port());
Bongjun 6:e2ab76b2be07 440 if (_w5500.is_closed(SKT(handle)->fd)) {
Bongjun 6:e2ab76b2be07 441 nsapi_error_t err = socket_bind(handle, address);
Bongjun 6:e2ab76b2be07 442 if (err < 0 ) {
Bongjun 6:e2ab76b2be07 443 DBG("failed to bind socket: %d\n", err);
Bongjun 6:e2ab76b2be07 444 return err;
Bongjun 6:e2ab76b2be07 445 }
Bongjun 6:e2ab76b2be07 446 }
Bongjun 6:e2ab76b2be07 447 //compare with original: int size = eth->wait_writeable(_sock_fd, _blocking ? -1 : _timeout, length-1);
Bongjun 6:e2ab76b2be07 448 int len = _w5500.wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, size-1);
Bongjun 6:e2ab76b2be07 449 if (len < 0) {
Bongjun 6:e2ab76b2be07 450 DBG("error: NSAPI_ERROR_WOULD_BLOCK\n");
Bongjun 6:e2ab76b2be07 451 return NSAPI_ERROR_WOULD_BLOCK;;
Bongjun 6:e2ab76b2be07 452 }
Bongjun 6:e2ab76b2be07 453
Bongjun 6:e2ab76b2be07 454 // set remote host
Bongjun 6:e2ab76b2be07 455 _w5500.sreg_ip(SKT(handle)->fd, Sn_DIPR, address.get_ip_address());
Bongjun 6:e2ab76b2be07 456 // set remote port
Bongjun 6:e2ab76b2be07 457 _w5500.sreg<uint16_t>(SKT(handle)->fd, Sn_DPORT, address.get_port());
Bongjun 6:e2ab76b2be07 458
Bongjun 6:e2ab76b2be07 459 nsapi_size_or_error_t err = _w5500.send(SKT(handle)->fd, (const char*)data, size);
Bongjun 6:e2ab76b2be07 460 DBG("rv: %d, size: %d\n", err, size);
Bongjun 6:e2ab76b2be07 461
Bongjun 6:e2ab76b2be07 462 #if w5500_INTF_DBG
Bongjun 6:e2ab76b2be07 463 if (err > 0) {
Bongjun 6:e2ab76b2be07 464 debug("[socket_sendto] data: ");
Bongjun 6:e2ab76b2be07 465 for(int i = 0; i < err; i++) {
Bongjun 6:e2ab76b2be07 466 if ((i%16) == 0) {
Bongjun 6:e2ab76b2be07 467 debug("\n");
Bongjun 6:e2ab76b2be07 468 }
Bongjun 6:e2ab76b2be07 469 debug(" %02x", ((uint8_t*)data)[i]);
Bongjun 6:e2ab76b2be07 470 }
Bongjun 6:e2ab76b2be07 471 if ((err-1%16) != 0) {
Bongjun 6:e2ab76b2be07 472 debug("\n");
Bongjun 6:e2ab76b2be07 473 }
Bongjun 6:e2ab76b2be07 474 }
Bongjun 6:e2ab76b2be07 475 #endif
Bongjun 6:e2ab76b2be07 476 return err;
Bongjun 6:e2ab76b2be07 477 }
Bongjun 6:e2ab76b2be07 478
Bongjun 6:e2ab76b2be07 479 nsapi_size_or_error_t W5500Interface::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
Bongjun 6:e2ab76b2be07 480 void *buffer, nsapi_size_t size)
Bongjun 6:e2ab76b2be07 481 {
Bongjun 6:e2ab76b2be07 482 DBG("fd: %d\n", SKT(handle)->fd);
Bongjun 6:e2ab76b2be07 483 //check for null pointers
Bongjun 6:e2ab76b2be07 484 if (buffer == NULL) {
Bongjun 6:e2ab76b2be07 485 DBG("buffer is NULL; receive is ABORTED\n");
Bongjun 6:e2ab76b2be07 486 return -1;
Bongjun 6:e2ab76b2be07 487 }
Bongjun 6:e2ab76b2be07 488
Bongjun 6:e2ab76b2be07 489 uint8_t info[8];
Bongjun 6:e2ab76b2be07 490 int len = _w5500.wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, sizeof(info));
Bongjun 6:e2ab76b2be07 491 if (len < 0) {
Bongjun 6:e2ab76b2be07 492 DBG("error: NSAPI_ERROR_WOULD_BLOCK\n");
Bongjun 6:e2ab76b2be07 493 return NSAPI_ERROR_WOULD_BLOCK;
Bongjun 6:e2ab76b2be07 494 }
Bongjun 6:e2ab76b2be07 495
Bongjun 6:e2ab76b2be07 496 //receive endpoint information
Bongjun 6:e2ab76b2be07 497 _w5500.recv(SKT(handle)->fd, (char*)info, sizeof(info));
Bongjun 6:e2ab76b2be07 498
Bongjun 6:e2ab76b2be07 499 char addr[17];
Bongjun 6:e2ab76b2be07 500 snprintf(addr, sizeof(addr), "%d.%d.%d.%d", info[0], info[1], info[2], info[3]);
Bongjun 6:e2ab76b2be07 501 uint16_t port = info[4]<<8|info[5];
Bongjun 6:e2ab76b2be07 502 // original behavior was to terminate execution if address is NULL
Bongjun 6:e2ab76b2be07 503 if (address != NULL) {
Bongjun 6:e2ab76b2be07 504 //DBG("[socket_recvfrom] warn: addressis NULL");
Bongjun 6:e2ab76b2be07 505 address->set_ip_address(addr);
Bongjun 6:e2ab76b2be07 506 address->set_port(port);
Bongjun 6:e2ab76b2be07 507 }
Bongjun 6:e2ab76b2be07 508
Bongjun 6:e2ab76b2be07 509 int udp_size = info[6]<<8|info[7];
Bongjun 6:e2ab76b2be07 510
Bongjun 6:e2ab76b2be07 511 if (udp_size > (len-sizeof(info))) {
Bongjun 6:e2ab76b2be07 512 DBG("error: udp_size > (len-sizeof(info))\n");
Bongjun 6:e2ab76b2be07 513 return -1;
Bongjun 6:e2ab76b2be07 514 }
Bongjun 6:e2ab76b2be07 515
Bongjun 6:e2ab76b2be07 516 //receive from socket
Bongjun 6:e2ab76b2be07 517 nsapi_size_or_error_t err = _w5500.recv(SKT(handle)->fd, (char*)buffer, udp_size);
Bongjun 6:e2ab76b2be07 518 DBG("rv: %d\n", err);
Bongjun 6:e2ab76b2be07 519 #if w5500_INTF_DBG
Bongjun 6:e2ab76b2be07 520 if (err > 0) {
Bongjun 6:e2ab76b2be07 521 debug("[socket_recvfrom] buffer:");
Bongjun 6:e2ab76b2be07 522 for(int i = 0; i < err; i++) {
Bongjun 6:e2ab76b2be07 523 if ((i%16) == 0) {
Bongjun 6:e2ab76b2be07 524 debug("\n");
Bongjun 6:e2ab76b2be07 525 }
Bongjun 6:e2ab76b2be07 526 debug(" %02x", ((uint8_t*)buffer)[i]);
Bongjun 6:e2ab76b2be07 527 }
Bongjun 6:e2ab76b2be07 528 if ((err-1%16) != 0) {
Bongjun 6:e2ab76b2be07 529 debug("\n");
Bongjun 6:e2ab76b2be07 530 }
Bongjun 6:e2ab76b2be07 531 }
Bongjun 6:e2ab76b2be07 532 #endif
Bongjun 6:e2ab76b2be07 533 return err;
Bongjun 6:e2ab76b2be07 534 }
Bongjun 6:e2ab76b2be07 535
Bongjun 6:e2ab76b2be07 536 void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
Bongjun 6:e2ab76b2be07 537 {
Bongjun 6:e2ab76b2be07 538 /*
Bongjun 6:e2ab76b2be07 539 if (handle == NULL) return;
Bongjun 6:e2ab76b2be07 540 DBG("fd: %d, callback: %p\n", SKT(handle)->fd, callback);
Bongjun 6:e2ab76b2be07 541 SKT(handle)->callback = callback;
Bongjun 6:e2ab76b2be07 542 SKT(handle)->callback_data = data;
Bongjun 6:e2ab76b2be07 543 */
Bongjun 6:e2ab76b2be07 544 if (handle == NULL) return;
Bongjun 6:e2ab76b2be07 545 w5500_socket *socket = (w5500_socket *)handle;
Bongjun 6:e2ab76b2be07 546 w5500_sockets[socket->fd].callback = callback;
Bongjun 6:e2ab76b2be07 547 w5500_sockets[socket->fd].callback_data = data;
Bongjun 6:e2ab76b2be07 548 }
Bongjun 6:e2ab76b2be07 549
Bongjun 6:e2ab76b2be07 550 /*
Bongjun 6:e2ab76b2be07 551 void W5500Interface::event()
Bongjun 6:e2ab76b2be07 552 {
Bongjun 6:e2ab76b2be07 553 for(int i=0; i<MAX_SOCK_NUM; i++){
Bongjun 6:e2ab76b2be07 554 if (w5500_sockets[i].callback) {
Bongjun 6:e2ab76b2be07 555 w5500_sockets[i].callback(w5500_sockets[i].data);
Bongjun 6:e2ab76b2be07 556 }
Bongjun 6:e2ab76b2be07 557 }
Bongjun 6:e2ab76b2be07 558 }
Bongjun 6:e2ab76b2be07 559 */