LCOV - code coverage report
Current view: top level - AP_Logger - AP_Logger.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 22 25 88.0 %
Date: 2026-09-09 11:02:08 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /* ************************************************************ */
       2             : /* Test for AP_Logger Log library                               */
       3             : /* ************************************************************ */
       4             : #pragma once
       5             : 
       6             : #include "AP_Logger_config.h"
       7             : 
       8             : #if HAL_LOGGING_ENABLED
       9             : 
      10             : #include <AP_HAL/AP_HAL.h>
      11             : #include <AP_Common/AP_Common.h>
      12             : #include <AP_Param/AP_Param.h>
      13             : #include <AP_Mission/AP_Mission.h>
      14             : #include <AP_Logger/LogStructure.h>
      15             : #include <AP_Vehicle/ModeReason.h>
      16             : 
      17             : #include <stdint.h>
      18             : 
      19             : #include "LoggerMessageWriter.h"
      20             : 
      21             : class AP_Logger_Backend;
      22             : 
      23             : // do not do anything here apart from add stuff; maintaining older
      24             : // entries means log analysis is easier
      25             : enum class LogEvent : uint8_t {
      26             :     ARMED = 10,
      27             :     DISARMED = 11,
      28             :     AUTO_ARMED = 15,
      29             :     LAND_COMPLETE_MAYBE = 17,
      30             :     LAND_COMPLETE = 18,
      31             :     LOST_GPS = 19,
      32             :     FLIP_START = 21,
      33             :     FLIP_END = 22,
      34             :     SET_HOME = 25,
      35             :     SET_SIMPLE_ON = 26,
      36             :     SET_SIMPLE_OFF = 27,
      37             :     NOT_LANDED = 28,
      38             :     SET_SUPERSIMPLE_ON = 29,
      39             :     AUTOTUNE_INITIALISED = 30,
      40             :     AUTOTUNE_OFF = 31,
      41             :     AUTOTUNE_RESTART = 32,
      42             :     AUTOTUNE_SUCCESS = 33,
      43             :     AUTOTUNE_FAILED = 34,
      44             :     AUTOTUNE_REACHED_LIMIT = 35,
      45             :     AUTOTUNE_PILOT_TESTING = 36,
      46             :     AUTOTUNE_SAVEDGAINS = 37,
      47             :     SAVE_TRIM = 38,
      48             :     SAVEWP_ADD_WP = 39,
      49             :     FENCE_ENABLE = 41,
      50             :     FENCE_DISABLE = 42,
      51             :     ACRO_TRAINER_OFF = 43,
      52             :     ACRO_TRAINER_LEVELING = 44,
      53             :     ACRO_TRAINER_LIMITED = 45,
      54             :     GRIPPER_GRAB = 46,
      55             :     GRIPPER_RELEASE = 47,
      56             :     PARACHUTE_DISABLED = 49,
      57             :     PARACHUTE_ENABLED = 50,
      58             :     PARACHUTE_RELEASED = 51,
      59             :     LANDING_GEAR_DEPLOYED = 52,
      60             :     LANDING_GEAR_RETRACTED = 53,
      61             :     MOTORS_EMERGENCY_STOPPED = 54,
      62             :     MOTORS_EMERGENCY_STOP_CLEARED = 55,
      63             :     MOTORS_INTERLOCK_DISABLED = 56,
      64             :     MOTORS_INTERLOCK_ENABLED = 57,
      65             :     ROTOR_RUNUP_COMPLETE = 58, // Heli only
      66             :     ROTOR_SPEED_BELOW_CRITICAL = 59, // Heli only
      67             :     EKF_ALT_RESET = 60,
      68             :     LAND_CANCELLED_BY_PILOT = 61,
      69             :     EKF_YAW_RESET = 62,
      70             :     AVOIDANCE_ADSB_ENABLE = 63,
      71             :     AVOIDANCE_ADSB_DISABLE = 64,
      72             :     AVOIDANCE_PROXIMITY_ENABLE = 65,
      73             :     AVOIDANCE_PROXIMITY_DISABLE = 66,
      74             :     GPS_PRIMARY_CHANGED = 67,
      75             :     // 68, 69, 70 were winch events
      76             :     ZIGZAG_STORE_A = 71,
      77             :     ZIGZAG_STORE_B = 72,
      78             :     LAND_REPO_ACTIVE = 73,
      79             :     STANDBY_ENABLE = 74,
      80             :     STANDBY_DISABLE = 75,
      81             : 
      82             :     // Fence events
      83             :     FENCE_ALT_MAX_ENABLE = 76,
      84             :     FENCE_ALT_MAX_DISABLE = 77,
      85             :     FENCE_CIRCLE_ENABLE = 78,
      86             :     FENCE_CIRCLE_DISABLE = 79,
      87             :     FENCE_ALT_MIN_ENABLE = 80,
      88             :     FENCE_ALT_MIN_DISABLE = 81,
      89             :     FENCE_POLYGON_ENABLE = 82,
      90             :     FENCE_POLYGON_DISABLE = 83,
      91             : 
      92             :     // if the EKF's source input set is changed (e.g. via a switch or
      93             :     // a script), we log an event:
      94             :     EK3_SOURCES_SET_TO_PRIMARY = 85,
      95             :     EK3_SOURCES_SET_TO_SECONDARY = 86,
      96             :     EK3_SOURCES_SET_TO_TERTIARY = 87,
      97             : 
      98             :     AIRSPEED_PRIMARY_CHANGED = 90,
      99             : 
     100             :     SURFACED = 163,
     101             :     NOT_SURFACED = 164,
     102             :     BOTTOMED = 165,
     103             :     NOT_BOTTOMED = 166,
     104             : 
     105             :     EKF_MAG_OFFSETS_SAVED = 167, // compass offsets learned by the EKF were saved on disarm
     106             : };
     107             : 
     108             : enum class LogDataID : uint8_t {
     109             :     AP_STATE = 7,
     110             : // SYSTEM_TIME_SET = 8,
     111             :     INIT_SIMPLE_BEARING = 9,
     112             : };
     113             : 
     114             : enum class LogErrorSubsystem : uint8_t {
     115             :     MAIN = 1,
     116             :     RADIO = 2,
     117             :     COMPASS = 3,
     118             :     OPTFLOW = 4,   // not used
     119             :     FAILSAFE_RADIO = 5,
     120             :     FAILSAFE_BATT = 6,
     121             :     FAILSAFE_GPS = 7,   // not used
     122             :     FAILSAFE_GCS = 8,
     123             :     FAILSAFE_FENCE = 9,
     124             :     FLIGHT_MODE = 10,
     125             :     GPS = 11,
     126             :     CRASH_CHECK = 12,
     127             :     FLIP = 13,
     128             :     AUTOTUNE = 14,  // not used
     129             :     PARACHUTES = 15,
     130             :     EKFCHECK = 16,
     131             :     FAILSAFE_EKFINAV = 17,
     132             :     BARO = 18,
     133             :     CPU = 19,
     134             :     FAILSAFE_ADSB = 20,
     135             :     TERRAIN = 21,
     136             :     NAVIGATION = 22,
     137             :     FAILSAFE_TERRAIN = 23,
     138             :     EKF_PRIMARY = 24,
     139             :     THRUST_LOSS_CHECK = 25,
     140             :     FAILSAFE_SENSORS = 26,
     141             :     FAILSAFE_LEAK = 27,
     142             :     PILOT_INPUT = 28,
     143             :     FAILSAFE_VIBE = 29,
     144             :     INTERNAL_ERROR = 30,
     145             :     FAILSAFE_DEADRECKON = 31
     146             : };
     147             : 
     148             : // bizarrely this enumeration has lots of duplicate values, offering
     149             : // very little in the way of typesafety
     150             : enum class LogErrorCode : uint8_t {
     151             : // general error codes
     152             :     ERROR_RESOLVED  = 0,
     153             :     FAILED_TO_INITIALISE = 1,
     154             :     UNHEALTHY = 4,
     155             : // subsystem specific error codes -- radio
     156             :     RADIO_LATE_FRAME = 2,
     157             : // subsystem specific error codes -- failsafe_thr, batt, gps
     158             :     FAILSAFE_RESOLVED = 0,
     159             :     FAILSAFE_OCCURRED = 1,
     160             : // subsystem specific error codes -- main
     161             :     MAIN_INS_DELAY = 1,
     162             : // subsystem specific error codes -- crash checker
     163             :     CRASH_CHECK_CRASH = 1,
     164             :     CRASH_CHECK_LOSS_OF_CONTROL = 2,
     165             : // subsystem specific error codes -- flip
     166             :     FLIP_ABANDONED = 2,
     167             : // subsystem specific error codes -- terrain
     168             :     MISSING_TERRAIN_DATA = 2,
     169             : // subsystem specific error codes -- navigation
     170             :     FAILED_TO_SET_DESTINATION = 2,
     171             :     RESTARTED_RTL = 3,
     172             :     FAILED_CIRCLE_INIT = 4,
     173             :     DEST_OUTSIDE_FENCE = 5,
     174             :     RTL_MISSING_RNGFND = 6,
     175             : // subsystem specific error codes -- internal_error
     176             :     INTERNAL_ERRORS_DETECTED = 1,
     177             : 
     178             : // parachute failed to deploy because of low altitude or landed
     179             :     PARACHUTE_TOO_LOW = 2,
     180             :     PARACHUTE_LANDED = 3,
     181             : // EKF check definitions
     182             :     EKFCHECK_BAD_VARIANCE = 2,
     183             :     EKFCHECK_VARIANCE_CLEARED = 0,
     184             : // Baro specific error codes
     185             :     BARO_GLITCH = 2,
     186             :     BAD_DEPTH = 3, // sub-only
     187             : // GPS specific error codes
     188             :     GPS_GLITCH = 2,
     189             : };
     190             : 
     191             : class AP_Logger
     192             : {
     193             :     friend class AP_Logger_Backend; // for _num_types
     194             :     friend class AP_Logger_RateLimiter;
     195             : 
     196             : public:
     197             :     FUNCTOR_TYPEDEF(vehicle_startup_message_Writer, void);
     198             : 
     199             :     AP_Logger();
     200             : 
     201             :     /* Do not allow copies */
     202             :     CLASS_NO_COPY(AP_Logger);
     203             : 
     204             :     // get singleton instance
     205  1817285678 :     static AP_Logger *get_singleton(void) {
     206  1817285678 :         return _singleton;
     207             :     }
     208             : 
     209             :     // initialisation
     210             :     void init(const AP_Int32 &log_bitmask, const struct LogStructure *structure, uint8_t num_types);
     211             :     void set_num_types(uint8_t num_types) { _num_types = num_types; }
     212             : 
     213             :     bool CardInserted(void);
     214             :     bool _log_pause;
     215             : 
     216             :     // pause logging if aux switch is active and log rate limit enabled
     217           0 :     void log_pause(bool value) {
     218           0 :         _log_pause = value;
     219           0 :     }
     220             : 
     221             :     // erase handling
     222             :     void EraseAll();
     223             : 
     224             :     /* Write a block of data at current offset */
     225             :     void WriteBlock(const void *pBuffer, uint16_t size);
     226             : 
     227             :     /* Write block of data at current offset and return true if first backend succeeds*/
     228             :     bool WriteBlock_first_succeed(const void *pBuffer, uint16_t size);
     229             : 
     230             :     /* Write an *important* block of data at current offset */
     231             :     void WriteCriticalBlock(const void *pBuffer, uint16_t size);
     232             : 
     233             :     /* Write a block of replay data at current offset */
     234             :     bool WriteReplayBlock(uint8_t msg_id, const void *pBuffer, uint16_t size);
     235             : 
     236             :     // high level interface
     237             :     uint16_t find_last_log() const;
     238             :     void get_log_boundaries(uint16_t log_num, uint32_t & start_page, uint32_t & end_page);
     239             :     uint16_t get_num_logs(void);
     240             :     uint16_t get_max_num_logs();
     241             : 
     242             :     void setVehicle_Startup_Writer(vehicle_startup_message_Writer writer);
     243             : 
     244             :     void PrepForArming();
     245             : 
     246     4832902 :     void EnableWrites(bool enable) { _writes_enabled = enable; }
     247   266877798 :     bool WritesEnabled() const { return _writes_enabled; }
     248             : 
     249             :     void StopLogging();
     250             : 
     251             :     void Write_RTC();
     252             : 
     253             :     void Write_Parameter(const char *name, float value);
     254             :     void Write_Event(LogEvent id);
     255             :     void Write_Error(LogErrorSubsystem sub_system,
     256             :                      LogErrorCode error_code);
     257             :     void Write_RCIN(void);
     258             :     void Write_RCOUT(void);
     259             :     void Write_RSSI();
     260             :     void Write_Rally();
     261             : #if HAL_LOGGER_FENCE_ENABLED
     262             :     void Write_Fence();
     263             : #endif
     264             :     void Write_NamedValueFloat(const char *name, float value);
     265             :     void Write_Power(void);
     266             :     void Write_Radio(const mavlink_radio_t &packet);
     267             :     void Write_Message(const char *message);
     268             :     // support for multi-chunk messages:
     269      738876 :     uint8_t get_MSG_id() {
     270      738876 :         uint8_t ret = ++MSG_id;
     271      738876 :         if (ret > 0) {
     272      736859 :             return ret;
     273             :         }
     274        2017 :         return ++MSG_id;
     275             :     }
     276             :     void Write_MessageChunk(uint8_t id, const char *messagechunk, uint8_t chunk_seq);
     277             : 
     278             :     void Write_MessageF(const char *fmt, ...);
     279             :     void Write_Mode(uint8_t mode, const ModeReason reason);
     280             : 
     281             :     void Write_EntireMission();
     282             :     void Write_Command(const mavlink_command_int_t &packet,
     283             :                        uint8_t source_system,
     284             :                        uint8_t source_component,
     285             :                        MAV_RESULT result,
     286             :                        bool was_command_long=false);
     287        2026 :     void Write_MISE(const AP_Mission &mission, const AP_Mission::Mission_Command &cmd) {
     288        2026 :         Write_Mission_Cmd(mission, cmd, LOG_MISE_MSG);
     289        2026 :     }
     290             :     void Write_Mission_Cmd(const AP_Mission &mission,
     291             :                            const AP_Mission::Mission_Command &cmd,
     292             :                            LogMessages id);
     293             :     void Write_RallyPoint(uint8_t total,
     294             :                           uint8_t sequence,
     295             :                           const class RallyLocation &rally_point);
     296             :     void Write_SRTL(bool active, uint16_t num_points, uint16_t max_points, uint8_t action, const Vector3f& point);
     297             :     void Write_Winch(bool healthy, bool thread_end, bool moving, bool clutch, uint8_t mode, float desired_length, float length, float desired_rate, uint16_t tension, float voltage, int8_t temp);
     298             : 
     299             :     //! @deprecated Use the other signature with units and mults
     300             :     void Write(const char *name, const char *labels, const char *fmt, ...);
     301             :     void Write(const char *name, const char *labels, const char *units, const char *mults, const char *fmt, ...);
     302             :     //! @deprecated Use the other signature with units and mults
     303             :     void WriteStreaming(const char *name, const char *labels, const char *fmt, ...);
     304             :     void WriteStreaming(const char *name, const char *labels, const char *units, const char *mults, const char *fmt, ...);
     305             :     //! @deprecated Use the other signature with units and mults
     306             :     void WriteCritical(const char *name, const char *labels, const char *fmt, ...);
     307             :     void WriteCritical(const char *name, const char *labels, const char *units, const char *mults, const char *fmt, ...);
     308             :     void WriteV(const char *name, const char *labels, const char *units, const char *mults, const char *fmt, va_list arg_list, bool is_critical=false, bool is_streaming=false);
     309             : 
     310             :     void Write_PID(uint8_t msg_type, const class AP_PIDInfo &info);
     311             : 
     312             :     // returns true if logging of a message should be attempted
     313             :     bool should_log(uint32_t mask) const;
     314             : 
     315             :     bool logging_started(void) const;
     316             : 
     317             : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL || CONFIG_HAL_BOARD == HAL_BOARD_LINUX
     318             :     // currently only AP_Logger_File support this:
     319             :     void flush(void);
     320             : #endif
     321             : 
     322             :     void handle_mavlink_msg(class GCS_MAVLINK &, const mavlink_message_t &msg);
     323             : 
     324             :     void periodic_tasks(); // may want to split this into GCS/non-GCS duties
     325             : 
     326             :     // We may need to make sure data is loggable before starting the
     327             :     // EKF; when allow_start_ekf we should be able to log that data
     328             :     bool allow_start_ekf() const;
     329             : 
     330             :     // number of blocks that have been dropped
     331             :     uint32_t num_dropped(void) const;
     332             : 
     333             :     // access to public parameters
     334             :     void set_force_log_disarmed(bool force_logging) { _force_log_disarmed = force_logging; }
     335        1103 :     void set_long_log_persist(bool b) { _force_long_log_persist = b; }
     336             :     bool log_while_disarmed(void) const;
     337             :     bool in_log_persistance(void) const;
     338   210429284 :     uint8_t log_replay(void) const { return _params.log_replay; }
     339             : 
     340             :     vehicle_startup_message_Writer _vehicle_messages;
     341             : 
     342             :     enum class LogDisarmed : uint8_t {
     343             :         NONE = 0,
     344             :         LOG_WHILE_DISARMED = 1,
     345             :         LOG_WHILE_DISARMED_NOT_USB = 2,
     346             :         LOG_WHILE_DISARMED_DISCARD = 3,
     347             :     };
     348             : 
     349             :     // parameter support
     350             :     static const struct AP_Param::GroupInfo        var_info[];
     351             :     struct {
     352             :         AP_Int8 backend_types;
     353             :         AP_Int16 file_bufsize; // in kilobytes
     354             :         AP_Int8 file_disarm_rot;
     355             :         AP_Enum<LogDisarmed> log_disarmed;
     356             :         AP_Int8 log_replay;
     357             :         AP_Int8 mav_bufsize; // in kilobytes
     358             :         AP_Int16 file_timeout; // in seconds
     359             :         AP_Int16 min_MB_free;
     360             :         AP_Float file_ratemax;
     361             :         AP_Float mav_ratemax;
     362             :         AP_Float blk_ratemax;
     363             :         AP_Float disarm_ratemax;
     364             :         AP_Int16 max_log_files;
     365             :     } _params;
     366             : 
     367             :     const struct LogStructure *structure(uint16_t num) const;
     368             :     const struct UnitStructure *unit(uint16_t num) const;
     369             :     const struct MultiplierStructure *multiplier(uint16_t num) const;
     370             : 
     371             :     // methods for mavlink SYS_STATUS message (update_sensor_status_flags) and
     372             :     // arming checks. these cover all backends.
     373             :     bool logging_present() const;
     374             :     bool logging_enabled() const;
     375             :     bool logging_failed() const;
     376             : 
     377             :     // notify logging subsystem of an arming failure. This triggers
     378             :     // logging for HAL_LOGGER_ARM_PERSIST seconds
     379         114 :     void arming_failure() {
     380         114 :         _last_arming_failure_ms = AP_HAL::millis();
     381             : #if HAL_LOGGER_FILE_CONTENTS_ENABLED
     382         114 :         file_content_prepare_for_arming = true;
     383             : #endif
     384         114 :     }
     385             : 
     386             :     void set_vehicle_armed(bool armed_state);
     387  1284697172 :     bool vehicle_is_armed() const { return _armed; }
     388             : 
     389             :     void handle_log_send();
     390             :     bool in_log_download() const;
     391             : 
     392   117497053 :     static float quiet_nanf() { return NaNf; } // "AR"
     393             :     static double quiet_nan() { return nan("0x4152445550490a"); } // "ARDUPI"
     394             : 
     395             :     // returns true if msg_type is associated with a message
     396             :     bool msg_type_in_use(uint8_t msg_type) const;
     397             : 
     398             :     // calculate the length of a message using fields specified in
     399             :     // fmt; includes the message header. returns -1 on on error.
     400             :     int16_t Write_calc_msg_len(const char *fmt) const;
     401             : 
     402             :     // this structure looks much like struct LogStructure in
     403             :     // LogStructure.h, however we need to remember a pointer value for
     404             :     // efficiency of finding message types
     405             :     struct log_write_fmt {
     406             :         struct log_write_fmt *next;
     407             :         uint8_t msg_type;
     408             :         uint8_t msg_len;
     409             :         const char *name;
     410             :         const char *fmt;
     411             :         const char *labels;
     412             :         const char *units;
     413             :         const char *mults;
     414             :     } *log_write_fmts;
     415             : 
     416             :     // return (possibly allocating) a log_write_fmt for a name
     417             :     struct log_write_fmt *msg_fmt_for_name(const char *name, const char *labels, const char *units, const char *mults, const char *fmt, const bool direct_comp = false, const bool copy_strings = false);
     418             : 
     419             :     // output a FMT message for each backend if not already done so
     420             :     void Safe_Write_Emit_FMT(log_write_fmt *f);
     421             : 
     422             :     // get count of number of times we have started logging
     423         100 :     uint8_t get_log_start_count(void) const {
     424         100 :         return _log_start_count;
     425             :     }
     426             : 
     427             :     // add a filename to list of files to log. The name is copied internally so
     428             :     // the pointer passed can be freed after return.
     429             :     void log_file_content(const char *name);
     430             : 
     431             : protected:
     432             : 
     433             :     const struct LogStructure *_structures;
     434             :     uint8_t _num_types;
     435             :     const struct UnitStructure *_units = log_Units;
     436             :     const struct MultiplierStructure *_multipliers = log_Multipliers;
     437             :     const uint8_t _num_units = (sizeof(log_Units) / sizeof(log_Units[0]));
     438             :     const uint8_t _num_multipliers = (sizeof(log_Multipliers) / sizeof(log_Multipliers[0]));
     439             : 
     440             :     /* Write a block with specified importance */
     441             :     /* might be useful if you have a boolean indicating a message is
     442             :      * important... */
     443             :     void WritePrioritisedBlock(const void *pBuffer, uint16_t size,
     444             :                                bool is_critical);
     445             : 
     446             : private:
     447             :     #define LOGGER_MAX_BACKENDS 2
     448             :     uint8_t _next_backend;
     449             :     AP_Logger_Backend *backends[LOGGER_MAX_BACKENDS];
     450             :     const AP_Int32 *_log_bitmask;
     451             : 
     452             :     enum class Backend_Type : uint8_t {
     453             :         NONE       = 0,
     454             :         FILESYSTEM = (1<<0),
     455             :         MAVLINK    = (1<<1),
     456             :         BLOCK      = (1<<2),
     457             :     };
     458             : 
     459             :     enum class RCLoggingFlags : uint8_t {
     460             :         HAS_VALID_INPUT = 1U<<0,  // true if the system is receiving good RC values
     461             :         IN_RC_FAILSAFE =  1U<<1,  // true if the system is current in RC failsafe
     462             :         RC_PROTOCOL_FAILSAFE =  1U<<2,  // true if the RC Protocol library is indicating the RC receiver is indicating failsafe via its protocol
     463             :     };
     464             : 
     465             :     /*
     466             :      * support for dynamic Write; user-supplies name, format,
     467             :      * labels and values in a single function call.
     468             :      */
     469             :     HAL_Semaphore log_write_fmts_sem;
     470             : 
     471             :     // return (possibly allocating) a log_write_fmt for a name
     472             :     const struct log_write_fmt *log_write_fmt_for_msg_type(uint8_t msg_type) const;
     473             : 
     474             :     const struct LogStructure *structure_for_msg_type(uint8_t msg_type) const;
     475             : 
     476             :     // return a msg_type which is not currently in use (or -1 if none available)
     477             :     int16_t find_free_msg_type() const;
     478             : 
     479             :     // fill LogStructure with information about msg_type
     480             :     bool fill_logstructure(struct LogStructure &logstruct, const uint8_t msg_type) const;
     481             : 
     482             :     bool _armed;
     483             : 
     484             :     void backend_starting_new_log(const AP_Logger_Backend *backend);
     485             : 
     486             :     static AP_Logger *_singleton;
     487             : 
     488             : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
     489             :     bool validate_structure(const struct LogStructure *logstructure, int16_t offset);
     490             :     void validate_structures(const struct LogStructure *logstructures, const uint8_t num_types);
     491             :     void dump_structure_field(const struct LogStructure *logstructure, const char *label, const uint8_t fieldnum);
     492             :     void dump_structures(const struct LogStructure *logstructures, const uint8_t num_types);
     493             :     bool assert_same_fmt_for_name(const log_write_fmt *f,
     494             :                                   const char *name,
     495             :                                   const char *labels,
     496             :                                   const char *units,
     497             :                                   const char *mults,
     498             :                                   const char *fmt) const;
     499             :     const char* unit_name(const uint8_t unit_id);
     500             :     double multiplier_name(const uint8_t multiplier_id);
     501             :     bool seen_ids[256] = { };
     502             :     bool labels_string_is_good(const char *labels) const;
     503             : #endif
     504             : 
     505             :     bool _writes_enabled:1;
     506             :     bool _force_log_disarmed:1;
     507             :     bool _force_long_log_persist:1;
     508             : 
     509             :     struct log_write_fmt_strings {
     510             :         char name[LS_NAME_SIZE];
     511             :         char format[LS_FORMAT_SIZE];
     512             :         char labels[LS_LABELS_SIZE];
     513             :         char units[LS_UNITS_SIZE];
     514             :         char multipliers[LS_MULTIPLIERS_SIZE];
     515             :     };
     516             : 
     517             :     // remember formats for replay
     518             :     void save_format_Replay(const void *pBuffer);
     519             : 
     520             :     // io thread support
     521             :     bool _io_thread_started;
     522             : 
     523             :     void start_io_thread(void);
     524             :     void io_thread();
     525             :     bool check_crash_dump_save(void);
     526             : 
     527             : #if HAL_LOGGER_FILE_CONTENTS_ENABLED
     528             :     // support for logging file content
     529             :     struct file_list {
     530             :         struct file_list *next;
     531             :         const char *filename;
     532             :         char log_filename[16];
     533             :     };
     534             :     struct FileContent {
     535             :         void reset();
     536             :         void remove_and_free(file_list *victim);
     537             :         struct file_list *head, *tail;
     538             :         int fd{-1};
     539             :         uint32_t offset;
     540             :         bool fast;
     541             :         uint8_t counter;
     542             :         HAL_Semaphore sem;
     543             :     };
     544             :     FileContent normal_file_content;
     545             :     FileContent at_arm_file_content;
     546             : 
     547             :     // protect this with a semaphore?
     548             :     bool file_content_prepare_for_arming;
     549             : 
     550             :     void file_content_update(void);
     551             : 
     552             :     void prepare_at_arming_sys_file_logging();
     553             : 
     554             : #endif
     555             :     
     556             :     /* support for retrieving logs via mavlink: */
     557             : 
     558             :     enum class TransferActivity {
     559             :         IDLE,    // not doing anything, all file descriptors closed
     560             :         LISTING, // actively sending log_entry packets
     561             :         SENDING, // actively sending log_sending packets
     562             :     } transfer_activity = TransferActivity::IDLE;
     563             : 
     564             :     // last time we handled a log-transfer-over-mavlink message:
     565             :     uint32_t _last_mavlink_log_transfer_message_handled_ms;
     566             :     bool _warned_log_disarm; // true if we have sent a message warning to disarm for logging
     567             : 
     568             :     // next log list entry to send
     569             :     uint16_t _log_next_list_entry;
     570             : 
     571             :     // last log list entry to send
     572             :     uint16_t _log_last_list_entry;
     573             : 
     574             :     // number of log files
     575             :     uint16_t _log_num_logs;
     576             : 
     577             :     // log number for data send
     578             :     uint16_t _log_num_data;
     579             : 
     580             :     // offset in log
     581             :     uint32_t _log_data_offset;
     582             : 
     583             :     // size of log file
     584             :     uint32_t _log_data_size;
     585             : 
     586             :     // number of bytes left to send
     587             :     uint32_t _log_data_remaining;
     588             : 
     589             :     // start page of log data
     590             :     uint32_t _log_data_page;
     591             : 
     592             :     GCS_MAVLINK *_log_sending_link;
     593             :     HAL_Semaphore _log_send_sem;
     594             : 
     595             :     // last time arming failed, for backends
     596             :     uint32_t _last_arming_failure_ms;
     597             : 
     598             :     // count of number of times we've started logging
     599             :     // can be used by other subsystems to detect if they should log data
     600             :     uint8_t _log_start_count;
     601             : 
     602             :     void handle_log_message(class GCS_MAVLINK &, const mavlink_message_t &msg);
     603             : 
     604             :     void handle_log_request_list(class GCS_MAVLINK &, const mavlink_message_t &msg);
     605             :     void handle_log_request_data(class GCS_MAVLINK &, const mavlink_message_t &msg);
     606             :     void handle_log_request_erase(class GCS_MAVLINK &, const mavlink_message_t &msg);
     607             :     void handle_log_request_end(class GCS_MAVLINK &, const mavlink_message_t &msg);
     608             :     void end_log_transfer();
     609             :     void handle_log_send_listing(); // handle LISTING state
     610             :     void handle_log_sending(); // handle SENDING state
     611             :     bool handle_log_send_data(); // send data chunk to client
     612             : 
     613             :     void get_log_info(uint16_t log_num, uint32_t &size, uint32_t &time_utc);
     614             : 
     615             :     int16_t get_log_data(uint16_t log_num, uint16_t page, uint32_t offset, uint16_t len, uint8_t *data);
     616             : 
     617             :     /* end support for retrieving logs via mavlink: */
     618             : 
     619             : #if HAL_LOGGER_FILE_CONTENTS_ENABLED
     620             :     void log_file_content(FileContent &file_content, const char *filename);
     621             :     void file_content_update(FileContent &file_content);
     622             : #endif
     623             : 
     624             :     // support for multi-chunk messages:
     625             :     uint8_t MSG_id;
     626             : };
     627             : 
     628             : namespace AP {
     629             :     AP_Logger &logger();
     630             : };
     631             : 
     632             : #define LOGGER_WRITE_ERROR(subsys, err) AP::logger().Write_Error(subsys, err)
     633             : #define LOGGER_WRITE_EVENT(evt) AP::logger().Write_Event(evt)
     634             : 
     635             : #else
     636             : 
     637             : #define LOGGER_WRITE_ERROR(subsys, err)
     638             : #define LOGGER_WRITE_EVENT(evt)
     639             : 
     640             : #endif  // HAL_LOGGING_ENABLED

Generated by: LCOV version 1.14