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
|