Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: NetRelais TCP_Client_Example TCP_Server_Example UDP_Server_Example ... more
tcp/socket.cpp@8:cdee0f2b6ff0, 2012-09-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |