LCOV - code coverage report
Current view: top level - AP_Networking - AP_Networking.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 11 19 57.9 %
Date: 2026-09-09 11:02:08 Functions: 7 12 58.3 %

          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

Generated by: LCOV version 1.14