Norimasa Okamoto / WIZ820ioNetIf
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MyNetTcpSocket.cpp Source File

MyNetTcpSocket.cpp

00001 // MyNetTcpSocket.cpp 2013/3/24
00002 #include "mbed.h"
00003 #include "w5200.h"
00004 #include "MyNetTcpSocket.h"
00005 //#define DEBUG
00006 //#define DEBUG_LISTEN
00007 #include "w5200debug.h"
00008 
00009 #define USE_NO_DELAYED_ACK 1
00010 
00011 int w5200_new_socket() 
00012 {
00013     for(int i = 0; i < MAX_SOCK_NUM; i++) {
00014         if (W5200.readSnMR(i) == SnMR::CLOSE) { // 0x00
00015             if (W5200.readSnSR(i) != SnSR::LISTEN) { // 0x14
00016                 return i;
00017             }
00018         }
00019     }
00020     return -1; // not found
00021 }
00022 
00023 MyNetTcpSocket::MyNetTcpSocket(int socket) : NetTcpSocket(),_socket(socket),wait_accept(false)  {
00024     DBG("socket: %d\n", socket);
00025     if (_socket == (-1)) {
00026         _socket = w5200_new_socket();
00027     }
00028     DBG("%p socket: %d\n", this, _socket);
00029     if (_socket != (-1)) {
00030         uint8_t Sn_MR = SnMR::TCP; // set TCP mode
00031 #if USE_NO_DELAYED_ACK 
00032         Sn_MR |= SnMR::ND;
00033 #endif 
00034         W5200.writeSnMR(_socket, Sn_MR);
00035     }
00036 }
00037 
00038 MyNetTcpSocket::~MyNetTcpSocket() {
00039     DBG("socket=%d\n", _socket);
00040     close();
00041     if (_socket != (-1)) {
00042         W5200.writeSnMR(_socket, SnMR::CLOSE);
00043     }
00044 }
00045 
00046 NetTcpSocketErr MyNetTcpSocket::bind(const Host& me) {
00047     if (_socket == (-1)) {
00048         return NETTCPSOCKET_MEM;
00049     }
00050     int port = me.getPort();
00051     W5200.writeSnPORT(_socket, port);
00052     return NETTCPSOCKET_OK;
00053 }
00054 
00055 NetTcpSocketErr MyNetTcpSocket::listen() {
00056     DBG("%p\n", this);
00057     if (_socket == (-1)) {
00058         return NETTCPSOCKET_MEM;
00059     }
00060     W5200.execCmdSn(_socket, Sock_OPEN); // set OPEN command
00061     W5200.execCmdSn(_socket, Sock_LISTEN); // listen
00062 #ifdef DEBUG_LISTEN
00063     printf("[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);
00064     uint8_t ip[4];
00065     printf("socket:%d SnMR:%02x SnIR:%02x SnSR:%02x", _socket, 
00066         W5200.readSnMR(_socket), W5200.readSnIR(_socket), W5200.readSnSR(_socket));
00067     W5200.getIPAddress(ip);
00068     printf(" SIPR: %d.%d.%d.%d Sn_PORT:%d\n", ip[0], ip[1], ip[2], ip[3], W5200.readSnPORT(_socket));
00069 #endif //DEBUG_LISTEN
00070     wait_accept = true;
00071     return NETTCPSOCKET_OK;
00072 }
00073 
00074 NetTcpSocketErr MyNetTcpSocket::connect(const Host& host) {
00075     DBG("%p host=%p\n", this, host);
00076     if (_socket == (-1)) {
00077         return NETTCPSOCKET_MEM;
00078     }
00079     uint8_t ip[4];
00080     ip[0] = host.getIp()[0];
00081     ip[1] = host.getIp()[1];
00082     ip[2] = host.getIp()[2];
00083     ip[3] = host.getIp()[3];
00084     int port = host.getPort();
00085     W5200.writeSnDIPR(_socket, ip);
00086     W5200.writeSnDPORT(_socket, port);
00087     if (W5200.readSnPORT(_socket) == 0) {
00088         W5200.writeSnPORT(_socket, 1024 + _socket);
00089     }
00090     W5200.execCmdSn(_socket, Sock_OPEN); // set OPEN command
00091     W5200.execCmdSn(_socket, Sock_CONNECT);
00092 #ifdef DEBUG_CONNECT
00093     printf("socket:%d SnMR:%02x SnIR:%02x SnSR:%02x\n", _socket, 
00094         W5200.readSnMR(_socket), W5200.readSnIR(_socket), W5200.readSnSR(_socket));
00095     W5200.getIPAddress(ip);
00096     printf("SIPR: %d.%d.%d.%d Sn_PORT:%d\n", ip[0], ip[1], ip[2], ip[3], W5200.readSnPORT(_socket));
00097     W5200.readSnDIPR(_socket, ip);
00098     printf("Sn_DIPR: %d.%d.%d.%d Sn_DPORT:%d\n", ip[0], ip[1], ip[2], ip[3], W5200.readSnDPORT(_socket));
00099 #endif //DEBUG_CONNECT
00100     return NETTCPSOCKET_OK;
00101 }
00102 
00103 NetTcpSocketErr MyNetTcpSocket::accept(Host* pClient, NetTcpSocket** ppNewNetTcpSocket) {
00104     DBG("%p pClient=%p\n", this, pClient);
00105     if (_socket == (-1)) {
00106         return NETTCPSOCKET_MEM;
00107     }
00108     uint8_t ip[4];
00109     W5200.readSnDIPR(_socket, ip);
00110     pClient->setIp(IpAddr(ip[0],ip[1],ip[2],ip[3]));
00111     int port = W5200.readSnDPORT(_socket);
00112     pClient->setPort(port);
00113     Host me;
00114     me.setPort(W5200.readSnPORT(_socket));
00115     MyNetTcpSocket* pNewNetTcpSocket = new MyNetTcpSocket(_socket);
00116     if (pNewNetTcpSocket == NULL) {
00117         return NETTCPSOCKET_EMPTY;
00118     }
00119     pNewNetTcpSocket->m_refs++;
00120     *ppNewNetTcpSocket = pNewNetTcpSocket;
00121     _socket = w5200_new_socket();
00122     if (_socket != (-1)) {
00123         uint8_t Sn_MR = SnMR::TCP; // set TCP mode
00124 #if USE_NO_DELAYED_ACK 
00125         Sn_MR |= SnMR::ND;
00126 #endif 
00127         W5200.writeSnMR(_socket, Sn_MR);
00128         bind(me);
00129         listen();
00130      }
00131     return NETTCPSOCKET_OK;
00132 }
00133 
00134 int /*if < 0 : NetTcpSocketErr*/ MyNetTcpSocket::send(const char* buf, int len) {
00135     DBG_STR((uint8_t*)buf,len);
00136     if (_socket == (-1)) {
00137         return NETTCPSOCKET_MEM;
00138     }
00139     if (len > 0) {
00140         W5200.send_data_processing(_socket, (uint8_t*)buf, len);
00141         W5200.execCmdSn(_socket, Sock_SEND);
00142     }
00143     return len;
00144 }
00145 
00146 int /*if < 0 : NetTcpSocketErr*/ MyNetTcpSocket::recv(char* buf, int len){
00147     if (_socket == (-1)) {
00148         return NETTCPSOCKET_MEM;
00149     }
00150     int size = W5200.getRXReceivedSize(_socket);
00151     if (size > len) {
00152         size = len;
00153     }
00154     if (size > 0) {
00155         W5200.recv_data_processing(_socket, (uint8_t*)buf, size);
00156         W5200.execCmdSn(_socket, Sock_RECV);
00157     }
00158     DBG_STR((uint8_t*)buf, size);
00159     return size;
00160 }
00161 
00162 NetTcpSocketErr MyNetTcpSocket::close() {
00163     DBG("%p m_closed=%d m_refs=%d\n", this, m_closed, m_refs);
00164     if(m_closed) {
00165         return NETTCPSOCKET_OK;
00166     }
00167     m_closed = true;
00168     cleanUp();
00169     if (_socket != (-1)) {
00170         W5200.execCmdSn(_socket, Sock_DISCON);
00171         W5200.execCmdSn(_socket, Sock_CLOSE);
00172     }
00173     return NETTCPSOCKET_OK;
00174 }
00175 
00176 NetTcpSocketErr MyNetTcpSocket::poll(){
00177     NetTcpSocket::flushEvents();
00178 #ifdef DEBUG_POLL
00179     printf("%p socket:%d\n", this,_socket);
00180     if (_socket != (-1)) {
00181         printf("SnMR:%02x SnIR:%02x SnSR:%02x\n", 
00182             W5200.readSnMR(_socket), W5200.readSnIR(_socket), W5200.readSnSR(_socket));
00183         uint8_t ip[4];
00184         W5200.readSnDIPR(_socket, ip);
00185         printf("Sn_DIPR: %d.%d.%d.%d Sn_DPORT: %d\n", ip[0], ip[1], ip[2], ip[3], W5200.readSnDPORT(_socket));
00186         printf("Sn_RX_RSR:%5d, Sn_RX_RD:%5d, Sn_RX_WR:%5d\n",
00187                 W5200.readSnRX_RSR(_socket), W5200.readSnRX_RD(_socket), W5200.readSnRX_WR(_socket));
00188         printf("Sn_TX_FSR:%5d, Sn_TX_RD:%5d, Sn_TX_WR:%5d\n",
00189                 W5200.readSnTX_FSR(_socket), W5200.readSnTX_RD(_socket), W5200.readSnTX_WR(_socket));
00190     }
00191     wait_ms(200);
00192 #endif //DEBUG_POLL
00193     if (_socket == (-1)) {
00194         return NETTCPSOCKET_OK;
00195     }
00196     uint8_t Sn_SR = W5200.readSnSR(_socket);
00197     if (wait_accept) {
00198         if (Sn_SR == 0x17) {
00199             queueEvent(NETTCPSOCKET_ACCEPT);
00200             wait_accept = false;
00201         }
00202     }
00203     if (Sn_SR == 0x1c) {
00204         queueEvent(NETTCPSOCKET_CONRST);
00205     }
00206     if (W5200.getRXReceivedSize(_socket) > 0) {
00207         queueEvent(NETTCPSOCKET_READABLE);
00208     }
00209     if (Sn_SR == 0x17) {
00210         queueEvent(NETTCPSOCKET_CONNECTED);
00211         if (W5200.getTXFreeSize(_socket) > 0) {
00212             queueEvent(NETTCPSOCKET_WRITEABLE);
00213         }
00214     }
00215     if (Sn_SR == 0x00) {
00216         queueEvent(NETTCPSOCKET_DISCONNECTED);
00217     }
00218     return NETTCPSOCKET_OK;
00219 }
00220 
00221 void MyNetTcpSocket::cleanUp() //Flush input buffer
00222 {
00223     if (_socket == (-1)) {
00224         return;
00225     }
00226     while(W5200.getRXReceivedSize(_socket) > 0) {
00227         uint8_t temp[1];
00228         W5200.recv_data_processing(_socket, temp, 1);
00229         W5200.execCmdSn(_socket, Sock_RECV);
00230     }    
00231 }