Line data Source code
1 : 2 : #pragma once 3 : 4 : #include "AP_Networking_Config.h" 5 : 6 : #if AP_NETWORKING_ENABLED 7 : #include <AP_Param/AP_Param.h> 8 : 9 : #include "AP_Networking_address.h" 10 : #include "AP_Networking_Backend.h" 11 : #include "AP_Networking_CAN.h" 12 : #include <AP_SerialManager/AP_SerialManager.h> 13 : #include <AP_HAL/utility/RingBuffer.h> 14 : 15 : /* 16 : Note! all uint32_t IPv4 addresses are in host byte order 17 : */ 18 : 19 : // declare backend classes 20 : class AP_Networking_Backend; 21 : class AP_Networking_ChibiOS; 22 : 23 : class SocketAPM; 24 : 25 : class AP_Networking 26 : { 27 : public: 28 : friend class AP_Networking_Backend; 29 : friend class AP_Networking_ChibiOS; 30 : friend class AP_Networking_PPP; 31 : friend class AP_Networking_SITL_TUN; 32 : friend class AP_Vehicle; 33 : friend class Networking_Periph; 34 : 35 : AP_Networking(); 36 : 37 : /* Do not allow copies */ 38 : CLASS_NO_COPY(AP_Networking); 39 : 40 : // initialize the library. This should only be run once 41 : void init(); 42 : 43 : // update task, called at 10Hz 44 : void update(); 45 : 46 11 : static AP_Networking *get_singleton(void) 47 : { 48 11 : return singleton; 49 : } 50 : 51 0 : HAL_Semaphore &get_semaphore(void) 52 : { 53 0 : return sem; 54 : } 55 : 56 : // Networking interface is enabled and initialized 57 1504089 : bool is_healthy() const 58 : { 59 1504089 : return param.enabled && backend != nullptr; 60 : } 61 : 62 : // returns true if DHCP is enabled 63 : bool get_dhcp_enabled() const 64 : { 65 : #if AP_NETWORKING_DHCP_AVAILABLE 66 : return param.dhcp; 67 : #else 68 : // DHCP is not available from our scope but could be enabled/controlled 69 : // by the OS which is the case on Linux builds, including SITL 70 : // TODO: ask the OS if DHCP is enabled 71 : return false; 72 : #endif 73 : } 74 : 75 : // Sets DHCP to be enabled or disabled 76 : void set_dhcp_enable(const bool enable) 77 : { 78 : #if AP_NETWORKING_DHCP_AVAILABLE 79 : param.dhcp.set(enable); 80 : #endif 81 : } 82 : 83 : // returns the 32bit value of the active IP address that is currently in use 84 : uint32_t get_ip_active() const; 85 : 86 : // returns the 32bit value of the user-parameter static IP address 87 : uint32_t get_ip_param() const 88 : { 89 : #if AP_NETWORKING_CONTROLS_HOST_IP_SETTINGS_ENABLED 90 : return param.ipaddr.get_uint32(); 91 : #else 92 : // TODO: ask the OS for the IP address 93 : return 0; 94 : #endif 95 : } 96 : 97 : // sets the user-parameter static IP address from a 32bit value 98 : void set_ip_param(const uint32_t ip) 99 : { 100 : #if AP_NETWORKING_CONTROLS_HOST_IP_SETTINGS_ENABLED 101 : param.ipaddr.set_uint32(ip); 102 : #endif 103 : } 104 : 105 : // returns the 32bit value of the active Netmask that is currently in use 106 : uint32_t get_netmask_active() const; 107 : 108 : // returns the 32bit value of the of the user-parameter static Netmask 109 : uint32_t get_netmask_param() const 110 : { 111 : #if AP_NETWORKING_CONTROLS_HOST_IP_SETTINGS_ENABLED 112 : return convert_netmask_bitcount_to_ip(param.netmask.get()); 113 : #else 114 : // TODO: ask the OS for the Netmask 115 : return 0; 116 : #endif 117 : } 118 : 119 : uint32_t get_gateway_active() const; 120 : 121 : uint32_t get_gateway_param() const 122 : { 123 : #if AP_NETWORKING_CONTROLS_HOST_IP_SETTINGS_ENABLED 124 : return param.gwaddr.get_uint32(); 125 : #else 126 : // TODO: ask the OS for the Gateway 127 : return 0; 128 : #endif 129 : } 130 : 131 : void set_gateway_param(const uint32_t gw) 132 : { 133 : #if AP_NETWORKING_CONTROLS_HOST_IP_SETTINGS_ENABLED 134 : param.gwaddr.set_uint32(gw); 135 : #endif 136 : } 137 : 138 : // wait in a thread for network startup 139 : void startup_wait(void) const; 140 : 141 : // convert string to ethernet mac address 142 : static bool convert_str_to_macaddr(const char *mac_str, uint8_t addr[6]); 143 : 144 : // address to string using a static return buffer for scripting 145 : static const char *address_to_str(uint32_t addr); 146 : 147 : // helper functions to convert between 32bit Netmask and counting consecutive bits and back 148 : static uint32_t convert_netmask_bitcount_to_ip(const uint32_t netmask_bitcount); 149 : static uint8_t convert_netmask_ip_to_bitcount(const uint32_t netmask_ip); 150 : 151 : // add new routes for an interface. 152 : // Returns true if the route is added or the route already exists 153 : bool add_route(uint8_t backend_idx, uint8_t iface_idx, uint32_t dest_ip, uint8_t mask_len); 154 : 155 : // hook for custom routes 156 : struct netif *routing_hook(uint32_t dest); 157 : 158 : /* 159 : send contents of a file to a socket then close both socket and file 160 : */ 161 : bool sendfile(SocketAPM *sock, int fd); 162 : 163 : static const struct AP_Param::GroupInfo var_info[]; 164 : 165 : enum class OPTION { 166 : PPP_ETHERNET_GATEWAY=(1U<<0), 167 : #if AP_NETWORKING_CAN_MCAST_ENABLED 168 : CAN1_MCAST_ENDPOINT=(1U<<1), 169 : CAN2_MCAST_ENDPOINT=(1U<<2), 170 : #if AP_NETWORKING_CAN_MCAST_BRIDGING_ENABLED 171 : CAN1_MCAST_BRIDGED=(1U<<3), 172 : CAN2_MCAST_BRIDGED=(1U<<4), 173 : #endif 174 : #endif 175 : PPP_TIMEOUT_DISABLE=(1U<<5), 176 : PPP_ECHO_LIMIT_DISABLE=(1U<<6), 177 : #if AP_NETWORKING_CAPTURE_ENABLED 178 : CAPTURE_PACKETS=(1U<<7), 179 : #endif 180 : }; 181 : bool option_is_set(OPTION option) const { 182 : return (param.options.get() & int32_t(option)) != 0; 183 : } 184 : 185 : #if AP_NETWORKING_CAN_MCAST_BRIDGING_ENABLED 186 : bool is_can_mcast_ep_bridged(uint8_t bus) const { 187 : return (option_is_set(OPTION::CAN1_MCAST_BRIDGED) && bus == 0) || 188 : (option_is_set(OPTION::CAN2_MCAST_BRIDGED) && bus == 1); 189 : } 190 : #endif 191 : 192 : private: 193 : static AP_Networking *singleton; 194 : 195 : void announce_address_changes(); 196 : 197 : struct { 198 : #if AP_NETWORKING_CONTROLS_HOST_IP_SETTINGS_ENABLED 199 : AP_Networking_IPV4 ipaddr{AP_NETWORKING_DEFAULT_STATIC_IP_ADDR}; 200 : AP_Int8 netmask; // bits to mask. example: (16 == 255.255.0.0) and (24 == 255.255.255.0) 201 : AP_Networking_IPV4 gwaddr{AP_NETWORKING_DEFAULT_STATIC_GW_ADDR}; 202 : AP_Networking_MAC macaddr{AP_NETWORKING_DEFAULT_MAC_ADDR}; 203 : #if AP_NETWORKING_DHCP_AVAILABLE 204 : AP_Int8 dhcp; 205 : #endif 206 : #endif 207 : 208 : AP_Int8 enabled; 209 : AP_Int32 options; 210 : 211 : #if AP_NETWORKING_TESTS_ENABLED 212 : AP_Int32 tests; 213 : AP_Networking_IPV4 test_ipaddr{AP_NETWORKING_TEST_IP}; 214 : #endif 215 : 216 : #if AP_NETWORKING_PPP_GATEWAY_ENABLED 217 : AP_Networking_IPV4 remote_ppp_ip{AP_NETWORKING_REMOTE_PPP_IP}; 218 : #endif 219 : } param; 220 : 221 : AP_Networking_Backend *backend; 222 : 223 : #if AP_NETWORKING_PPP_GATEWAY_ENABLED 224 : AP_Networking_Backend *backend_PPP; 225 : #endif 226 : 227 : HAL_Semaphore sem; 228 : 229 : enum class NetworkPortType { 230 : NONE = 0, 231 : UDP_CLIENT = 1, 232 : UDP_SERVER = 2, 233 : TCP_CLIENT = 3, 234 : TCP_SERVER = 4, 235 : }; 236 : 237 : #if AP_NETWORKING_REGISTER_PORT_ENABLED 238 : // class for NET_Pn_* parameters 239 : class Port : public AP_SerialManager::RegisteredPort { 240 : public: 241 : /* Do not allow copies */ 242 : CLASS_NO_COPY(Port); 243 : 244 8392 : Port() {} 245 : 246 : static const struct AP_Param::GroupInfo var_info[]; 247 : AP_Enum<NetworkPortType> type_param; 248 : NetworkPortType type; 249 : AP_Networking_IPV4 ip {"0.0.0.0"}; 250 : AP_Int32 port; 251 : SocketAPM *sock; 252 : SocketAPM *listen_sock; 253 : 254 0 : bool is_initialized() override { 255 0 : return true; 256 : } 257 0 : bool tx_pending() override { 258 0 : return false; 259 : } 260 122 : bool is_network_port() const override { 261 122 : return true; 262 : } 263 : 264 : void udp_client_init(void); 265 : void udp_server_init(void); 266 : void tcp_server_init(void); 267 : void tcp_client_init(void); 268 : 269 : void udp_client_loop(void); 270 : void udp_server_loop(void); 271 : void tcp_client_loop(void); 272 : void tcp_server_loop(void); 273 : 274 : bool send_receive(void); 275 : 276 : private: 277 : bool init_buffers(const uint32_t size_rx, const uint32_t size_tx); 278 : void thread_create(AP_HAL::MemberProc); 279 : 280 : uint32_t txspace() override; 281 : void _begin(uint32_t b, uint16_t rxS, uint16_t txS) override; 282 : size_t _write(const uint8_t *buffer, size_t size) override; 283 : ssize_t _read(uint8_t *buffer, uint16_t count) override; 284 : uint32_t _available() override; 285 0 : void _end() override {} 286 0 : void _flush() override {} 287 : bool _discard_input() override; 288 : 289 : enum flow_control get_flow_control(void) override; 290 : 291 692 : uint32_t bw_in_bytes_per_second() const override { 292 692 : return 1000000UL; 293 : } 294 : 295 : ByteBuffer *readbuffer; 296 : ByteBuffer *writebuffer; 297 : char thread_name[10]; 298 : uint32_t last_size_tx; 299 : uint32_t last_size_rx; 300 : bool packetise; 301 : bool connected; 302 : uint32_t last_udp_connect_address; 303 : uint16_t last_udp_connect_port; 304 : bool have_received; 305 : bool close_on_recv_error; 306 : uint32_t last_udp_srv_recv_time_ms; 307 : 308 : // statistics 309 : uint32_t tx_stats_bytes; 310 : uint32_t rx_stats_bytes; 311 : 312 : HAL_Semaphore sem; 313 : 314 : protected: 315 : #if HAL_UART_STATS_ENABLED 316 : // Getters for cumulative tx and rx counts 317 257 : uint32_t get_total_tx_bytes() const override { return tx_stats_bytes; } 318 257 : uint32_t get_total_rx_bytes() const override { return rx_stats_bytes; } 319 : #endif 320 : }; 321 : #endif // AP_NETWORKING_REGISTER_PORT_ENABLED 322 : 323 : private: 324 : uint32_t announce_ms; 325 : 326 : #if AP_NETWORKING_TESTS_ENABLED 327 : enum { 328 : TEST_UDP_CLIENT = (1U<<0), 329 : TEST_TCP_CLIENT = (1U<<1), 330 : TEST_TCP_DISCARD = (1U<<2), 331 : TEST_TCP_REFLECT = (1U<<3), 332 : TEST_CONNECTOR_LOOPBACK = (1U<<4), 333 : }; 334 : void start_tests(void); 335 : void test_UDP_client(void); 336 : void test_TCP_client(void); 337 : void test_TCP_discard(void); 338 : void test_TCP_reflect(void); 339 : void test_connector_loopback(void); 340 : #endif // AP_NETWORKING_TESTS_ENABLED 341 : 342 : #if AP_NETWORKING_REGISTER_PORT_ENABLED 343 : // ports for registration with serial manager 344 : Port ports[AP_NETWORKING_NUM_PORTS]; 345 : #endif 346 : 347 : #if AP_NETWORKING_CAN_MCAST_ENABLED 348 : AP_Networking_CAN mcast_server; 349 : #endif 350 : 351 : // support for sendfile() 352 : struct SendFile { 353 : SocketAPM *sock; 354 : int fd; 355 : void close(void); 356 : } sendfiles[AP_NETWORKING_NUM_SENDFILES]; 357 : 358 : uint8_t *sendfile_buf; 359 : uint32_t sendfile_bufsize; 360 : void sendfile_check(void); 361 : bool sendfile_thread_started; 362 : 363 : void ports_init(void); 364 : }; 365 : 366 : namespace AP 367 : { 368 : AP_Networking &network(); 369 : }; 370 : 371 : extern "C" { 372 : int ap_networking_printf(const char *fmt, ...); 373 : } 374 : 375 : #endif // AP_NETWORKING_ENABLED