for EthernetInterface library compatibility.\\ ** Unoffical fix. may be a problem. **

Dependents:   SNIC-httpclient-example SNIC-ntpclient-example

Fork of SNICInterface by muRata

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UDPSocket.cpp Source File

UDPSocket.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 "Socket/UDPSocket.h"
00022 #include <cstring>
00023 
00024 UDPSocket::UDPSocket() {
00025 }
00026 
00027 UDPSocket::~UDPSocket()
00028 {
00029 }
00030 
00031 int UDPSocket::init(void) 
00032 {
00033     return 0;
00034 }
00035 
00036 // Server initialization
00037 int UDPSocket::bind(short port) 
00038 {
00039     int ret;
00040     C_SNIC_Core               *snic_core_p  = C_SNIC_Core::getInstance();
00041     C_SNIC_UartCommandManager *uartCmdMgr_p = snic_core_p->getUartCommand();
00042     
00043     FUNC_IN();
00044     // Get local ip address.
00045     // Get buffer for response payload from MemoryPool
00046     tagMEMPOOL_BLOCK_T *payload_buf_p = snic_core_p->allocCmdBuf();
00047     if( payload_buf_p == NULL )
00048     {
00049         DEBUG_PRINT("UDP bind payload_buf_p NULL\r\n");
00050         FUNC_OUT();
00051         return -1;
00052     }
00053 
00054     C_SNIC_Core::tagSNIC_GET_DHCP_INFO_REQ_T req;
00055     // Make request
00056     req.cmd_sid      = UART_CMD_SID_SNIC_GET_DHCP_INFO_REQ;
00057     req.seq          = mUartRequestSeq++;
00058     req.interface    = 0;
00059     
00060     unsigned char *command_array_p = snic_core_p->getCommandBuf();
00061     unsigned int  command_len;
00062     // Preparation of command
00063     command_len = snic_core_p->preparationSendCommand( UART_CMD_ID_SNIC, req.cmd_sid, (unsigned char *)&req
00064                             , sizeof(C_SNIC_Core::tagSNIC_GET_DHCP_INFO_REQ_T), payload_buf_p->buf, command_array_p );
00065     // Send uart command request
00066     snic_core_p->sendUart( command_len, command_array_p );
00067     // Wait UART response
00068     ret = uartCmdMgr_p->wait();
00069     if( ret != 0 )
00070     {
00071         DEBUG_PRINT( "UDP bind failed\r\n" );
00072         snic_core_p->freeCmdBuf( payload_buf_p );
00073         FUNC_OUT();
00074         return -1;
00075     }
00076     
00077     if( uartCmdMgr_p->getCommandStatus() != UART_CMD_RES_SNIC_SUCCESS )
00078     {
00079         DEBUG_PRINT("UDP bind status:%02x\r\n", uartCmdMgr_p->getCommandStatus());
00080         snic_core_p->freeCmdBuf( payload_buf_p );
00081         FUNC_OUT();
00082         return -1;
00083     }
00084     
00085     unsigned int local_addr = (payload_buf_p->buf[9]  << 24)
00086                             | (payload_buf_p->buf[10] << 16)
00087                             | (payload_buf_p->buf[11] << 8)
00088                             | (payload_buf_p->buf[12]);
00089 
00090 
00091     C_SNIC_Core::tagSNIC_UDP_CREATE_SOCKET_REQ_T create_req;
00092     
00093     // Make request
00094     create_req.cmd_sid  = UART_CMD_SID_SNIC_UDP_CREATE_SOCKET_REQ;
00095     create_req.seq      = mUartRequestSeq++;
00096     create_req.bind     = 1;
00097     // set ip addr ( byte order )
00098     C_SNIC_UartMsgUtil::convertIntToByteAdday( local_addr, (char *)create_req.local_addr );
00099     create_req.local_port[0] = ( (port & 0xFF00) >> 8 );
00100     create_req.local_port[1] = (port & 0xFF);
00101 
00102     // Preparation of command
00103     command_len = snic_core_p->preparationSendCommand( UART_CMD_ID_SNIC, create_req.cmd_sid, (unsigned char *)&create_req
00104                             , sizeof(C_SNIC_Core::tagSNIC_UDP_CREATE_SOCKET_REQ_T), payload_buf_p->buf, command_array_p );
00105     // Send uart command request
00106     snic_core_p->sendUart( command_len, command_array_p );
00107 
00108     // Wait UART response
00109     ret = uartCmdMgr_p->wait();
00110     if( ret != 0 )
00111     {
00112         DEBUG_PRINT( "UDP bind failed\r\n" );
00113         snic_core_p->freeCmdBuf( payload_buf_p );
00114         FUNC_OUT();
00115         return -1;
00116     }
00117 
00118     if( uartCmdMgr_p->getCommandStatus() != 0 )
00119     {
00120         DEBUG_PRINT("UDP bind status:%02x\r\n", uartCmdMgr_p->getCommandStatus());
00121         snic_core_p->freeCmdBuf( payload_buf_p );
00122         FUNC_OUT();
00123         return -1;
00124     }
00125     mSocketID = payload_buf_p->buf[3];
00126     
00127     // Initialize connection information
00128     C_SNIC_Core::tagCONNECT_INFO_T *con_info_p = snic_core_p->getConnectInfo( mSocketID );
00129     if( con_info_p->recvbuf_p == NULL )
00130     {
00131         DEBUG_PRINT( "create recv buffer[socket:%d]\r\n", mSocketID);
00132         con_info_p->recvbuf_p = new CircBuffer<char>(SNIC_UART_RECVBUF_SIZE);
00133     }
00134     con_info_p->is_connected = true;
00135     con_info_p->is_received  = false;
00136 
00137     C_SNIC_Core::tagSNIC_UDP_START_RECV_REQ_T recv_start_req;
00138     
00139     // Make request
00140     recv_start_req.cmd_sid         = UART_CMD_SID_SNIC_UDP_START_RECV_REQ;
00141     recv_start_req.seq             = mUartRequestSeq++;
00142     recv_start_req.socket_id       = mSocketID;
00143     recv_start_req.recv_bufsize[0] = ( (SNIC_UART_RECVBUF_SIZE & 0xFF00) >> 8 );
00144     recv_start_req.recv_bufsize[1] = (SNIC_UART_RECVBUF_SIZE & 0xFF);
00145 
00146     // Preparation of command
00147     command_len = snic_core_p->preparationSendCommand( UART_CMD_ID_SNIC, recv_start_req.cmd_sid, (unsigned char *)&recv_start_req
00148                             , sizeof(C_SNIC_Core::tagSNIC_UDP_START_RECV_REQ_T), payload_buf_p->buf, command_array_p );
00149     // Send uart command request
00150     snic_core_p->sendUart( command_len, command_array_p );
00151 
00152     // Wait UART response
00153     ret = uartCmdMgr_p->wait();
00154     if( ret != 0 )
00155     {
00156         DEBUG_PRINT( "UDP recv start failed\r\n" );
00157         snic_core_p->freeCmdBuf( payload_buf_p );
00158         FUNC_OUT();
00159         return -1;
00160     }
00161 
00162     if( uartCmdMgr_p->getCommandStatus() != 0 )
00163     {
00164         DEBUG_PRINT("UDP recv start status:%02x\r\n", uartCmdMgr_p->getCommandStatus());
00165         snic_core_p->freeCmdBuf( payload_buf_p );
00166         FUNC_OUT();
00167         return -1;
00168     }
00169 
00170     snic_core_p->freeCmdBuf( payload_buf_p );
00171     FUNC_OUT();
00172     return 0;
00173 }
00174 
00175 // -1 if unsuccessful, else number of bytes written
00176 int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
00177 {
00178     C_SNIC_Core               *snic_core_p  = C_SNIC_Core::getInstance();
00179     C_SNIC_UartCommandManager *uartCmdMgr_p = snic_core_p->getUartCommand();
00180 
00181     osThreadId tid = Thread::gettid();
00182     
00183 //  pc.printf("send[%08x] len:%d(%04x)\r\n", tid, length, length);
00184     
00185 #if 0   // TODO: Not wait for command response(Tentative)    
00186     snic_core_p->lockAPI();
00187 #endif
00188     FUNC_IN();
00189 
00190 #if 0   // TODO: Not wait for command response(Tentative)    
00191     // Get buffer for response payload from MemoryPool
00192     tagMEMPOOL_BLOCK_T *payload_buf_p = snic_core_p->allocCmdBuf();
00193     if( payload_buf_p == NULL )
00194     {
00195         DEBUG_PRINT("connect payload_buf_p NULL\r\n");
00196         FUNC_OUT();
00197         snic_core_p->unlockAPI();
00198         return -1;
00199     }
00200 #endif
00201 
00202     C_SNIC_Core::tagSNIC_UDP_SEND_FROM_SOCKET_REQ_T req;
00203     // Make request
00204     req.cmd_sid       = UART_CMD_SID_SNIC_UDP_SEND_FROM_SOCKET_REQ;
00205     req.seq           = mUartRequestSeq++;
00206 
00207     int addr_temp;
00208     addr_temp = C_SNIC_UartMsgUtil::addrToInteger( remote.get_address() );
00209     C_SNIC_UartMsgUtil::convertIntToByteAdday( addr_temp, (char *)req.remote_ip );
00210     req.remote_port[0]  = ( (remote.get_port() & 0xFF00) >> 8 );
00211     req.remote_port[1]  = (remote.get_port() & 0xFF);
00212     req.payload_len[0]  = ( (length & 0xFF00) >> 8 );
00213     req.payload_len[1]  = (length & 0xFF);
00214     req.socket_id       = mSocketID;
00215     req.connection_mode = 1;
00216     
00217     // Initialize connection information
00218     C_SNIC_Core::tagCONNECT_INFO_T *con_info_p = snic_core_p->getConnectInfo( mSocketID );
00219     if( con_info_p != NULL )
00220     {
00221         con_info_p->from_ip   = addr_temp;
00222         con_info_p->from_port = remote.get_port();
00223     }
00224 
00225     int req_size = sizeof(C_SNIC_Core::tagSNIC_UDP_SEND_FROM_SOCKET_REQ_T);
00226     
00227     char *send_buf_p = getSocketSendBuf();
00228     memcpy( send_buf_p, &req, req_size );
00229     memcpy( &send_buf_p[req_size], packet, length );
00230     
00231     unsigned char *command_array_p = snic_core_p->getCommandBuf();
00232     unsigned int   command_len;
00233 
00234     // Make all command request
00235     command_len = C_SNIC_UartMsgUtil::makeRequest( UART_CMD_ID_SNIC, (unsigned char *)send_buf_p, req_size + length, command_array_p );
00236 
00237     // Send uart command request
00238     snic_core_p->sendUart( command_len, command_array_p );
00239 
00240 #if 0   // TODO: Not wait for command response(Tentative)
00241     // Wait UART response
00242     int ret = uartCmdMgr_p->wait();
00243     if( ret != 0 )
00244     {
00245         DEBUG_PRINT( "send failed\r\n" );
00246         snic_core_p->freeCmdBuf( payload_buf_p );
00247         FUNC_OUT();
00248         snic_core_p->unlockAPI();
00249         return -1;
00250     }
00251     
00252     if( uartCmdMgr_p->getCommandStatus() != UART_CMD_RES_SNIC_SUCCESS )
00253     {
00254         DEBUG_PRINT("send status:%02x\r\n", uartCmdMgr_p->getCommandStatus());
00255         snic_core_p->freeCmdBuf( payload_buf_p );
00256         FUNC_OUT();
00257         snic_core_p->unlockAPI();
00258         return -1;
00259     }
00260     snic_core_p->freeCmdBuf( payload_buf_p );
00261 #endif
00262     
00263     FUNC_OUT();
00264 #if 0   // TODO: Not wait for command response(Tentative)    
00265     snic_core_p->unlockAPI();
00266 #endif
00267     // SNIC_SEND_FROM_SOCKET_REQ
00268     wait(0.05);
00269 
00270     return length;
00271 //    return 0;
00272 }
00273 
00274 // -1 if unsuccessful, else number of bytes received
00275 int UDPSocket::receiveFrom(Endpoint &remote, char *data_p, int length)
00276 {
00277     FUNC_IN();
00278     if( (data_p == NULL) || (length < 1) )
00279     {
00280         DEBUG_PRINT("UDPSocket::receiveFrom parameter error\r\n");
00281         FUNC_OUT();
00282         return -1;
00283     }
00284 
00285     C_SNIC_Core                    *snic_core_p  = C_SNIC_Core::getInstance();
00286     // Initialize connection information
00287     C_SNIC_Core::tagCONNECT_INFO_T *con_info_p = snic_core_p->getConnectInfo( mSocketID );
00288     if( con_info_p->recvbuf_p == NULL )
00289     {
00290         DEBUG_PRINT("UDPSocket::receiveFrom Conncection info error\r\n");
00291         FUNC_OUT();
00292         return -1;
00293     }
00294 
00295     char remote_ip[20] = {'\0'};
00296     sprintf( remote_ip, "%d.%d.%d.%d"
00297         , (con_info_p->from_ip >>24) & 0x000000ff
00298         , (con_info_p->from_ip >>16) & 0x000000ff
00299         , (con_info_p->from_ip >>8)  & 0x000000ff
00300         , (con_info_p->from_ip)      & 0x000000ff );
00301     remote.set_address( remote_ip, con_info_p->from_port );
00302     
00303     con_info_p->mutex.lock();
00304     con_info_p->is_receive_complete = true;
00305     con_info_p->mutex.unlock();
00306     if( con_info_p->is_received == false )
00307     {
00308         // Try receive
00309         Thread::yield();
00310         
00311         if( con_info_p->is_received == false )
00312         {
00313             // No data received.
00314             FUNC_OUT();
00315             return 0;
00316         }
00317     }
00318     // Get packet data from buffer for receive.
00319     int i;
00320     for (i = 0; i < length; i ++) 
00321     {
00322         if (con_info_p->recvbuf_p->dequeue(&data_p[i]) == false)
00323         {
00324             break;
00325         }
00326     }
00327     if( con_info_p->recvbuf_p->isEmpty() )
00328     {
00329         con_info_p->mutex.lock();
00330         con_info_p->is_received = false;
00331         con_info_p->mutex.unlock();
00332     }
00333     FUNC_OUT();
00334     return i;
00335 }