Daniele Lacamera / PicoTCP-Experimental_CDC_ECM_Branch

Fork of PicoTCP by Daniele Lacamera

Committer:
daniele
Date:
Thu Jun 06 07:08:58 2013 +0000
Revision:
11:58acd53df75c
Parent:
5:445d2fc04784
Child:
13:c6662adea07d
Update from masterbranch;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 5:445d2fc04784 1 /*
tass 5:445d2fc04784 2 *
tass 5:445d2fc04784 3 * PicoTCP Socket interface for mbed.
tass 5:445d2fc04784 4 * Copyright (C) 2013 TASS Belgium NV
tass 5:445d2fc04784 5 *
tass 5:445d2fc04784 6 * Released under GPL v2
tass 5:445d2fc04784 7 *
tass 5:445d2fc04784 8 * Other licensing models might apply at the sole discretion of the copyright holders.
tass 5:445d2fc04784 9 *
tass 5:445d2fc04784 10 *
tass 5:445d2fc04784 11 * This software is based on the mbed.org EthernetInterface implementation:
tass 5:445d2fc04784 12 * Copyright (C) 2012 mbed.org, MIT License
tass 5:445d2fc04784 13 *
tass 5:445d2fc04784 14 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
tass 5:445d2fc04784 15 * and associated documentation files (the "Software"), to deal in the Software without restriction,
tass 5:445d2fc04784 16 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
tass 5:445d2fc04784 17 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
tass 5:445d2fc04784 18 * furnished to do so, subject to the following conditions:
tass 5:445d2fc04784 19 *
tass 5:445d2fc04784 20 * The above copyright notice and this permission notice shall be included in all copies or
tass 5:445d2fc04784 21 * substantial portions of the Software.
tass 5:445d2fc04784 22 *
tass 5:445d2fc04784 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
tass 5:445d2fc04784 24 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
tass 5:445d2fc04784 25 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
tass 5:445d2fc04784 26 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
tass 5:445d2fc04784 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tass 5:445d2fc04784 28 */
tass 5:445d2fc04784 29 #include "TCPSocketConnection.h"
tass 5:445d2fc04784 30 #include "pico_bsd_layer.h"
tass 5:445d2fc04784 31 #include <cstring>
tass 5:445d2fc04784 32
tass 5:445d2fc04784 33 using std::memset;
tass 5:445d2fc04784 34 using std::memcpy;
tass 5:445d2fc04784 35
tass 5:445d2fc04784 36 TCPSocketConnection::TCPSocketConnection() :
tass 5:445d2fc04784 37 _is_connected(false) {
tass 5:445d2fc04784 38 }
tass 5:445d2fc04784 39
tass 5:445d2fc04784 40 int TCPSocketConnection::connect(const char* host, const int port) {
tass 5:445d2fc04784 41 if (init_socket(SOCK_STREAM) < 0)
tass 5:445d2fc04784 42 {
tass 5:445d2fc04784 43 printf("init_socket\n");
tass 5:445d2fc04784 44 return -1;
tass 5:445d2fc04784 45 }
tass 5:445d2fc04784 46
tass 5:445d2fc04784 47 if (set_address(host, port) != 0)
tass 5:445d2fc04784 48 {
tass 5:445d2fc04784 49 printf("set_address\n");
tass 5:445d2fc04784 50 return -1;
tass 5:445d2fc04784 51 }
tass 5:445d2fc04784 52
tass 5:445d2fc04784 53 if (picotcp_connect(_sock_fd, (struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
tass 5:445d2fc04784 54 close();
tass 5:445d2fc04784 55 return -1;
tass 5:445d2fc04784 56 }
tass 5:445d2fc04784 57 _is_connected = true;
tass 5:445d2fc04784 58
tass 5:445d2fc04784 59 return 0;
tass 5:445d2fc04784 60 }
tass 5:445d2fc04784 61
tass 5:445d2fc04784 62 bool TCPSocketConnection::is_connected(void) {
tass 5:445d2fc04784 63 return _is_connected;
tass 5:445d2fc04784 64 }
tass 5:445d2fc04784 65
tass 5:445d2fc04784 66 int TCPSocketConnection::send(char* data, int length) {
tass 5:445d2fc04784 67 if ((_sock_fd < 0) || !_is_connected)
tass 5:445d2fc04784 68 return -1;
tass 5:445d2fc04784 69
tass 5:445d2fc04784 70 if (!_blocking) {
tass 5:445d2fc04784 71 TimeInterval timeout(_timeout);
tass 5:445d2fc04784 72 if (wait_writable(timeout) != 0)
tass 5:445d2fc04784 73 {
tass 5:445d2fc04784 74 printf("Failed\n");
tass 5:445d2fc04784 75 return -1;
tass 5:445d2fc04784 76 }
tass 5:445d2fc04784 77 }
tass 5:445d2fc04784 78
daniele 11:58acd53df75c 79 int n = picotcp_write(_sock_fd, data, length);
tass 5:445d2fc04784 80 _is_connected = (picotcp_state(_sock_fd) == SOCK_CONNECTED);
tass 5:445d2fc04784 81
tass 5:445d2fc04784 82 return n;
tass 5:445d2fc04784 83 }
tass 5:445d2fc04784 84
tass 5:445d2fc04784 85 // -1 if unsuccessful, else number of bytes written
tass 5:445d2fc04784 86 int TCPSocketConnection::send_all(char* data, int length) {
tass 5:445d2fc04784 87 if ((_sock_fd < 0) || !_is_connected)
tass 5:445d2fc04784 88 return -1;
tass 5:445d2fc04784 89
tass 5:445d2fc04784 90 size_t writtenLen = 0;
tass 5:445d2fc04784 91 TimeInterval timeout(_timeout);
tass 5:445d2fc04784 92 while (writtenLen < length) {
tass 5:445d2fc04784 93 if (!_blocking) {
tass 5:445d2fc04784 94 // Wait for socket to be writeable
tass 5:445d2fc04784 95 if (wait_writable(timeout) != 0)
tass 5:445d2fc04784 96 return writtenLen;
tass 5:445d2fc04784 97 }
tass 5:445d2fc04784 98
daniele 11:58acd53df75c 99 int ret = picotcp_write(_sock_fd, data + writtenLen, length - writtenLen);
tass 5:445d2fc04784 100 if (ret > 0) {
tass 5:445d2fc04784 101 writtenLen += ret;
tass 5:445d2fc04784 102 continue;
tass 5:445d2fc04784 103 } else if (ret == 0) {
tass 5:445d2fc04784 104 _is_connected = (picotcp_state(_sock_fd) == SOCK_CONNECTED);
tass 5:445d2fc04784 105 return writtenLen;
tass 5:445d2fc04784 106 } else {
tass 5:445d2fc04784 107 return -1; //Connnection error
tass 5:445d2fc04784 108 }
tass 5:445d2fc04784 109 }
tass 5:445d2fc04784 110 return writtenLen;
tass 5:445d2fc04784 111 }
tass 5:445d2fc04784 112
tass 5:445d2fc04784 113 int TCPSocketConnection::receive(char* data, int length) {
tass 5:445d2fc04784 114 if ((_sock_fd < 0) || !_is_connected)
tass 5:445d2fc04784 115 return -1;
tass 5:445d2fc04784 116
tass 5:445d2fc04784 117 if (!_blocking) {
tass 5:445d2fc04784 118 TimeInterval timeout(_timeout);
tass 5:445d2fc04784 119 if (wait_readable(timeout) != 0)
tass 5:445d2fc04784 120 return -1;
tass 5:445d2fc04784 121 }
tass 5:445d2fc04784 122
daniele 11:58acd53df75c 123 int n = picotcp_read(_sock_fd, data, length);
tass 5:445d2fc04784 124 _is_connected = (picotcp_state(_sock_fd) == SOCK_CONNECTED);
tass 5:445d2fc04784 125
tass 5:445d2fc04784 126 return n;
tass 5:445d2fc04784 127 }
tass 5:445d2fc04784 128
tass 5:445d2fc04784 129 // -1 if unsuccessful, else number of bytes received
tass 5:445d2fc04784 130 int TCPSocketConnection::receive_all(char* data, int length) {
tass 5:445d2fc04784 131 if ((_sock_fd < 0) || !_is_connected)
tass 5:445d2fc04784 132 return -1;
tass 5:445d2fc04784 133
tass 5:445d2fc04784 134 size_t readLen = 0;
tass 5:445d2fc04784 135 TimeInterval timeout(_timeout);
tass 5:445d2fc04784 136 while (readLen < length) {
tass 5:445d2fc04784 137 if (!_blocking) {
tass 5:445d2fc04784 138 //Wait for socket to be readable
tass 5:445d2fc04784 139 if (wait_readable(timeout) != 0)
tass 5:445d2fc04784 140 return readLen;
tass 5:445d2fc04784 141 }
tass 5:445d2fc04784 142
daniele 11:58acd53df75c 143 int ret = picotcp_read(_sock_fd, data + readLen, length - readLen);
tass 5:445d2fc04784 144 if (ret > 0) {
tass 5:445d2fc04784 145 readLen += ret;
tass 5:445d2fc04784 146 } else if (ret == 0) {
tass 5:445d2fc04784 147 _is_connected = (picotcp_state(_sock_fd) == SOCK_CONNECTED);
tass 5:445d2fc04784 148 return readLen;
tass 5:445d2fc04784 149 } else {
tass 5:445d2fc04784 150 return -1; //Connnection error
tass 5:445d2fc04784 151 }
tass 5:445d2fc04784 152 }
tass 5:445d2fc04784 153 return readLen;
tass 5:445d2fc04784 154 }