Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : /* 16 : simple socket handling class for systems with BSD socket API 17 : */ 18 : 19 : #include <AP_HAL/AP_HAL.h> 20 : #include <AP_Networking/AP_Networking_Config.h> 21 : 22 : #if AP_NETWORKING_SOCKETS_ENABLED || defined(AP_SOCKET_NATIVE_ENABLED) 23 : 24 : #ifndef SOCKET_CLASS_NAME 25 : #error "Don't include Socket.hpp directly" 26 : #endif 27 : 28 : #define IP4_STR_LEN 16 29 : 30 : class SOCKET_CLASS_NAME { 31 : public: 32 : SOCKET_CLASS_NAME(bool _datagram); 33 : SOCKET_CLASS_NAME(bool _datagram, int _fd); 34 : ~SOCKET_CLASS_NAME(); 35 : 36 : bool connect(const char *address, uint16_t port); 37 : bool connect_timeout(const char *address, uint16_t port, uint32_t timeout_ms); 38 : bool bind(const char *address, uint16_t port); 39 : #if defined(AP_SOCKET_NATIVE_ENABLED) 40 : bool connect_unix(const char *path); 41 : bool bind_unix(const char *path); 42 : static void register_unix_path(int fd, const char *path); 43 : static void cleanup_unix_paths(); 44 : #endif 45 : bool reuseaddress() const; 46 : bool set_blocking(bool blocking) const; 47 : bool set_cloexec() const; 48 : void set_broadcast(void) const; 49 : 50 : /* 51 : set the address of the local interface to send and receive 52 : multicast on. Must be called before connect(). The default of 53 : zero (INADDR_ANY) leaves the choice of interface to the routing 54 : table, which is what you want unless you have a reason to pin the 55 : traffic to one interface. Address is in network byte order. 56 : */ 57 5 : void set_multicast_interface_address(uint32_t addr) { 58 5 : multicast_interface_address = addr; 59 5 : } 60 : 61 : ssize_t send(const void *pkt, size_t size) const; 62 : ssize_t sendto(const void *buf, size_t size, const char *address, uint16_t port); 63 : ssize_t sendto(const void *buf, size_t size, uint32_t address, uint16_t port); 64 : ssize_t recv(void *pkt, size_t size, uint32_t timeout_ms); 65 : 66 : // return the IP address and port of the last received packet 67 : void last_recv_address(const char *&ip_addr, uint16_t &port) const; 68 : 69 : // return the IP address and port of the last received packet, using caller supplied buffer 70 : const char *last_recv_address(char *ip_addr_buf, uint8_t buflen, uint16_t &port) const; 71 : 72 : // return the IP address and port of the last received packet 73 : bool last_recv_address(uint32_t &ip_addr, uint16_t &port) const; 74 : 75 : // return true if there is pending data for input 76 : bool pollin(uint32_t timeout_ms); 77 : 78 : // return true if there is room for output data 79 : bool pollout(uint32_t timeout_ms); 80 : 81 : // start listening for new tcp connections 82 : bool listen(uint16_t backlog) const; 83 : 84 : // close socket 85 : void close(void); 86 : 87 : // accept a new connection. Only valid for TCP connections after 88 : // listen has been used. A new socket is returned 89 : SOCKET_CLASS_NAME *accept(uint32_t timeout_ms); 90 : 91 : // get a FD suitable for read selection 92 42231470 : int get_read_fd(void) const { 93 42231470 : return fd_in != -1? fd_in : fd; 94 : } 95 : 96 : // create a new socket with same fd, but new memory 97 : // the old socket gets fd of -1 98 : SOCKET_CLASS_NAME *duplicate(void); 99 : 100 0 : bool is_connected(void) const { 101 0 : return connected; 102 : } 103 : 104 0 : bool is_pending(void) const { 105 0 : return pending_connect; 106 : } 107 : 108 : // access to inet_ntop 109 : static const char *inet_addr_to_str(uint32_t addr, char *dst, uint16_t len); 110 : 111 : // access to inet_pton 112 : static uint32_t inet_str_to_addr(const char *ipstr); 113 : 114 : private: 115 : bool datagram; 116 : // we avoid using struct sockaddr_in here to keep support for 117 : // mixing native sockets and lwip sockets in SITL 118 : uint32_t last_in_addr[4]; 119 : bool is_multicast_address(struct sockaddr_in &addr) const; 120 : 121 : int fd = -1; 122 : 123 : // fd_in is used for multicast UDP 124 : int fd_in = -1; 125 : 126 : // address of the local interface to multicast on, network byte 127 : // order; zero (INADDR_ANY) leaves the choice to the routing table 128 : uint32_t multicast_interface_address; 129 : 130 : bool connected; 131 : 132 : bool pending_connect; 133 : 134 : void make_sockaddr(const char *address, uint16_t port, struct sockaddr_in &sockaddr); 135 : }; 136 : 137 : #endif // AP_NETWORKING_SOCKETS_ENABLED