Toyomasa Watarai / type-yd-driver

Dependents:   easy-connect-type-yd

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TCPSocketConnection.cpp Source File

TCPSocketConnection.cpp

00001 /* Copyright (C) 2012 mbed.org, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 /* Copyright (C) 2014 Murata Manufacturing Co.,Ltd., MIT License
00019  *  port to the muRata, SWITCH SCIENCE Wi-FI module TypeYD SNIC-UART.
00020  */
00021 #include "SNICInterface/Socket/TCPSocketConnection.h"
00022 #include <cstring>
00023 
00024 #include "mbed.h"
00025 #include "mbed-trace/mbed_trace.h"
00026 #define TRACE_GROUP "SNIC"
00027 
00028 TCPSocketConnection::TCPSocketConnection()
00029 {
00030 }
00031 
00032 TCPSocketConnection::~TCPSocketConnection()
00033 {
00034 }
00035 
00036 int TCPSocketConnection::bind(short port) 
00037 {
00038     C_SNIC_Core               *snic_core_p  = C_SNIC_Core::getInstance();
00039 
00040     FUNC_IN();
00041 
00042     // TODO : bind to specified port
00043     //        but Type YD dosn't accept when UART_CMD_SID_SNIC_TCP_CONNECT_TO_SERVER_REQ
00044 //    int ret = createSocket(1, 0, port);
00045     int ret = createSocket();
00046     if (ret != 0)
00047     {
00048         DEBUG_PRINT( "TCP bind failed\r\n" );
00049         FUNC_OUT();
00050         return -1;
00051     }
00052 
00053     FUNC_OUT();
00054     return 0;
00055 }
00056 
00057 int TCPSocketConnection::connect( const char *host_p, unsigned short port)
00058 {
00059     int ret;
00060     C_SNIC_Core               *snic_core_p  = C_SNIC_Core::getInstance();
00061     C_SNIC_UartCommandManager *uartCmdMgr_p = snic_core_p->getUartCommand();
00062 
00063     FUNC_IN();
00064     // Socket create
00065     if (mSocketID < 0) {
00066         ret = createSocket();
00067         if( ret != 0 )
00068         {
00069             DEBUG_PRINT("createSocket error : %d\r\n", ret);
00070             FUNC_OUT();
00071             return -1;
00072         }
00073     }
00074     
00075     int ip_addr = resolveHostName( host_p );
00076     //lcd_printf("connect to [%s](%08x)\r\n", host_p, ip_addr);
00077     if( ( ip_addr == 0) || (ip_addr == -1) )
00078     {
00079         DEBUG_PRINT("connect resolveHostName failed\r\n");
00080         FUNC_OUT();
00081         return -1;
00082     }
00083         
00084     // Get buffer for response payload from MemoryPool
00085     tagMEMPOOL_BLOCK_T *payload_buf_p = snic_core_p->allocCmdBuf();
00086     if( payload_buf_p == NULL )
00087     {
00088         DEBUG_PRINT("connect payload_buf_p NULL\r\n");
00089         FUNC_OUT();
00090         return -1;
00091     }
00092     
00093     // IP address convert to number from strings.     
00094 //    unsigned int ip_addr = addrToInteger(ip_addr_p);
00095 
00096     // 
00097     C_SNIC_Core::tagSNIC_TCP_CONNECT_TO_SERVER_REQ_T req;
00098     // Make request
00099     req.cmd_sid      = UART_CMD_SID_SNIC_TCP_CONNECT_TO_SERVER_REQ;
00100     req.seq          = mUartRequestSeq++;
00101     req.socket_id    = mSocketID;
00102     
00103     // set ip addr ( byte order )
00104     C_SNIC_UartMsgUtil::convertIntToByteAdday( ip_addr, (char *)req.remote_addr );
00105     req.remote_port[0] = ( (port & 0xFF00) >> 8 );
00106     req.remote_port[1] = (port & 0xFF);
00107     req.recv_bufsize[0] = ( (SNIC_UART_RECVBUF_SIZE & 0xFF00) >> 8 );
00108     req.recv_bufsize[1] = (SNIC_UART_RECVBUF_SIZE & 0xFF);
00109     req.timeout         = 60;
00110 
00111     unsigned char *command_array_p = snic_core_p->getCommandBuf();
00112     unsigned int  command_len;
00113     // Preparation of command
00114     command_len = snic_core_p->preparationSendCommand( UART_CMD_ID_SNIC, req.cmd_sid, (unsigned char *)&req
00115                             , sizeof(C_SNIC_Core::tagSNIC_TCP_CONNECT_TO_SERVER_REQ_T), payload_buf_p->buf, command_array_p );
00116 
00117     uartCmdMgr_p->setCommandSID( UART_CMD_SID_SNIC_TCP_CONNECTION_STATUS_IND );
00118 
00119     // Send uart command request
00120     snic_core_p->sendUart( command_len, command_array_p );
00121 
00122     // Wait UART response
00123     ret = uartCmdMgr_p->wait();
00124     if( ret != 0 )
00125     {
00126         DEBUG_PRINT( "connect failed\r\n" );
00127         snic_core_p->freeCmdBuf( payload_buf_p );
00128         FUNC_OUT();
00129         return -1;
00130     }
00131     
00132     if( uartCmdMgr_p->getCommandStatus() != UART_CMD_RES_SNIC_CONNECTION_UP )
00133     {
00134         DEBUG_PRINT("connect status:%02x\r\n", uartCmdMgr_p->getCommandStatus());
00135         snic_core_p->freeCmdBuf( payload_buf_p );
00136         FUNC_OUT();
00137         return -1;
00138     }
00139 
00140     snic_core_p->freeCmdBuf( payload_buf_p );
00141 
00142     //DEBUG_PRINT( "TCP connection success[%d]\n", mSocketID);
00143     // Initialize connection information
00144     C_SNIC_Core::tagCONNECT_INFO_T *con_info_p = snic_core_p->getConnectInfo( mSocketID );
00145     if( con_info_p->recvbuf_p == NULL )
00146     {
00147         //DEBUG_PRINT( "create recv buffer[socket:%d]\r\n", mSocketID);
00148         con_info_p->recvbuf_p = new CircBuffer<char>(SNIC_UART_RECVBUF_SIZE);
00149     }
00150     con_info_p->is_connected = true;
00151     con_info_p->is_received  = false;
00152     con_info_p->snic_socket = this;
00153     FUNC_OUT();
00154     return 0;
00155 }
00156 
00157 bool TCPSocketConnection::is_connected(void)
00158 {
00159     C_SNIC_Core                    *snic_core_p  = C_SNIC_Core::getInstance();
00160     C_SNIC_Core::tagCONNECT_INFO_T *con_info_p = snic_core_p->getConnectInfo( mSocketID );
00161     return con_info_p->is_connected;
00162 }
00163 
00164 int TCPSocketConnection::send(char* data_p, int length)
00165 {
00166     C_SNIC_Core               *snic_core_p  = C_SNIC_Core::getInstance();
00167     C_SNIC_UartCommandManager *uartCmdMgr_p = snic_core_p->getUartCommand();
00168 
00169     FUNC_IN();
00170     // Get buffer for response payload from MemoryPool
00171     tagMEMPOOL_BLOCK_T *payload_buf_p = snic_core_p->allocCmdBuf();
00172     if( payload_buf_p == NULL )
00173     {
00174         DEBUG_PRINT("connect payload_buf_p NULL\r\n");
00175         FUNC_OUT();
00176         return -1;
00177     }
00178     
00179     C_SNIC_Core::tagSNIC_TCP_SEND_FROM_SOCKET_REQ_T req;
00180     // Make request
00181     req.cmd_sid       = UART_CMD_SID_SNIC_SEND_FROM_SOCKET_REQ;
00182     req.seq           = mUartRequestSeq++;
00183     req.socket_id     = mSocketID;
00184     req.option        = 0;
00185     req.payload_len[0]= ( (length & 0xFF00) >> 8 );
00186     req.payload_len[1]= (length & 0xFF);
00187     
00188     int req_size     = sizeof(C_SNIC_Core::tagSNIC_TCP_SEND_FROM_SOCKET_REQ_T);
00189     char *send_buf_p = getSocketSendBuf();
00190     memcpy( send_buf_p, &req, req_size );
00191     memcpy( &send_buf_p[req_size], data_p, length );
00192     
00193     unsigned char *command_array_p = snic_core_p->getCommandBuf();
00194     unsigned int   command_len;
00195     // Preparation of command
00196     command_len = snic_core_p->preparationSendCommand( UART_CMD_ID_SNIC, req.cmd_sid, (unsigned char *)send_buf_p
00197                             , req_size + length, payload_buf_p->buf, command_array_p );
00198 
00199     // Send uart command request
00200     snic_core_p->sendUart( command_len, command_array_p );
00201 
00202     // Wait UART response
00203     int ret = uartCmdMgr_p->wait();
00204     if( ret != 0 )
00205     {
00206       DEBUG_PRINT( "send failed:%d\r\n", ret );
00207         snic_core_p->freeCmdBuf( payload_buf_p );
00208         FUNC_OUT();
00209         return -1;
00210     }
00211     
00212     if( uartCmdMgr_p->getCommandStatus() != UART_CMD_RES_SNIC_SUCCESS )
00213     {
00214         DEBUG_PRINT("send status:%02x\r\n", uartCmdMgr_p->getCommandStatus());
00215         snic_core_p->freeCmdBuf( payload_buf_p );
00216         FUNC_OUT();
00217         return -1;
00218     }
00219     snic_core_p->freeCmdBuf( payload_buf_p );
00220 
00221     // SNIC_SEND_FROM_SOCKET_REQ
00222     FUNC_OUT();
00223     return length;
00224 }
00225 
00226 int TCPSocketConnection::send_all(char *data_p, int length)
00227 {
00228     return send( data_p, length );
00229 }
00230 
00231 int TCPSocketConnection::receive(char* data_p, int length)
00232 {
00233     FUNC_IN();
00234     if( (data_p == NULL) || (length < 1) )
00235     {
00236         DEBUG_PRINT("TCPSocketConnection::receive parameter error\r\n");
00237         FUNC_OUT();
00238         return -1;
00239     }
00240     
00241     C_SNIC_Core                    *snic_core_p  = C_SNIC_Core::getInstance();
00242     // Initialize connection information
00243     C_SNIC_Core::tagCONNECT_INFO_T *con_info_p = snic_core_p->getConnectInfo( mSocketID );
00244     if( con_info_p->recvbuf_p == NULL )
00245     {
00246         DEBUG_PRINT("TCPSocketConnection::receive Conncection info error\r\n");
00247         FUNC_OUT();
00248         return -1;
00249     }
00250 
00251     // Check connection
00252     if( con_info_p->is_connected == false )
00253     {
00254         DEBUG_PRINT(" Socket id \"%d\" is not connected\r\n", mSocketID);
00255         FUNC_OUT();
00256         return -1;
00257     }
00258 
00259     // TODO : wait receive timeout
00260     if (con_info_p->recvbuf_p->isEmpty()) {
00261         return NSAPI_ERROR_WOULD_BLOCK;
00262     }
00263 
00264     con_info_p->mutex.lock();
00265 
00266     // Get packet data from buffer for receive.
00267     int i = 0;
00268     for (i = 0; i < length; i ++) 
00269     {
00270         if (con_info_p->recvbuf_p->dequeue(&data_p[i]) == false)
00271         {
00272             break;
00273         }
00274     }
00275     
00276     con_info_p->mutex.unlock();
00277 
00278     FUNC_OUT();
00279     return i;
00280 }
00281 
00282 int TCPSocketConnection::receive_all(char* data_p, int length)
00283 {
00284     return receive( data_p, length );
00285 }
00286 
00287 void TCPSocketConnection::setAcceptSocket( int socket_id )
00288 {
00289     FUNC_IN();
00290     mSocketID = socket_id;
00291     tr_debug("setAcceptSocket:mSocketID=%d", mSocketID);
00292     FUNC_OUT();
00293 }
00294