Free (GPLv2) TCP/IP stack developed by TASS Belgium

Dependents:   lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TCPSocketConnection.cpp Source File

TCPSocketConnection.cpp

00001 /* 
00002  *
00003  * PicoTCP Socket interface for mbed.
00004  * Copyright (C) 2013 TASS Belgium NV
00005  * 
00006  * Released under GPL v2
00007  *
00008  * Other licensing models might apply at the sole discretion of the copyright holders.
00009  *
00010  *
00011  * This software is based on the mbed.org EthernetInterface implementation:
00012  * Copyright (C) 2012 mbed.org, MIT License
00013  *
00014  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00015  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00016  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00017  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00018  * furnished to do so, subject to the following conditions:
00019  *
00020  * The above copyright notice and this permission notice shall be included in all copies or
00021  * substantial portions of the Software.
00022  *
00023  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00024  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00025  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00026  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00028  */
00029 #include "TCPSocketConnection.h"
00030 #include "wrapper.h"
00031 #include <cstring>
00032 
00033 using std::memset;
00034 using std::memcpy;
00035 
00036 TCPSocketConnection::TCPSocketConnection()
00037 {
00038 }
00039 
00040 int TCPSocketConnection::connect(const char* host, const int port) {
00041     if (init_socket(SOCK_STREAM) < 0)
00042     {
00043         mbed_dbg("init_socket\n");
00044         return -1;
00045     }
00046    
00047     if (set_address(host, port) != 0)
00048     {
00049         mbed_dbg("set_address\n");
00050         return -1;
00051     }
00052     if (picotcp_connect(_ep, (struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
00053         close();
00054         return -1;
00055     }
00056     
00057     return 0;
00058 }
00059 
00060 bool TCPSocketConnection::is_connected(void) {
00061     if((_ep == NULL) || (_ep->state != SOCK_CONNECTED))
00062         return false;
00063     else
00064         return true;
00065 }
00066 
00067 int TCPSocketConnection::send(char* data, int length) {
00068     int ret;
00069     pico_time localTimeout = _timeout;
00070     pico_time finalTimeout = PICO_TIME_MS() + _timeout;
00071     if (!is_connected())
00072         return -1;
00073     
00074     if(is_writable())
00075     {
00076         ret = picotcp_write(_ep, data, length);
00077         if(ret < length)
00078             _ep->revents &= (~PICO_SOCK_EV_WR);
00079         if(ret) // data was read or error was reported
00080             return ret;
00081     }
00082 repeat:    
00083     TimeInterval timeout(!_blocking ? localTimeout : osWaitForever);
00084     if (wait_writable(timeout) != 0)
00085     {
00086         return 0; /* Timeout */
00087     }
00088     
00089     ret = picotcp_write(_ep, data, length);
00090     if (ret < length) {
00091         _ep->revents &= (~PICO_SOCK_EV_WR);
00092         //mbed_dbg("Short write\n");
00093       if(ret ==0 && pico_err == PICO_ERR_EAGAIN && PICO_TIME_MS() < finalTimeout)
00094       {
00095         localTimeout = finalTimeout - PICO_TIME_MS();
00096         goto repeat;
00097       }
00098     }
00099     return ret;
00100 }
00101 
00102 // -1 if unsuccessful, else number of bytes written
00103 int TCPSocketConnection::send_all(char* data, int length) {
00104     return send(data,length);
00105 }
00106 
00107 int TCPSocketConnection::receive(char* data, int length) {
00108     int ret;
00109     if (!is_connected() && !is_readable())
00110         return -1;
00111     
00112     if(is_readable())
00113     {
00114         ret = picotcp_read(_ep, data, length);
00115         if(ret<length)
00116             _ep->revents &= (~PICO_SOCK_EV_RD);
00117         if(ret) // data was read or error was reported
00118             return ret;
00119     }   
00120     
00121     TimeInterval timeout(!_blocking ? _timeout : osWaitForever);
00122     if (wait_readable(timeout) != 0)
00123     {
00124         return 0; /* Timeout */
00125     }
00126 
00127     ret = picotcp_read(_ep, data, length);
00128     if (ret < length) {
00129         _ep->revents &= (~PICO_SOCK_EV_RD);
00130         //mbed_dbg("Short read\n");
00131     }
00132     return ret;
00133 }
00134 
00135 // -1 if unsuccessful, else number of bytes received
00136 int TCPSocketConnection::receive_all(char* data, int length) {
00137     return receive(data, length);
00138 }