Roy van Dam / NetworkAPI

Dependents:   NetRelais TCP_Client_Example TCP_Server_Example UDP_Server_Example ... more

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 }