W5200(WIZ820io) network interface

Revision:
1:803123933c5a
Parent:
0:61831b843b44
Child:
2:a8df39b4f3aa
--- a/MyNetTcpSocket.cpp	Sat Apr 14 17:21:11 2012 +0000
+++ b/MyNetTcpSocket.cpp	Tue Apr 17 12:13:15 2012 +0000
@@ -1,9 +1,11 @@
-// MyNetTcpSocket.cpp 2012/4/15
+// MyNetTcpSocket.cpp 2012/4/17
 #include "mbed.h"
 #include "w5100.h"
 #include "MyNetTcpSocket.h"
+#define __DEBUG
+#include "dbg/dbg.h"
 
-#define DEBUG
+//#define DEBUG
 
 #ifdef DEBUG
 #include "Utils.h"
@@ -12,18 +14,44 @@
 #define PRINT_FUNC()
 #endif //DEBUG
 
-MyNetTcpSocket::MyNetTcpSocket() : NetTcpSocket()  {
+int w5200_new_socket() 
+{
+    for(int i = 0; i < MAX_SOCK_NUM; i++) {
+        if (W5100.readSnMR(i) == SnMR::CLOSE) { // 0x00
+            if (W5100.readSnSR(i) != SnSR::LISTEN) { // 0x14
+                return i;
+            }
+        }
+    }
+    return -1; // not found
+}
+
+MyNetTcpSocket::MyNetTcpSocket(int socket) : NetTcpSocket(),_socket(socket),wait_accept(false)  {
     PRINT_FUNC();
-    _socket = 1;
-    W5100.writeSnMR(_socket, SnMR:: TCP); // set TCP mode
+    if (_socket == (-1)) {
+        _socket = w5200_new_socket();
+    }
+#ifdef DEBUG
+    printf("%p socket: %d\n", this, _socket);
+#endif //DEBUG
+    if (_socket != (-1)) {
+        W5100.writeSnMR(_socket, SnMR::TCP); // set TCP mode
+    }
 }
 
 MyNetTcpSocket::~MyNetTcpSocket() {
     PRINT_FUNC();
+    close();
+    if (_socket != (-1)) {
+        W5100.writeSnMR(_socket, SnMR::CLOSE);
+    }
 }
 
 NetTcpSocketErr MyNetTcpSocket::bind(const Host& me) {
     PRINT_FUNC();
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_MEM;
+    }
     int port = me.getPort();
     W5100.writeSnPORT(_socket, port);
     return NETTCPSOCKET_OK;
@@ -31,6 +59,9 @@
 
 NetTcpSocketErr MyNetTcpSocket::listen() {
     PRINT_FUNC();
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_MEM;
+    }
     W5100.execCmdSn(_socket, Sock_OPEN); // set OPEN command
     W5100.execCmdSn(_socket, Sock_LISTEN); // listen
 #ifdef DEBUG
@@ -40,11 +71,15 @@
     W5100.getIPAddress(ip);
     printf("SIPR: %d.%d.%d.%d Sn_PORT:%d\n", ip[0], ip[1], ip[2], ip[3], W5100.readSnPORT(_socket));
 #endif //DEBUG
+    wait_accept = true;
     return NETTCPSOCKET_OK;
 }
 
 NetTcpSocketErr MyNetTcpSocket::connect(const Host& host) {
     PRINT_FUNC();
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_MEM;
+    }
     uint8_t ip[4];
     ip[0] = host.getIp()[0];
     ip[1] = host.getIp()[1];
@@ -71,12 +106,23 @@
 
 NetTcpSocketErr MyNetTcpSocket::accept(Host* pClient, NetTcpSocket** ppNewNetTcpSocket) {
     PRINT_FUNC();
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_MEM;
+    }
     uint8_t ip[4];
     W5100.readSnDIPR(_socket, ip);
     pClient->setIp(IpAddr(ip[0],ip[1],ip[2],ip[3]));
     int port = W5100.readSnDPORT(_socket);
     pClient->setPort(port);
-    
+    Host me;
+    me.setPort(W5100.readSnPORT(_socket));
+    *ppNewNetTcpSocket = new MyNetTcpSocket(_socket);
+    _socket = w5200_new_socket();
+    if (_socket != (-1)) {
+        W5100.writeSnMR(_socket, SnMR::TCP); // set TCP mode
+        bind(me);
+        listen();
+     }
     return NETTCPSOCKET_OK;
 }
 
