LCOV - code coverage report
Current view: top level - GCS_MAVLink - GCS_MAVLink.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 44 56 78.6 %
Date: 2026-09-09 11:02:08 Functions: 9 10 90.0 %

          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             : /// @file       GCS_MAVLink.cpp
      17             : 
      18             : /*
      19             : This provides some support code and variables for MAVLink enabled sketches
      20             : 
      21             : */
      22             : 
      23             : #include "GCS_config.h"
      24             : 
      25             : #if HAL_MAVLINK_BINDINGS_ENABLED
      26             : 
      27             : #include "GCS.h"
      28             : #include "GCS_MAVLink.h"
      29             : 
      30             : #include <AP_Common/AP_Common.h>
      31             : #include <AP_HAL/AP_HAL.h>
      32             : 
      33             : extern const AP_HAL::HAL& hal;
      34             : 
      35             : #ifdef MAVLINK_SEPARATE_HELPERS
      36             : // Shut up warnings about missing declarations; TODO: should be fixed on
      37             : // mavlink/pymavlink project for when MAVLINK_SEPARATE_HELPERS is defined
      38             : #pragma GCC diagnostic push
      39             : #pragma GCC diagnostic ignored "-Wmissing-declarations"
      40             : #include "include/mavlink/v2.0/mavlink_helpers.h"
      41             : #pragma GCC diagnostic pop
      42             : #endif
      43             : 
      44           0 : mavlink_message_t* mavlink_get_channel_buffer(uint8_t chan) {
      45             : #if HAL_GCS_ENABLED
      46           0 :     GCS_MAVLINK *link = gcs().chan(chan);
      47           0 :     if (link == nullptr) {
      48           0 :         return nullptr;
      49             :     }
      50           0 :     return link->channel_buffer();
      51             : #else
      52             :     return nullptr;
      53             : #endif
      54             : }
      55             : 
      56   314543847 : mavlink_status_t* mavlink_get_channel_status(uint8_t chan) {
      57             : #if HAL_GCS_ENABLED
      58   314543847 :     GCS_MAVLINK *link = gcs().chan(chan);
      59   314543847 :     if (link == nullptr) {
      60    17544946 :         return nullptr;
      61             :     }
      62   296998901 :     return link->channel_status();
      63             : #else
      64             :     return nullptr;
      65             : #endif
      66             : }
      67             : 
      68             : #endif // HAL_MAVLINK_BINDINGS_ENABLED
      69             : 
      70             : #if HAL_GCS_ENABLED
      71             : 
      72             : AP_HAL::UARTDriver      *mavlink_comm_port[MAVLINK_COMM_NUM_BUFFERS];
      73             : bool gcs_alternative_active[MAVLINK_COMM_NUM_BUFFERS];
      74             : 
      75             : // per-channel lock
      76             : static HAL_Semaphore chan_locks[MAVLINK_COMM_NUM_BUFFERS];
      77             : static bool chan_discard[MAVLINK_COMM_NUM_BUFFERS];
      78             : 
      79             : mavlink_system_t mavlink_system = {7,1};
      80             : 
      81             : // routing table
      82             : MAVLink_routing GCS_MAVLINK::routing;
      83             : 
      84           8 : GCS_MAVLINK *GCS_MAVLINK::find_by_mavtype_and_compid(uint8_t mav_type, uint8_t compid, uint8_t &sysid) {
      85             :     mavlink_channel_t channel;
      86           8 :     if (!routing.find_by_mavtype_and_compid(mav_type, compid, sysid, channel)) {
      87           0 :         return nullptr;
      88             :     }
      89           8 :     return gcs().chan(channel);
      90             : }
      91             : 
      92             : // set a channel as private. Private channels get sent heartbeats, but
      93             : // don't get broadcast packets or forwarded packets
      94       18206 : void GCS_MAVLINK::set_channel_private(mavlink_channel_t _chan)
      95             : {
      96       18206 :     const uint8_t mask = (1U<<(unsigned)_chan);
      97       18206 :     mavlink_private |= mask;
      98       18206 : }
      99             : 
     100             : // return a MAVLink parameter type given a AP_Param type
     101     1541876 : MAV_PARAM_TYPE GCS_MAVLINK::mav_param_type(enum ap_var_type t)
     102             : {
     103     1541876 :     if (t == AP_PARAM_INT8) {
     104      477115 :             return MAV_PARAM_TYPE_INT8;
     105             :     }
     106     1064761 :     if (t == AP_PARAM_INT16) {
     107      303053 :             return MAV_PARAM_TYPE_INT16;
     108             :     }
     109      761708 :     if (t == AP_PARAM_INT32) {
     110      133160 :             return MAV_PARAM_TYPE_INT32;
     111             :     }
     112             :     // treat any others as float
     113      628548 :     return MAV_PARAM_TYPE_REAL32;
     114             : }
     115             : 
     116             : 
     117             : /// Check for available transmit space on the nominated MAVLink channel
     118             : ///
     119             : /// @param chan         Channel to check
     120             : /// @returns            Number of bytes available
     121   105695018 : uint16_t comm_get_txspace(mavlink_channel_t chan)
     122             : {
     123   105695018 :     GCS_MAVLINK *link = gcs().chan(chan);
     124   105695018 :     if (link == nullptr) {
     125           0 :         return 0;
     126             :     }
     127   105695018 :     return link->txspace();
     128             : }
     129             : 
     130             : /*
     131             :   send a buffer out a MAVLink channel
     132             :  */
     133   106074534 : void comm_send_buffer(mavlink_channel_t chan, const uint8_t *buf, uint8_t len)
     134             : {
     135   106074534 :     if (!valid_channel(chan) || mavlink_comm_port[chan] == nullptr || chan_discard[chan]) {
     136           0 :         return;
     137             :     }
     138             : #if HAL_HIGH_LATENCY2_ENABLED
     139             :     // if it's a disabled high latency channel, don't send
     140   106074534 :     GCS_MAVLINK *link = gcs().chan(chan);
     141   106074534 :     if (link->is_high_latency_link && !gcs().get_high_latency_status()) {
     142        5508 :         return;
     143             :     }
     144             : #endif
     145   106069026 :     if (gcs_alternative_active[chan]) {
     146             :         // an alternative protocol is active
     147           0 :         return;
     148             :     }
     149   106069026 :     const size_t written = mavlink_comm_port[chan]->write(buf, len);
     150             : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
     151   106069026 :     if (written < len && !mavlink_comm_port[chan]->is_write_locked()) {
     152           0 :         AP_HAL::panic("Short write on UART: %lu < %u", (unsigned long)written, len);
     153             :     }
     154             : #else
     155             :     (void)written;
     156             : #endif
     157             : }
     158             : 
     159             : /*
     160             :   lock a channel for send
     161             :   if there is insufficient space to send size bytes then all bytes
     162             :   written to the channel by the mavlink library will be discarded
     163             :   while the lock is held.
     164             :  */
     165    35358178 : void comm_send_lock(mavlink_channel_t chan_m, uint16_t size)
     166             : {
     167    35358178 :     const uint8_t chan = uint8_t(chan_m);
     168    35358178 :     chan_locks[chan].take_blocking();
     169    35358178 :     if (mavlink_comm_port[chan]->txspace() < size) {
     170           0 :         chan_discard[chan] = true;
     171           0 :         gcs_out_of_space_to_send(chan_m);
     172             :     }
     173    35358178 : }
     174             : 
     175             : /*
     176             :   unlock a channel
     177             :  */
     178    35358178 : void comm_send_unlock(mavlink_channel_t chan_m)
     179             : {
     180    35358178 :     const uint8_t chan = uint8_t(chan_m);
     181    35358178 :     chan_discard[chan] = false;
     182    35358178 :     chan_locks[chan].give();
     183    35358178 : }
     184             : 
     185             : /*
     186             :   return reference to GCS channel lock, allowing for
     187             :   HAVE_PAYLOAD_SPACE() to be run with a locked channel
     188             :  */
     189   173367476 : HAL_Semaphore &comm_chan_lock(mavlink_channel_t chan)
     190             : {
     191   173367476 :     return chan_locks[uint8_t(chan)];
     192             : }
     193             : 
     194             : #endif  // HAL_GCS_ENABLED

Generated by: LCOV version 1.14