A new object oriented network api that can be used to replace the one provided by the EthernetInterface library.

Dependents:   NetRelais TCP_Client_Example TCP_Server_Example UDP_Server_Example ... more

Object oriented network interface for the mbed platform

Currently implemented:

  • Address
  • Endpoint
  • UDP Socket
  • TCP Socket
  • Databuffer
  • Select API

It depends on the EthernetInterface for the lwip network stack.

Please do not hesitate to contact me with any remarks, improvements or questions.

The API is also available for unix at GitHub: LibNosa

Examples

Committer:
NegativeBlack
Date:
Thu Sep 27 09:31:40 2012 +0000
Revision:
8:cdee0f2b6ff0
Parent:
4:d854fa394f85
Fixed binding to the new Ethernet LWIP api

Who changed what in which revision?

UserRevisionLine numberNew contents of line
NegativeBlack 3:d30db8752485 1 /**
NegativeBlack 3:d30db8752485 2 * Copyright (c) 2012, Roy van Dam <roy@vandam-innovations.com>
NegativeBlack 3:d30db8752485 3 * All rights reserved.
NegativeBlack 3:d30db8752485 4 *
NegativeBlack 3:d30db8752485 5 * Redistribution and use in source and binary forms, with or without
NegativeBlack 3:d30db8752485 6 * modification, are permitted provided that the following conditions are met:
NegativeBlack 3:d30db8752485 7 *
NegativeBlack 3:d30db8752485 8 * 1. Redistributions of source code must retain the above copyright notice, this
NegativeBlack 3:d30db8752485 9 * list of conditions and the following disclaimer.
NegativeBlack 3:d30db8752485 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
NegativeBlack 3:d30db8752485 11 * this list of conditions and the following disclaimer in the documentation
NegativeBlack 3:d30db8752485 12 * and/or other materials provided with the distribution.
NegativeBlack 3:d30db8752485 13 *
NegativeBlack 3:d30db8752485 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
NegativeBlack 3:d30db8752485 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
NegativeBlack 3:d30db8752485 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
NegativeBlack 3:d30db8752485 17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
NegativeBlack 3:d30db8752485 18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
NegativeBlack 3:d30db8752485 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
NegativeBlack 3:d30db8752485 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
NegativeBlack 3:d30db8752485 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
NegativeBlack 3:d30db8752485 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
NegativeBlack 3:d30db8752485 23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
NegativeBlack 3:d30db8752485 24 */
NegativeBlack 3:d30db8752485 25
NegativeBlack 3:d30db8752485 26 #include "socket.hpp"
NegativeBlack 3:d30db8752485 27 using namespace network::tcp;
NegativeBlack 3:d30db8752485 28
NegativeBlack 3:d30db8752485 29 int
NegativeBlack 3:d30db8752485 30 Socket::open()
NegativeBlack 3:d30db8752485 31 {
NegativeBlack 3:d30db8752485 32 // Check socket status
NegativeBlack 3:d30db8752485 33 if (this->_status != Socket::Closed) {
NegativeBlack 3:d30db8752485 34 return -1;
NegativeBlack 3:d30db8752485 35 }
NegativeBlack 3:d30db8752485 36
NegativeBlack 3:d30db8752485 37 // Open socket
NegativeBlack 8:cdee0f2b6ff0 38 this->_socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
NegativeBlack 3:d30db8752485 39 if (this->_socket < 0) {
NegativeBlack 4:d854fa394f85 40 return -2;
NegativeBlack 3:d30db8752485 41 }
NegativeBlack 3:d30db8752485 42
NegativeBlack 3:d30db8752485 43 // Update status and return
NegativeBlack 3:d30db8752485 44 this->_status = Socket::Open;
NegativeBlack 3:d30db8752485 45 return 0;
NegativeBlack 3:d30db8752485 46 }
NegativeBlack 3:d30db8752485 47
NegativeBlack 3:d30db8752485 48 int
NegativeBlack 4:d854fa394f85 49 Socket::connect(const char *hostname, int port)
NegativeBlack 4:d854fa394f85 50 {
NegativeBlack 4:d854fa394f85 51 ip::Address address;
NegativeBlack 4:d854fa394f85 52 if (address.fromHostname(hostname) < 0) {
NegativeBlack 4:d854fa394f85 53 return -1;
NegativeBlack 4:d854fa394f85 54 }
NegativeBlack 4:d854fa394f85 55
NegativeBlack 4:d854fa394f85 56 return this->connect(address, port);
NegativeBlack 4:d854fa394f85 57 }
NegativeBlack 4:d854fa394f85 58
NegativeBlack 4:d854fa394f85 59 int
NegativeBlack 4:d854fa394f85 60 Socket::connect(const std::string hostname, int port)
NegativeBlack 4:d854fa394f85 61 {
NegativeBlack 4:d854fa394f85 62 ip::Address address;
NegativeBlack 4:d854fa394f85 63 if (address.fromHostname(hostname) < 0) {
NegativeBlack 4:d854fa394f85 64 return -1;
NegativeBlack 4:d854fa394f85 65 }
NegativeBlack 4:d854fa394f85 66
NegativeBlack 4:d854fa394f85 67 return this->connect(address, port);
NegativeBlack 4:d854fa394f85 68 }
NegativeBlack 4:d854fa394f85 69
NegativeBlack 4:d854fa394f85 70 int
NegativeBlack 4:d854fa394f85 71 Socket::connect(const ip::Address &address, int port)
NegativeBlack 3:d30db8752485 72 {
NegativeBlack 3:d30db8752485 73 ip::Endpoint endpoint(address, port);
NegativeBlack 3:d30db8752485 74 return this->connect(endpoint);
NegativeBlack 3:d30db8752485 75 }
NegativeBlack 3:d30db8752485 76
NegativeBlack 3:d30db8752485 77 int
NegativeBlack 3:d30db8752485 78 Socket::connect(ip::Endpoint &endpoint)
NegativeBlack 3:d30db8752485 79 {
NegativeBlack 3:d30db8752485 80 // Check socket status
NegativeBlack 4:d854fa394f85 81 if ((this->_status != Socket::Open) &&
NegativeBlack 3:d30db8752485 82 (this->_status != Socket::Disconnected))
NegativeBlack 3:d30db8752485 83 {
NegativeBlack 3:d30db8752485 84 return -1;
NegativeBlack 3:d30db8752485 85 }
NegativeBlack 3:d30db8752485 86
NegativeBlack 3:d30db8752485 87 // Create native endpoint
NegativeBlack 3:d30db8752485 88 struct sockaddr_in native_endpoint;
NegativeBlack 3:d30db8752485 89 endpoint.toNative(&native_endpoint);
NegativeBlack 3:d30db8752485 90
NegativeBlack 3:d30db8752485 91 // Attempt to connect with remote endpoint.
NegativeBlack 8:cdee0f2b6ff0 92 int result = lwip_connect(this->_socket,
NegativeBlack 3:d30db8752485 93 (const struct sockaddr *)&native_endpoint, sizeof(native_endpoint));
NegativeBlack 3:d30db8752485 94
NegativeBlack 3:d30db8752485 95 // Check result
NegativeBlack 3:d30db8752485 96 if (result < 0) {
NegativeBlack 4:d854fa394f85 97 return -2;
NegativeBlack 3:d30db8752485 98 }
NegativeBlack 3:d30db8752485 99
NegativeBlack 3:d30db8752485 100 // Update remote endpoint information.
NegativeBlack 3:d30db8752485 101 this->_remote_endpoint = endpoint;
NegativeBlack 3:d30db8752485 102
NegativeBlack 3:d30db8752485 103 // Update status and return
NegativeBlack 3:d30db8752485 104 this->_status = Socket::Connected;
NegativeBlack 3:d30db8752485 105 return 0;
NegativeBlack 3:d30db8752485 106 }
NegativeBlack 3:d30db8752485 107
NegativeBlack 3:d30db8752485 108 int
NegativeBlack 3:d30db8752485 109 Socket::shutdown()
NegativeBlack 3:d30db8752485 110 {
NegativeBlack 3:d30db8752485 111 // Check socket status
NegativeBlack 3:d30db8752485 112 if (this->_status != Socket::Connected) {
NegativeBlack 3:d30db8752485 113 return -1;
NegativeBlack 3:d30db8752485 114 }
NegativeBlack 3:d30db8752485 115
NegativeBlack 3:d30db8752485 116 // Attempt to shutdown the connection.
NegativeBlack 8:cdee0f2b6ff0 117 int result = lwip_shutdown(this->_socket, SHUT_RDWR);
NegativeBlack 3:d30db8752485 118 if (result < 0) {
NegativeBlack 4:d854fa394f85 119 return -2;
NegativeBlack 3:d30db8752485 120 }
NegativeBlack 3:d30db8752485 121
NegativeBlack 3:d30db8752485 122 // Update status and return
NegativeBlack 3:d30db8752485 123 this->_status = Socket::Disconnected;
NegativeBlack 3:d30db8752485 124 return 0;
NegativeBlack 3:d30db8752485 125 }
NegativeBlack 3:d30db8752485 126
NegativeBlack 3:d30db8752485 127 int
NegativeBlack 3:d30db8752485 128 Socket::listen(int max_pending)
NegativeBlack 3:d30db8752485 129 {
NegativeBlack 3:d30db8752485 130 // Check socket status
NegativeBlack 3:d30db8752485 131 if (this->_status != Socket::Open) {
NegativeBlack 3:d30db8752485 132 return -1;
NegativeBlack 3:d30db8752485 133 }
NegativeBlack 3:d30db8752485 134
NegativeBlack 3:d30db8752485 135 // Put socket into listening mode.
NegativeBlack 8:cdee0f2b6ff0 136 int result = lwip_listen(this->_socket, max_pending);
NegativeBlack 3:d30db8752485 137 if (result < 0) {
NegativeBlack 4:d854fa394f85 138 return -2;
NegativeBlack 3:d30db8752485 139 }
NegativeBlack 3:d30db8752485 140
NegativeBlack 3:d30db8752485 141 // Update status and return
NegativeBlack 3:d30db8752485 142 this->_status = Socket::Listening;
NegativeBlack 3:d30db8752485 143 return 0;
NegativeBlack 3:d30db8752485 144 }
NegativeBlack 3:d30db8752485 145
NegativeBlack 3:d30db8752485 146 int
NegativeBlack 3:d30db8752485 147 Socket::accept(Socket &client)
NegativeBlack 3:d30db8752485 148 {
NegativeBlack 3:d30db8752485 149 // Check socket status
NegativeBlack 3:d30db8752485 150 if (this->_status != Socket::Listening) {
NegativeBlack 3:d30db8752485 151 return -1;
NegativeBlack 3:d30db8752485 152 }
NegativeBlack 3:d30db8752485 153
NegativeBlack 3:d30db8752485 154 // Check client socket status
NegativeBlack 3:d30db8752485 155 if (client._status != Socket::Closed) {
NegativeBlack 4:d854fa394f85 156 return -2;
NegativeBlack 3:d30db8752485 157 }
NegativeBlack 3:d30db8752485 158
NegativeBlack 3:d30db8752485 159 // Create native endpoint
NegativeBlack 3:d30db8752485 160 struct sockaddr_in native_endpoint;
NegativeBlack 3:d30db8752485 161 int native_endpoint_size = sizeof(native_endpoint);
NegativeBlack 3:d30db8752485 162 std::memset(&native_endpoint, 0, sizeof(native_endpoint));
NegativeBlack 3:d30db8752485 163
NegativeBlack 3:d30db8752485 164 // Accept new (pending) connections.
NegativeBlack 8:cdee0f2b6ff0 165 int socket = lwip_accept(this->_socket,
NegativeBlack 3:d30db8752485 166 (struct sockaddr*)&native_endpoint, (u32_t *)&native_endpoint_size);
NegativeBlack 3:d30db8752485 167
NegativeBlack 3:d30db8752485 168 // Did we succeed?
NegativeBlack 3:d30db8752485 169 if (socket < 0) {
NegativeBlack 4:d854fa394f85 170 return -3;
NegativeBlack 3:d30db8752485 171 }
NegativeBlack 3:d30db8752485 172
NegativeBlack 3:d30db8752485 173 // Check if we received the endpoint information correctly.
NegativeBlack 3:d30db8752485 174 if (native_endpoint_size != sizeof(native_endpoint)) {
NegativeBlack 3:d30db8752485 175 printf("Warning: invalid endpoint size received\n\r");
NegativeBlack 3:d30db8752485 176 }
NegativeBlack 3:d30db8752485 177
NegativeBlack 3:d30db8752485 178 // Populate client socket
NegativeBlack 3:d30db8752485 179 client._socket = socket;
NegativeBlack 3:d30db8752485 180 client._status = Socket::Connected;
NegativeBlack 3:d30db8752485 181 client._remote_endpoint.fromNative(&native_endpoint);
NegativeBlack 3:d30db8752485 182
NegativeBlack 3:d30db8752485 183 return 0;
NegativeBlack 3:d30db8752485 184 }
NegativeBlack 3:d30db8752485 185
NegativeBlack 3:d30db8752485 186 int
NegativeBlack 4:d854fa394f85 187 Socket::write(Buffer &buffer)
NegativeBlack 4:d854fa394f85 188 {
NegativeBlack 8:cdee0f2b6ff0 189 return this->write(buffer.data(), buffer.length());
NegativeBlack 4:d854fa394f85 190 }
NegativeBlack 4:d854fa394f85 191
NegativeBlack 4:d854fa394f85 192 int
NegativeBlack 3:d30db8752485 193 Socket::write(void *data, size_t size)
NegativeBlack 3:d30db8752485 194 {
NegativeBlack 3:d30db8752485 195 // Check data buffer and size
NegativeBlack 3:d30db8752485 196 if (data == NULL || size == 0) {
NegativeBlack 3:d30db8752485 197 return -1;
NegativeBlack 3:d30db8752485 198 }
NegativeBlack 3:d30db8752485 199
NegativeBlack 3:d30db8752485 200 // Check socket status
NegativeBlack 3:d30db8752485 201 if (this->_status != Socket::Connected) {
NegativeBlack 4:d854fa394f85 202 return -2;
NegativeBlack 3:d30db8752485 203 }
NegativeBlack 3:d30db8752485 204
NegativeBlack 3:d30db8752485 205 // Update status
NegativeBlack 3:d30db8752485 206 this->_status = Socket::Sending;
NegativeBlack 3:d30db8752485 207
NegativeBlack 3:d30db8752485 208 // Try to send the specified amount of bytes.
NegativeBlack 8:cdee0f2b6ff0 209 int bytes_written = lwip_send(this->_socket, data, size, 0);
NegativeBlack 3:d30db8752485 210
NegativeBlack 3:d30db8752485 211 // Update status
NegativeBlack 3:d30db8752485 212 this->_status = (bytes_written == 0)
NegativeBlack 3:d30db8752485 213 ? Socket::Disconnected
NegativeBlack 3:d30db8752485 214 : Socket::Connected;
NegativeBlack 3:d30db8752485 215
NegativeBlack 3:d30db8752485 216 // Return the result.
NegativeBlack 3:d30db8752485 217 return bytes_written;
NegativeBlack 3:d30db8752485 218 }
NegativeBlack 3:d30db8752485 219
NegativeBlack 4:d854fa394f85 220 int
NegativeBlack 4:d854fa394f85 221 Socket::read(Buffer &buffer)
NegativeBlack 4:d854fa394f85 222 {
NegativeBlack 8:cdee0f2b6ff0 223 int result = this->read(buffer.data(), buffer.size());
NegativeBlack 4:d854fa394f85 224 if (result >= 0) {
NegativeBlack 8:cdee0f2b6ff0 225 buffer.length(result);
NegativeBlack 4:d854fa394f85 226 }
NegativeBlack 4:d854fa394f85 227
NegativeBlack 4:d854fa394f85 228 return result;
NegativeBlack 4:d854fa394f85 229 }
NegativeBlack 3:d30db8752485 230
NegativeBlack 3:d30db8752485 231 int
NegativeBlack 3:d30db8752485 232 Socket::read(void *data, size_t max_size)
NegativeBlack 3:d30db8752485 233 {
NegativeBlack 3:d30db8752485 234 // Check data buffer and size
NegativeBlack 3:d30db8752485 235 if (data == NULL || max_size == 0) {
NegativeBlack 3:d30db8752485 236 return -1;
NegativeBlack 3:d30db8752485 237 }
NegativeBlack 3:d30db8752485 238
NegativeBlack 3:d30db8752485 239 // Check socket status
NegativeBlack 3:d30db8752485 240 if (this->_status != Socket::Connected) {
NegativeBlack 4:d854fa394f85 241 return -2;
NegativeBlack 3:d30db8752485 242 }
NegativeBlack 3:d30db8752485 243
NegativeBlack 3:d30db8752485 244 // Update status
NegativeBlack 3:d30db8752485 245 this->_status = Socket::Receiving;
NegativeBlack 3:d30db8752485 246
NegativeBlack 3:d30db8752485 247 // Try to read data from the socket.
NegativeBlack 8:cdee0f2b6ff0 248 int bytes_read = lwip_recv(this->_socket, data, max_size, 0);
NegativeBlack 3:d30db8752485 249
NegativeBlack 3:d30db8752485 250 // Update status
NegativeBlack 3:d30db8752485 251 this->_status = (bytes_read == 0)
NegativeBlack 3:d30db8752485 252 ? Socket::Disconnected
NegativeBlack 3:d30db8752485 253 : Socket::Connected;
NegativeBlack 3:d30db8752485 254
NegativeBlack 3:d30db8752485 255 // Return bytes read
NegativeBlack 3:d30db8752485 256 return bytes_read;
NegativeBlack 3:d30db8752485 257 }