Implementation of the NetworkSocketAPI for LWIP
Dependencies: lwip-eth lwip-sys lwip
Dependents: HelloLWIPInterface HelloLWIPInterfaceNonBlocking LWIPInterfaceTests SimpleHTTPExample ... more
LWIPInterface.cpp@12:899403b675fe, 2016-04-05 (annotated)
- Committer:
- geky
- Date:
- Tue Apr 05 19:20:42 2016 +0000
- Revision:
- 12:899403b675fe
- Parent:
- 11:82796df87b0a
- Child:
- 13:57d9e1721826
Added compilable pieces
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
geky | 1:2fbcfc9c12dd | 1 | /* LWIP implementation of NetworkInterfaceAPI |
geky | 1:2fbcfc9c12dd | 2 | * Copyright (c) 2015 ARM Limited |
geky | 1:2fbcfc9c12dd | 3 | * |
geky | 1:2fbcfc9c12dd | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
geky | 1:2fbcfc9c12dd | 5 | * you may not use this file except in compliance with the License. |
geky | 1:2fbcfc9c12dd | 6 | * You may obtain a copy of the License at |
geky | 1:2fbcfc9c12dd | 7 | * |
geky | 1:2fbcfc9c12dd | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
geky | 1:2fbcfc9c12dd | 9 | * |
geky | 1:2fbcfc9c12dd | 10 | * Unless required by applicable law or agreed to in writing, software |
geky | 1:2fbcfc9c12dd | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
geky | 1:2fbcfc9c12dd | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
geky | 1:2fbcfc9c12dd | 13 | * See the License for the specific language governing permissions and |
geky | 1:2fbcfc9c12dd | 14 | * limitations under the License. |
geky | 1:2fbcfc9c12dd | 15 | */ |
sam_grove | 8:cef01e812975 | 16 | |
Christopher Haster |
2:7fb7e78cb17f | 17 | #include "LWIPInterface.h" |
Christopher Haster |
2:7fb7e78cb17f | 18 | |
Christopher Haster |
2:7fb7e78cb17f | 19 | #include "mbed.h" |
Christopher Haster |
2:7fb7e78cb17f | 20 | #include "lwip/inet.h" |
Christopher Haster |
2:7fb7e78cb17f | 21 | #include "lwip/netif.h" |
Christopher Haster |
2:7fb7e78cb17f | 22 | #include "lwip/dhcp.h" |
Christopher Haster |
2:7fb7e78cb17f | 23 | #include "lwip/tcpip.h" |
Christopher Haster |
2:7fb7e78cb17f | 24 | #include "lwip/sockets.h" |
Christopher Haster |
2:7fb7e78cb17f | 25 | #include "lwip/netdb.h" |
Christopher Haster |
2:7fb7e78cb17f | 26 | #include "netif/etharp.h" |
Christopher Haster |
2:7fb7e78cb17f | 27 | #include "eth_arch.h" |
Christopher Haster |
2:7fb7e78cb17f | 28 | |
geky | 12:899403b675fe | 29 | #if 0 |
Christopher Haster |
2:7fb7e78cb17f | 30 | /* TCP/IP and Network Interface Initialisation */ |
Christopher Haster |
2:7fb7e78cb17f | 31 | static struct netif netif; |
Christopher Haster |
2:7fb7e78cb17f | 32 | |
geky | 5:2c7d2186543c | 33 | static char ip_addr[NS_IP_SIZE] = "\0"; |
Christopher Haster |
2:7fb7e78cb17f | 34 | static char mac_addr[NS_MAC_SIZE] = "\0"; |
Christopher Haster |
2:7fb7e78cb17f | 35 | |
Christopher Haster |
2:7fb7e78cb17f | 36 | static Semaphore tcpip_inited(0); |
Christopher Haster |
2:7fb7e78cb17f | 37 | static Semaphore netif_linked(0); |
Christopher Haster |
2:7fb7e78cb17f | 38 | static Semaphore netif_up(0); |
Christopher Haster |
2:7fb7e78cb17f | 39 | |
sam_grove | 8:cef01e812975 | 40 | static void tcpip_init_done(void *) |
sam_grove | 8:cef01e812975 | 41 | { |
Christopher Haster |
2:7fb7e78cb17f | 42 | tcpip_inited.release(); |
Christopher Haster |
2:7fb7e78cb17f | 43 | } |
Christopher Haster |
2:7fb7e78cb17f | 44 | |
sam_grove | 8:cef01e812975 | 45 | static void netif_link_callback(struct netif *netif) |
sam_grove | 8:cef01e812975 | 46 | { |
Christopher Haster |
2:7fb7e78cb17f | 47 | if (netif_is_link_up(netif)) { |
Christopher Haster |
2:7fb7e78cb17f | 48 | netif_linked.release(); |
Christopher Haster |
2:7fb7e78cb17f | 49 | } |
Christopher Haster |
2:7fb7e78cb17f | 50 | } |
Christopher Haster |
2:7fb7e78cb17f | 51 | |
sam_grove | 8:cef01e812975 | 52 | static void netif_status_callback(struct netif *netif) |
sam_grove | 8:cef01e812975 | 53 | { |
Christopher Haster |
2:7fb7e78cb17f | 54 | if (netif_is_up(netif)) { |
geky | 5:2c7d2186543c | 55 | strcpy(ip_addr, inet_ntoa(netif->ip_addr)); |
Christopher Haster |
2:7fb7e78cb17f | 56 | netif_up.release(); |
Christopher Haster |
2:7fb7e78cb17f | 57 | } |
Christopher Haster |
2:7fb7e78cb17f | 58 | } |
Christopher Haster |
2:7fb7e78cb17f | 59 | |
sam_grove | 8:cef01e812975 | 60 | static void init_netif(ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw) |
sam_grove | 8:cef01e812975 | 61 | { |
Christopher Haster |
2:7fb7e78cb17f | 62 | tcpip_init(tcpip_init_done, NULL); |
Christopher Haster |
2:7fb7e78cb17f | 63 | tcpip_inited.wait(); |
sam_grove | 8:cef01e812975 | 64 | |
Christopher Haster |
2:7fb7e78cb17f | 65 | memset((void*) &netif, 0, sizeof(netif)); |
Christopher Haster |
2:7fb7e78cb17f | 66 | netif_add(&netif, ipaddr, netmask, gw, NULL, eth_arch_enetif_init, tcpip_input); |
Christopher Haster |
2:7fb7e78cb17f | 67 | netif_set_default(&netif); |
sam_grove | 8:cef01e812975 | 68 | |
Christopher Haster |
2:7fb7e78cb17f | 69 | netif_set_link_callback (&netif, netif_link_callback); |
Christopher Haster |
2:7fb7e78cb17f | 70 | netif_set_status_callback(&netif, netif_status_callback); |
Christopher Haster |
2:7fb7e78cb17f | 71 | } |
Christopher Haster |
2:7fb7e78cb17f | 72 | |
sam_grove | 8:cef01e812975 | 73 | static void set_mac_address(void) |
sam_grove | 8:cef01e812975 | 74 | { |
Christopher Haster |
2:7fb7e78cb17f | 75 | #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) |
Christopher Haster |
2:7fb7e78cb17f | 76 | snprintf(mac_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x", MBED_MAC_ADDR_0, MBED_MAC_ADDR_1, MBED_MAC_ADDR_2, |
Christopher Haster |
2:7fb7e78cb17f | 77 | MBED_MAC_ADDR_3, MBED_MAC_ADDR_4, MBED_MAC_ADDR_5); |
Christopher Haster |
2:7fb7e78cb17f | 78 | #else |
Christopher Haster |
2:7fb7e78cb17f | 79 | char mac[6]; |
Christopher Haster |
2:7fb7e78cb17f | 80 | mbed_mac_address(mac); |
Christopher Haster |
2:7fb7e78cb17f | 81 | snprintf(mac_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
Christopher Haster |
2:7fb7e78cb17f | 82 | #endif |
Christopher Haster |
2:7fb7e78cb17f | 83 | } |
Christopher Haster |
2:7fb7e78cb17f | 84 | |
geky | 12:899403b675fe | 85 | #if 0 |
Christopher Haster |
2:7fb7e78cb17f | 86 | // LWIPInterface implementation |
Christopher Haster |
2:7fb7e78cb17f | 87 | int32_t LWIPInterface::connect() |
Christopher Haster |
2:7fb7e78cb17f | 88 | { |
Christopher Haster |
2:7fb7e78cb17f | 89 | // Set up network |
Christopher Haster |
2:7fb7e78cb17f | 90 | set_mac_address(); |
geky | 5:2c7d2186543c | 91 | init_netif(0, 0, 0); |
Christopher Haster |
2:7fb7e78cb17f | 92 | |
Christopher Haster |
2:7fb7e78cb17f | 93 | // Connect to network |
Christopher Haster |
2:7fb7e78cb17f | 94 | eth_arch_enable_interrupts(); |
Christopher Haster |
2:7fb7e78cb17f | 95 | |
geky | 5:2c7d2186543c | 96 | dhcp_start(&netif); |
sam_grove | 8:cef01e812975 | 97 | |
geky | 5:2c7d2186543c | 98 | // Wait for an IP Address |
geky | 5:2c7d2186543c | 99 | // -1: error, 0: timeout |
geky | 5:2c7d2186543c | 100 | if (netif_up.wait(LWIP_TIMEOUT) < 0) { |
geky | 5:2c7d2186543c | 101 | return NS_ERROR_TIMEOUT; |
Christopher Haster |
2:7fb7e78cb17f | 102 | } |
Christopher Haster |
2:7fb7e78cb17f | 103 | |
Christopher Haster |
2:7fb7e78cb17f | 104 | return 0; |
Christopher Haster |
2:7fb7e78cb17f | 105 | } |
Christopher Haster |
2:7fb7e78cb17f | 106 | |
Christopher Haster |
2:7fb7e78cb17f | 107 | int32_t LWIPInterface::disconnect() |
Christopher Haster |
2:7fb7e78cb17f | 108 | { |
geky | 5:2c7d2186543c | 109 | dhcp_release(&netif); |
geky | 5:2c7d2186543c | 110 | dhcp_stop(&netif); |
sam_grove | 8:cef01e812975 | 111 | |
Christopher Haster |
2:7fb7e78cb17f | 112 | eth_arch_disable_interrupts(); |
sam_grove | 8:cef01e812975 | 113 | |
Christopher Haster |
2:7fb7e78cb17f | 114 | return 0; |
Christopher Haster |
2:7fb7e78cb17f | 115 | } |
Christopher Haster |
2:7fb7e78cb17f | 116 | |
geky | 5:2c7d2186543c | 117 | const char *LWIPInterface::getIPAddress() |
geky | 5:2c7d2186543c | 118 | { |
geky | 5:2c7d2186543c | 119 | return ip_addr; |
geky | 5:2c7d2186543c | 120 | } |
geky | 5:2c7d2186543c | 121 | |
sam_grove | 8:cef01e812975 | 122 | const char *LWIPInterface::getMACAddress() |
Christopher Haster |
2:7fb7e78cb17f | 123 | { |
Christopher Haster |
2:7fb7e78cb17f | 124 | return mac_addr; |
Christopher Haster |
2:7fb7e78cb17f | 125 | } |
Christopher Haster |
2:7fb7e78cb17f | 126 | |
geky | 3:774869068511 | 127 | SocketInterface *LWIPInterface::createSocket(ns_protocol_t proto) |
Christopher Haster |
2:7fb7e78cb17f | 128 | { |
geky | 3:774869068511 | 129 | int type = (proto == NS_UDP) ? SOCK_DGRAM : SOCK_STREAM; |
Christopher Haster |
2:7fb7e78cb17f | 130 | int fd = lwip_socket(AF_INET, type, 0); |
Christopher Haster |
2:7fb7e78cb17f | 131 | if (fd < 0) { |
Christopher Haster |
2:7fb7e78cb17f | 132 | return 0; |
Christopher Haster |
2:7fb7e78cb17f | 133 | } |
Christopher Haster |
2:7fb7e78cb17f | 134 | |
Christopher Haster |
2:7fb7e78cb17f | 135 | return new LWIPSocket(fd); |
Christopher Haster |
2:7fb7e78cb17f | 136 | } |
Christopher Haster |
2:7fb7e78cb17f | 137 | |
Christopher Haster |
2:7fb7e78cb17f | 138 | void LWIPInterface::destroySocket(SocketInterface *siface) |
Christopher Haster |
2:7fb7e78cb17f | 139 | { |
Christopher Haster |
2:7fb7e78cb17f | 140 | LWIPSocket *socket = (LWIPSocket *)siface; |
Christopher Haster |
2:7fb7e78cb17f | 141 | lwip_close(socket->fd); |
Christopher Haster |
2:7fb7e78cb17f | 142 | |
Christopher Haster |
2:7fb7e78cb17f | 143 | delete socket; |
Christopher Haster |
2:7fb7e78cb17f | 144 | } |
Christopher Haster |
2:7fb7e78cb17f | 145 | |
Christopher Haster |
2:7fb7e78cb17f | 146 | |
Christopher Haster |
2:7fb7e78cb17f | 147 | // TCP SocketInterface implementation |
geky | 4:a7349bd7776c | 148 | int32_t LWIPInterface::LWIPSocket::open(const char *ip, uint16_t port) |
Christopher Haster |
2:7fb7e78cb17f | 149 | { |
Christopher Haster |
2:7fb7e78cb17f | 150 | struct sockaddr_in host; |
Christopher Haster |
2:7fb7e78cb17f | 151 | memset(&host, 0, sizeof host); |
Christopher Haster |
2:7fb7e78cb17f | 152 | inet_aton(ip, &host.sin_addr); |
Christopher Haster |
2:7fb7e78cb17f | 153 | host.sin_family = AF_INET; |
Christopher Haster |
2:7fb7e78cb17f | 154 | host.sin_port = htons(port); |
Christopher Haster |
2:7fb7e78cb17f | 155 | |
Christopher Haster |
2:7fb7e78cb17f | 156 | if (lwip_connect(fd, (const struct sockaddr *)&host, sizeof host) < 0) { |
Christopher Haster |
2:7fb7e78cb17f | 157 | return NS_ERROR_NO_CONNECTION; |
Christopher Haster |
2:7fb7e78cb17f | 158 | } |
Christopher Haster |
2:7fb7e78cb17f | 159 | |
Christopher Haster |
2:7fb7e78cb17f | 160 | return 0; |
Christopher Haster |
2:7fb7e78cb17f | 161 | } |
Christopher Haster |
2:7fb7e78cb17f | 162 | |
geky | 4:a7349bd7776c | 163 | int32_t LWIPInterface::LWIPSocket::close() |
Christopher Haster |
2:7fb7e78cb17f | 164 | { |
Christopher Haster |
2:7fb7e78cb17f | 165 | return 0; |
Christopher Haster |
2:7fb7e78cb17f | 166 | } |
Christopher Haster |
2:7fb7e78cb17f | 167 | |
geky | 4:a7349bd7776c | 168 | int32_t LWIPInterface::LWIPSocket::send(const void *voiddata, uint32_t size) |
Christopher Haster |
2:7fb7e78cb17f | 169 | { |
Christopher Haster |
2:7fb7e78cb17f | 170 | uint8_t *data = (uint8_t *)voiddata; |
Christopher Haster |
2:7fb7e78cb17f | 171 | uint32_t writtenLen = 0; |
Christopher Haster |
2:7fb7e78cb17f | 172 | |
Christopher Haster |
2:7fb7e78cb17f | 173 | while (writtenLen < size) { |
Christopher Haster |
2:7fb7e78cb17f | 174 | int ret = lwip_send(fd, data + writtenLen, size - writtenLen, 0); |
Christopher Haster |
2:7fb7e78cb17f | 175 | |
Christopher Haster |
2:7fb7e78cb17f | 176 | if (ret > 0) { |
Christopher Haster |
2:7fb7e78cb17f | 177 | writtenLen += ret; |
Christopher Haster |
2:7fb7e78cb17f | 178 | } else if (ret == 0) { |
Christopher Haster |
2:7fb7e78cb17f | 179 | return NS_ERROR_NO_CONNECTION; |
Christopher Haster |
2:7fb7e78cb17f | 180 | } else { |
Christopher Haster |
2:7fb7e78cb17f | 181 | return NS_ERROR_DEVICE_ERROR; |
Christopher Haster |
2:7fb7e78cb17f | 182 | } |
Christopher Haster |
2:7fb7e78cb17f | 183 | } |
Christopher Haster |
2:7fb7e78cb17f | 184 | |
geky | 11:82796df87b0a | 185 | return writtenLen; |
Christopher Haster |
2:7fb7e78cb17f | 186 | } |
Christopher Haster |
2:7fb7e78cb17f | 187 | |
geky | 4:a7349bd7776c | 188 | int32_t LWIPInterface::LWIPSocket::recv(void *data, uint32_t size) |
Christopher Haster |
2:7fb7e78cb17f | 189 | { |
Christopher Haster |
2:7fb7e78cb17f | 190 | int ret = lwip_recv(fd, data, size, MSG_DONTWAIT); |
Christopher Haster |
2:7fb7e78cb17f | 191 | |
Christopher Haster |
2:7fb7e78cb17f | 192 | if (ret > 0) { |
Christopher Haster |
2:7fb7e78cb17f | 193 | return ret; |
Christopher Haster |
2:7fb7e78cb17f | 194 | } else if (ret == 0) { |
Christopher Haster |
2:7fb7e78cb17f | 195 | return NS_ERROR_NO_CONNECTION; |
Christopher Haster |
2:7fb7e78cb17f | 196 | } else if (ret == -1) { |
geky | 11:82796df87b0a | 197 | return NS_ERROR_WOULD_BLOCK; |
Christopher Haster |
2:7fb7e78cb17f | 198 | } else { |
Christopher Haster |
2:7fb7e78cb17f | 199 | return NS_ERROR_DEVICE_ERROR; |
Christopher Haster |
2:7fb7e78cb17f | 200 | } |
Christopher Haster |
2:7fb7e78cb17f | 201 | } |
geky | 12:899403b675fe | 202 | #endif |
Christopher Haster |
2:7fb7e78cb17f | 203 | |
geky | 12:899403b675fe | 204 | /** Start the interface |
geky | 12:899403b675fe | 205 | * @return 0 on success, negative on failure |
geky | 12:899403b675fe | 206 | */ |
geky | 12:899403b675fe | 207 | virtual int connect() = 0; |
Christopher Haster |
2:7fb7e78cb17f | 208 | |
geky | 12:899403b675fe | 209 | /** Stop the interface |
geky | 12:899403b675fe | 210 | * @return 0 on success, negative on failure |
geky | 12:899403b675fe | 211 | */ |
geky | 12:899403b675fe | 212 | virtual int disconnect() = 0; |
geky | 12:899403b675fe | 213 | |
geky | 12:899403b675fe | 214 | class NetworkInterface |
geky | 12:899403b675fe | 215 | { |
geky | 12:899403b675fe | 216 | public: |
geky | 12:899403b675fe | 217 | virtual ~NetworkInterface() {}; |
geky | 12:899403b675fe | 218 | |
geky | 12:899403b675fe | 219 | /** Get the internally stored IP address |
geky | 12:899403b675fe | 220 | /return IP address of the interface or null if not yet connected |
geky | 12:899403b675fe | 221 | */ |
geky | 12:899403b675fe | 222 | virtual const char *get_ip_address() = 0; |
geky | 12:899403b675fe | 223 | |
geky | 12:899403b675fe | 224 | /** Get the internally stored MAC address |
geky | 12:899403b675fe | 225 | /return MAC address of the interface |
geky | 12:899403b675fe | 226 | */ |
geky | 12:899403b675fe | 227 | virtual const char *get_mac_address() = 0; |
geky | 12:899403b675fe | 228 | |
geky | 12:899403b675fe | 229 | /** Get the current status of the interface |
geky | 12:899403b675fe | 230 | /return true if connected |
geky | 12:899403b675fe | 231 | */ |
geky | 12:899403b675fe | 232 | virtual bool is_connected() { |
geky | 12:899403b675fe | 233 | return get_ip_address() != NULL; |
geky | 12:899403b675fe | 234 | } |
geky | 12:899403b675fe | 235 | |
geky | 12:899403b675fe | 236 | /** Looks up the specified host's IP address |
geky | 12:899403b675fe | 237 | /param name Hostname to lookup |
geky | 12:899403b675fe | 238 | /param dest Destination for IP address, must have space for SocketAddress::IP_SIZE |
geky | 12:899403b675fe | 239 | /return 0 on success, negative on failure |
geky | 12:899403b675fe | 240 | */ |
geky | 12:899403b675fe | 241 | virtual int gethostbyname(const char *name, char *dest); |
geky | 12:899403b675fe | 242 | |
geky | 12:899403b675fe | 243 | protected: |
geky | 12:899403b675fe | 244 | friend class Socket; |
geky | 12:899403b675fe | 245 | friend class UDPSocket; |
geky | 12:899403b675fe | 246 | friend class TCPSocket; |
geky | 12:899403b675fe | 247 | friend class TCPServer; |
geky | 12:899403b675fe | 248 | |
geky | 12:899403b675fe | 249 | /** Enum of socket protocols |
geky | 12:899403b675fe | 250 | /enum protocol_t |
geky | 12:899403b675fe | 251 | */ |
geky | 12:899403b675fe | 252 | enum protocol_t { |
geky | 12:899403b675fe | 253 | TCP, /*!< Socket is of TCP type */ |
geky | 12:899403b675fe | 254 | UDP, /*!< Socket is of UDP type */ |
geky | 12:899403b675fe | 255 | }; |
geky | 12:899403b675fe | 256 | |
geky | 12:899403b675fe | 257 | /** Create a socket |
geky | 12:899403b675fe | 258 | /param proto The type of socket to open, TCP or UDP |
geky | 12:899403b675fe | 259 | /return The alocated socket or null on failure |
geky | 12:899403b675fe | 260 | */ |
geky | 12:899403b675fe | 261 | virtual void *socket_create(protocol_t proto) = 0; |
geky | 12:899403b675fe | 262 | |
geky | 12:899403b675fe | 263 | /** Destroy a socket |
geky | 12:899403b675fe | 264 | /param socket Previously allocated socket |
geky | 12:899403b675fe | 265 | */ |
geky | 12:899403b675fe | 266 | virtual void socket_destroy(void *handle) = 0; |
geky | 12:899403b675fe | 267 | |
geky | 12:899403b675fe | 268 | /** Set socket options |
geky | 12:899403b675fe | 269 | \param handle Socket handle |
geky | 12:899403b675fe | 270 | \param optname Option ID |
geky | 12:899403b675fe | 271 | \param optval Option value |
geky | 12:899403b675fe | 272 | \param optlen Length of the option value |
geky | 12:899403b675fe | 273 | \return 0 on success, negative on failure |
geky | 12:899403b675fe | 274 | */ |
geky | 12:899403b675fe | 275 | virtual int socket_set_option(void *handle, int optname, const void *optval, unsigned int optlen) = 0; |
geky | 12:899403b675fe | 276 | |
geky | 12:899403b675fe | 277 | /** Get socket options |
geky | 12:899403b675fe | 278 | \param handle Socket handle |
geky | 12:899403b675fe | 279 | \param optname Option ID |
geky | 12:899403b675fe | 280 | \param optval Buffer pointer where to write the option value |
geky | 12:899403b675fe | 281 | \param optlen Length of the option value |
geky | 12:899403b675fe | 282 | \return 0 on success, negative on failure |
geky | 12:899403b675fe | 283 | */ |
geky | 12:899403b675fe | 284 | virtual int socket_get_option(void *handle, int optname, void *optval, unsigned int *optlen) = 0; |
geky | 12:899403b675fe | 285 | |
geky | 12:899403b675fe | 286 | /** Bind a server socket to a specific port |
geky | 12:899403b675fe | 287 | \param handle Socket handle |
geky | 12:899403b675fe | 288 | \param port The port to listen for incoming connections on |
geky | 12:899403b675fe | 289 | \return 0 on success, negative on failure. |
geky | 12:899403b675fe | 290 | */ |
geky | 12:899403b675fe | 291 | virtual int socket_bind(void *handle, int port) = 0; |
geky | 12:899403b675fe | 292 | |
geky | 12:899403b675fe | 293 | /** Start listening for incoming connections |
geky | 12:899403b675fe | 294 | \param handle Socket handle |
geky | 12:899403b675fe | 295 | \param backlog Number of pending connections that can be queued up at any |
geky | 12:899403b675fe | 296 | one time [Default: 1] |
geky | 12:899403b675fe | 297 | \return 0 on success, negative on failure |
geky | 12:899403b675fe | 298 | */ |
geky | 12:899403b675fe | 299 | virtual int socket_listen(void *handle, int backlog) = 0; |
geky | 12:899403b675fe | 300 | |
geky | 12:899403b675fe | 301 | /** Connects this TCP socket to the server |
geky | 12:899403b675fe | 302 | \param handle Socket handle |
geky | 12:899403b675fe | 303 | \param address SocketAddress to connect to |
geky | 12:899403b675fe | 304 | \return 0 on success, negative on failure |
geky | 12:899403b675fe | 305 | */ |
geky | 12:899403b675fe | 306 | virtual int socket_connect(void *handle, const SocketAddress &address) = 0; |
geky | 12:899403b675fe | 307 | |
geky | 12:899403b675fe | 308 | /** Check if the socket is connected |
geky | 12:899403b675fe | 309 | \param handle Socket handle |
geky | 12:899403b675fe | 310 | \return true if connected, false otherwise |
geky | 12:899403b675fe | 311 | */ |
geky | 12:899403b675fe | 312 | virtual bool socket_is_connected(void *handle) = 0; |
geky | 12:899403b675fe | 313 | |
geky | 12:899403b675fe | 314 | /** Accept a new connection. |
geky | 12:899403b675fe | 315 | \param handle Socket handle |
geky | 12:899403b675fe | 316 | \param socket A TCPSocket instance that will handle the incoming connection. |
geky | 12:899403b675fe | 317 | \return 0 on success, negative on failure. |
geky | 12:899403b675fe | 318 | \note This call is not-blocking, if this call would block, must |
geky | 12:899403b675fe | 319 | immediately return NSAPI_ERROR_WOULD_WAIT |
geky | 12:899403b675fe | 320 | */ |
geky | 12:899403b675fe | 321 | virtual int socket_accept(void *handle, void **connection) = 0; |
geky | 12:899403b675fe | 322 | |
geky | 12:899403b675fe | 323 | /** Send data to the remote host |
geky | 12:899403b675fe | 324 | \param handle Socket handle |
geky | 12:899403b675fe | 325 | \param data The buffer to send to the host |
geky | 12:899403b675fe | 326 | \param size The length of the buffer to send |
geky | 12:899403b675fe | 327 | \return Number of written bytes on success, negative on failure |
geky | 12:899403b675fe | 328 | \note This call is not-blocking, if this call would block, must |
geky | 12:899403b675fe | 329 | immediately return NSAPI_ERROR_WOULD_WAIT |
geky | 12:899403b675fe | 330 | */ |
geky | 12:899403b675fe | 331 | virtual int socket_send(void *handle, const void *data, unsigned size) = 0; |
geky | 12:899403b675fe | 332 | |
geky | 12:899403b675fe | 333 | /** Receive data from the remote host |
geky | 12:899403b675fe | 334 | \param handle Socket handle |
geky | 12:899403b675fe | 335 | \param data The buffer in which to store the data received from the host |
geky | 12:899403b675fe | 336 | \param size The maximum length of the buffer |
geky | 12:899403b675fe | 337 | \return Number of received bytes on success, negative on failure |
geky | 12:899403b675fe | 338 | \note This call is not-blocking, if this call would block, must |
geky | 12:899403b675fe | 339 | immediately return NSAPI_ERROR_WOULD_WAIT |
geky | 12:899403b675fe | 340 | */ |
geky | 12:899403b675fe | 341 | virtual int socket_recv(void *handle, void *data, unsigned size) = 0; |
geky | 12:899403b675fe | 342 | |
geky | 12:899403b675fe | 343 | /** Send a packet to a remote endpoint |
geky | 12:899403b675fe | 344 | \param handle Socket handle |
geky | 12:899403b675fe | 345 | \param address The remote SocketAddress |
geky | 12:899403b675fe | 346 | \param data The packet to be sent |
geky | 12:899403b675fe | 347 | \param size The length of the packet to be sent |
geky | 12:899403b675fe | 348 | \return the number of written bytes on success, negative on failure |
geky | 12:899403b675fe | 349 | \note This call is not-blocking, if this call would block, must |
geky | 12:899403b675fe | 350 | immediately return NSAPI_ERROR_WOULD_WAIT |
geky | 12:899403b675fe | 351 | */ |
geky | 12:899403b675fe | 352 | virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size) = 0; |
geky | 12:899403b675fe | 353 | |
geky | 12:899403b675fe | 354 | /** Receive a packet from a remote endpoint |
geky | 12:899403b675fe | 355 | \param handle Socket handle |
geky | 12:899403b675fe | 356 | \param address Destination for the remote SocketAddress or null |
geky | 12:899403b675fe | 357 | \param buffer The buffer for storing the incoming packet data |
geky | 12:899403b675fe | 358 | If a packet is too long to fit in the supplied buffer, |
geky | 12:899403b675fe | 359 | excess bytes are discarded |
geky | 12:899403b675fe | 360 | \param size The length of the buffer |
geky | 12:899403b675fe | 361 | \return the number of received bytes on success, negative on failure |
geky | 12:899403b675fe | 362 | \note This call is not-blocking, if this call would block, must |
geky | 12:899403b675fe | 363 | immediately return NSAPI_ERROR_WOULD_WAIT |
geky | 12:899403b675fe | 364 | */ |
geky | 12:899403b675fe | 365 | virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) = 0; |
geky | 12:899403b675fe | 366 | |
geky | 12:899403b675fe | 367 | /** Close the socket |
geky | 12:899403b675fe | 368 | \param handle Socket handle |
geky | 12:899403b675fe | 369 | \param shutdown free the left-over data in message queues |
geky | 12:899403b675fe | 370 | */ |
geky | 12:899403b675fe | 371 | virtual int socket_close(void *handle, bool shutdown) = 0; |
geky | 12:899403b675fe | 372 | |
geky | 12:899403b675fe | 373 | /** Register a callback on when a new connection is ready |
geky | 12:899403b675fe | 374 | \param handle Socket handle |
geky | 12:899403b675fe | 375 | \param callback Function to call when accept will succeed, may be called in |
geky | 12:899403b675fe | 376 | interrupt context. |
geky | 12:899403b675fe | 377 | \param id Argument to pass to callback |
geky | 12:899403b675fe | 378 | */ |
geky | 12:899403b675fe | 379 | virtual void socket_attach_accept(void *handle, void (*callback)(void *), void *id) = 0; |
geky | 12:899403b675fe | 380 | |
geky | 12:899403b675fe | 381 | /** Register a callback on when send is ready |
geky | 12:899403b675fe | 382 | \param handle Socket handle |
geky | 12:899403b675fe | 383 | \param callback Function to call when accept will succeed, may be called in |
geky | 12:899403b675fe | 384 | interrupt context. |
geky | 12:899403b675fe | 385 | \param id Argument to pass to callback |
geky | 12:899403b675fe | 386 | */ |
geky | 12:899403b675fe | 387 | virtual void socket_attach_send(void *handle, void (*callback)(void *), void *id) = 0; |
geky | 12:899403b675fe | 388 | |
geky | 12:899403b675fe | 389 | /** Register a callback on when recv is ready |
geky | 12:899403b675fe | 390 | \param handle Socket handle |
geky | 12:899403b675fe | 391 | \param callback Function to call when accept will succeed, may be called in |
geky | 12:899403b675fe | 392 | interrupt context. |
geky | 12:899403b675fe | 393 | \param id Argument to pass to callback |
geky | 12:899403b675fe | 394 | */ |
geky | 12:899403b675fe | 395 | virtual void socket_attach_recv(void *handle, void (*callback)(void *), void *id) = 0; |
geky | 12:899403b675fe | 396 | }; |
geky | 12:899403b675fe | 397 | #endif |
geky | 12:899403b675fe | 398 |