@@ -86,6 +132,9 @@
     printf("buf:%p, len=%d\n", buf, len);
     printHex((u8*)buf, len);
 #endif //DEBUG
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_MEM;
+    }
     if (len > 0) {
         W5100.send_data_processing(_socket, (uint8_t*)buf, len);
         W5100.execCmdSn(_socket, Sock_SEND);
@@ -95,6 +144,9 @@
 
 int /*if < 0 : NetTcpSocketErr*/ MyNetTcpSocket::recv(char* buf, int len){
     PRINT_FUNC();
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_MEM;
+    }
     int size = W5100.getRXReceivedSize(_socket);
     if (size > len) {
         size = len;
@@ -116,8 +168,10 @@
     }
     m_closed = true;
     cleanUp();
-    W5100.execCmdSn(_socket, Sock_DISCON);
-    W5100.execCmdSn(_socket, Sock_CLOSE);
+    if (_socket != (-1)) {
+        W5100.execCmdSn(_socket, Sock_DISCON);
+        W5100.execCmdSn(_socket, Sock_CLOSE);
+    }
     return NETTCPSOCKET_OK;
 }
 
@@ -125,42 +179,57 @@
     PRINT_FUNC();
     NetTcpSocket::flushEvents();
 #ifdef DEBUG
-    printf("socket:%d SnMR:%02x SnIR:%02x SnSR:%02x\n", _socket, 
-        W5100.readSnMR(_socket), W5100.readSnIR(_socket), W5100.readSnSR(_socket));
-    uint8_t ip[4];
-    W5100.readSnDIPR(_socket, ip);
-    printf("Sn_DIPR: %d.%d.%d.%d Sn_DPORT: %d\n", ip[0], ip[1], ip[2], ip[3], W5100.readSnDPORT(_socket));
-    printf("Sn_RX_RSR:%d, Sn_RX_RD:%d, Sn_RX_WR:%d\n",
+    printf("%p socket:%d\n", this,_socket);
+    if (_socket != (-1)) {
+        printf("SnMR:%02x SnIR:%02x SnSR:%02x\n", 
+            W5100.readSnMR(_socket), W5100.readSnIR(_socket), W5100.readSnSR(_socket));
+        uint8_t ip[4];
+        W5100.readSnDIPR(_socket, ip);
+        printf("Sn_DIPR: %d.%d.%d.%d Sn_DPORT: %d\n", ip[0], ip[1], ip[2], ip[3], W5100.readSnDPORT(_socket));
+        printf("Sn_RX_RSR:%5d, Sn_RX_RD:%5d, Sn_RX_WR:%5d\n",
                 W5100.readSnRX_RSR(_socket), W5100.readSnRX_RD(_socket), W5100.readSnRX_WR(_socket));
-    printf("Sn_TX_FSR:%d, Sn_TX_RD:%d, Sn_TX_WR:%d\n",
+        printf("Sn_TX_FSR:%5d, Sn_TX_RD:%5d, Sn_TX_WR:%5d\n",
                 W5100.readSnTX_FSR(_socket), W5100.readSnTX_RD(_socket), W5100.readSnTX_WR(_socket));
-    wait_ms(500);
+    }
+    wait_ms(200);
 #endif //DEBUG
-    if (W5100.readSnSR(_socket) == 0x1c) {
+    if (_socket == (-1)) {
+        return NETTCPSOCKET_OK;
+    }
+    uint8_t Sn_SR = W5100.readSnSR(_socket);
+    if (wait_accept) {
+        if (Sn_SR == 0x17) {
+            queueEvent(NETTCPSOCKET_ACCEPT);
+            wait_accept = false;
+        }
+    }
+    if (Sn_SR == 0x1c) {
         queueEvent(NETTCPSOCKET_CONRST);
     }
     if (W5100.getRXReceivedSize(_socket) > 0) {
         queueEvent(NETTCPSOCKET_READABLE);
     }
-    if (W5100.readSnSR(_socket) == 0x17) {
+    if (Sn_SR == 0x17) {
         queueEvent(NETTCPSOCKET_CONNECTED);
         if (W5100.getTXFreeSize(_socket) > 0) {
             queueEvent(NETTCPSOCKET_WRITEABLE);
         }
     }
+    if (Sn_SR == 0x00) {
+        queueEvent(NETTCPSOCKET_DISCONNECTED);
+    }
     return NETTCPSOCKET_OK;
 }
 
 void MyNetTcpSocket::cleanUp() //Flush input buffer
 {
     PRINT_FUNC();
-    while(1) {
-        int len = W5100.getRXReceivedSize(_socket);
-        if (len <= 0) {
-            break;
-        }
-        uint8_t temp[8];
-        W5100.recv_data_processing(_socket, temp, sizeof(temp));
+    if (_socket == (-1)) {
+        return;
+    }
+    while(W5100.getRXReceivedSize(_socket) > 0) {
+        uint8_t temp[1];
+        W5100.recv_data_processing(_socket, temp, 1);
         W5100.execCmdSn(_socket, Sock_RECV);
-    }
+    }    
 }