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:
Wed Jul 18 11:22:37 2012 +0000
Revision:
3:d30db8752485
Parent:
0:00d5bc4b46e1
Child:
4:d854fa394f85
Implemented UDP and TCP socket. UDP is fully tested, TCP still needs to be tested.

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 3:d30db8752485 38 this->_socket = ::socket(AF_INET, SOCK_STREAM, 0);
NegativeBlack 3:d30db8752485 39 if (this->_socket < 0) {
NegativeBlack 3:d30db8752485 40 return -1;
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 3:d30db8752485 49 Socket::connect(ip::Address &address, int port)
NegativeBlack 3:d30db8752485 50 {
NegativeBlack 3:d30db8752485 51 ip::Endpoint endpoint(address, port);
NegativeBlack 3:d30db8752485 52 return this->connect(endpoint);
NegativeBlack 3:d30db8752485 53 }
NegativeBlack 3:d30db8752485 54
NegativeBlack 3:d30db8752485 55 int
NegativeBlack 3:d30db8752485 56 Socket::connect(ip::Endpoint &endpoint)
NegativeBlack 3:d30db8752485 57 {
NegativeBlack 3:d30db8752485 58 // Check socket status
NegativeBlack 3:d30db8752485 59 if ((this->_status != Socket::Open) ||
NegativeBlack 3:d30db8752485 60 (this->_status != Socket::Disconnected))
NegativeBlack 3:d30db8752485 61 {
NegativeBlack 3:d30db8752485 62 return -1;
NegativeBlack 3:d30db8752485 63 }
NegativeBlack 3:d30db8752485 64
NegativeBlack 3:d30db8752485 65 // Create native endpoint
NegativeBlack 3:d30db8752485 66 struct sockaddr_in native_endpoint;
NegativeBlack 3:d30db8752485 67 endpoint.toNative(&native_endpoint);
NegativeBlack 3:d30db8752485 68
NegativeBlack 3:d30db8752485 69 // Attempt to connect with remote endpoint.
NegativeBlack 3:d30db8752485 70 int result = ::connect(this->_socket,
NegativeBlack 3:d30db8752485 71 (const struct sockaddr *)&native_endpoint, sizeof(native_endpoint));
NegativeBlack 3:d30db8752485 72
NegativeBlack 3:d30db8752485 73 // Check result
NegativeBlack 3:d30db8752485 74 if (result < 0) {
NegativeBlack 3:d30db8752485 75 return -1;
NegativeBlack 3:d30db8752485 76 }
NegativeBlack 3:d30db8752485 77
NegativeBlack 3:d30db8752485 78 // Update remote endpoint information.
NegativeBlack 3:d30db8752485 79 this->_remote_endpoint = endpoint;
NegativeBlack 3:d30db8752485 80
NegativeBlack 3:d30db8752485 81 // Update status and return
NegativeBlack 3:d30db8752485 82 this->_status = Socket::Connected;
NegativeBlack 3:d30db8752485 83 return 0;
NegativeBlack 3:d30db8752485 84 }
NegativeBlack 3:d30db8752485 85
NegativeBlack 3:d30db8752485 86 int
NegativeBlack 3:d30db8752485 87 Socket::shutdown()
NegativeBlack 3:d30db8752485 88 {
NegativeBlack 3:d30db8752485 89 // Check socket status
NegativeBlack 3:d30db8752485 90 if (this->_status != Socket::Connected) {
NegativeBlack 3:d30db8752485 91 return -1;
NegativeBlack 3:d30db8752485 92 }
NegativeBlack 3:d30db8752485 93
NegativeBlack 3:d30db8752485 94 // Attempt to shutdown the connection.
NegativeBlack 3:d30db8752485 95 int result = ::shutdown(this->_socket, SHUT_RDWR);
NegativeBlack 3:d30db8752485 96 if (result < 0) {
NegativeBlack 3:d30db8752485 97 return -1;
NegativeBlack 3:d30db8752485 98 }
NegativeBlack 3:d30db8752485 99
NegativeBlack 3:d30db8752485 100 // Update status and return
NegativeBlack 3:d30db8752485 101 this->_status = Socket::Disconnected;
NegativeBlack 3:d30db8752485 102 return 0;
NegativeBlack 3:d30db8752485 103 }
NegativeBlack 3:d30db8752485 104
NegativeBlack 3:d30db8752485 105 int
NegativeBlack 3:d30db8752485 106 Socket::listen(int max_pending)
NegativeBlack 3:d30db8752485 107 {
NegativeBlack 3:d30db8752485 108 // Check socket status
NegativeBlack 3:d30db8752485 109 if (this->_status != Socket::Open) {
NegativeBlack 3:d30db8752485 110 return -1;
NegativeBlack 3:d30db8752485 111 }
NegativeBlack 3:d30db8752485 112
NegativeBlack 3:d30db8752485 113 // Put socket into listening mode.
NegativeBlack 3:d30db8752485 114 int result = ::listen(this->_socket, max_pending);
NegativeBlack 3:d30db8752485 115 if (result < 0) {
NegativeBlack 3:d30db8752485 116 return -1;
NegativeBlack 3:d30db8752485 117 }
NegativeBlack 3:d30db8752485 118
NegativeBlack 3:d30db8752485 119 // Update status and return
NegativeBlack 3:d30db8752485 120 this->_status = Socket::Listening;
NegativeBlack 3:d30db8752485 121 return 0;
NegativeBlack 3:d30db8752485 122 }
NegativeBlack 3:d30db8752485 123
NegativeBlack 3:d30db8752485 124 int
NegativeBlack 3:d30db8752485 125 Socket::accept(Socket &client)
NegativeBlack 3:d30db8752485 126 {
NegativeBlack 3:d30db8752485 127 // Check socket status
NegativeBlack 3:d30db8752485 128 if (this->_status != Socket::Listening) {
NegativeBlack 3:d30db8752485 129 return -1;
NegativeBlack 3:d30db8752485 130 }
NegativeBlack 3:d30db8752485 131
NegativeBlack 3:d30db8752485 132 // Check client socket status
NegativeBlack 3:d30db8752485 133 if (client._status != Socket::Closed) {
NegativeBlack 3:d30db8752485 134 return -1;
NegativeBlack 3:d30db8752485 135 }
NegativeBlack 3:d30db8752485 136
NegativeBlack 3:d30db8752485 137 // Create native endpoint
NegativeBlack 3:d30db8752485 138 struct sockaddr_in native_endpoint;
NegativeBlack 3:d30db8752485 139 int native_endpoint_size = sizeof(native_endpoint);
NegativeBlack 3:d30db8752485 140 std::memset(&native_endpoint, 0, sizeof(native_endpoint));
NegativeBlack 3:d30db8752485 141
NegativeBlack 3:d30db8752485 142 // Accept new (pending) connections.
NegativeBlack 3:d30db8752485 143 int socket = ::accept(this->_socket,
NegativeBlack 3:d30db8752485 144 (struct sockaddr*)&native_endpoint, (u32_t *)&native_endpoint_size);
NegativeBlack 3:d30db8752485 145
NegativeBlack 3:d30db8752485 146 // Did we succeed?
NegativeBlack 3:d30db8752485 147 if (socket < 0) {
NegativeBlack 3:d30db8752485 148 return -1;
NegativeBlack 3:d30db8752485 149 }
NegativeBlack 3:d30db8752485 150
NegativeBlack 3:d30db8752485 151 // Check if we received the endpoint information correctly.
NegativeBlack 3:d30db8752485 152 if (native_endpoint_size != sizeof(native_endpoint)) {
NegativeBlack 3:d30db8752485 153 printf("Warning: invalid endpoint size received\n\r");
NegativeBlack 3:d30db8752485 154 }
NegativeBlack 3:d30db8752485 155
NegativeBlack 3:d30db8752485 156 // Populate client socket
NegativeBlack 3:d30db8752485 157 client._socket = socket;
NegativeBlack 3:d30db8752485 158 client._status = Socket::Connected;
NegativeBlack 3:d30db8752485 159 client._remote_endpoint.fromNative(&native_endpoint);
NegativeBlack 3:d30db8752485 160
NegativeBlack 3:d30db8752485 161 return 0;
NegativeBlack 3:d30db8752485 162 }
NegativeBlack 3:d30db8752485 163
NegativeBlack 3:d30db8752485 164 int
NegativeBlack 3:d30db8752485 165 Socket::write(void *data, size_t size)
NegativeBlack 3:d30db8752485 166 {
NegativeBlack 3:d30db8752485 167 // Check data buffer and size
NegativeBlack 3:d30db8752485 168 if (data == NULL || size == 0) {
NegativeBlack 3:d30db8752485 169 return -1;
NegativeBlack 3:d30db8752485 170 }
NegativeBlack 3:d30db8752485 171
NegativeBlack 3:d30db8752485 172 // Check socket status
NegativeBlack 3:d30db8752485 173 if (this->_status != Socket::Connected) {
NegativeBlack 3:d30db8752485 174 return -1;
NegativeBlack 3:d30db8752485 175 }
NegativeBlack 3:d30db8752485 176
NegativeBlack 3:d30db8752485 177 // Update status
NegativeBlack 3:d30db8752485 178 this->_status = Socket::Sending;
NegativeBlack 3:d30db8752485 179
NegativeBlack 3:d30db8752485 180 // Try to send the specified amount of bytes.
NegativeBlack 3:d30db8752485 181 int bytes_written = ::send(this->_socket, data, size, 0);
NegativeBlack 3:d30db8752485 182
NegativeBlack 3:d30db8752485 183 // Update status
NegativeBlack 3:d30db8752485 184 this->_status = (bytes_written == 0)
NegativeBlack 3:d30db8752485 185 ? Socket::Disconnected
NegativeBlack 3:d30db8752485 186 : Socket::Connected;
NegativeBlack 3:d30db8752485 187
NegativeBlack 3:d30db8752485 188 // Return the result.
NegativeBlack 3:d30db8752485 189 return bytes_written;
NegativeBlack 3:d30db8752485 190 }
NegativeBlack 3:d30db8752485 191
NegativeBlack 3:d30db8752485 192
NegativeBlack 3:d30db8752485 193 int
NegativeBlack 3:d30db8752485 194 Socket::read(void *data, size_t max_size)
NegativeBlack 3:d30db8752485 195 {
NegativeBlack 3:d30db8752485 196 // Check data buffer and size
NegativeBlack 3:d30db8752485 197 if (data == NULL || max_size == 0) {
NegativeBlack 3:d30db8752485 198 return -1;
NegativeBlack 3:d30db8752485 199 }
NegativeBlack 3:d30db8752485 200
NegativeBlack 3:d30db8752485 201 // Check socket status
NegativeBlack 3:d30db8752485 202 if (this->_status != Socket::Connected) {
NegativeBlack 3:d30db8752485 203 return -1;
NegativeBlack 3:d30db8752485 204 }
NegativeBlack 3:d30db8752485 205
NegativeBlack 3:d30db8752485 206 // Update status
NegativeBlack 3:d30db8752485 207 this->_status = Socket::Receiving;
NegativeBlack 3:d30db8752485 208
NegativeBlack 3:d30db8752485 209 // Try to read data from the socket.
NegativeBlack 3:d30db8752485 210 int bytes_read = ::recv(this->_socket, data, max_size, 0);
NegativeBlack 3:d30db8752485 211
NegativeBlack 3:d30db8752485 212 // Update status
NegativeBlack 3:d30db8752485 213 this->_status = (bytes_read == 0)
NegativeBlack 3:d30db8752485 214 ? Socket::Disconnected
NegativeBlack 3:d30db8752485 215 : Socket::Connected;
NegativeBlack 3:d30db8752485 216
NegativeBlack 3:d30db8752485 217 // Return bytes read
NegativeBlack 3:d30db8752485 218 return bytes_read;
NegativeBlack 3:d30db8752485 219 }