3 #include <AP_Logger/AP_Logger.h>
4 #include "VehicleType.h"
8 // ignore cast errors in this case to keep complexity down
9 // on x86 where replay is run we don't care about cast alignment
10 #pragma GCC diagnostic ignored "-Wcast-align"
12 #define LOGREADER_MAX_FIELDS 30
14 #define streq(x, y) (!strcmp(x, y))
18 // constructor - create a parser for a MavLink message format
19 MsgHandler(const struct log_Format
&f
);
21 // retrieve a comma-separated list of all labels
22 void string_for_labels(char *buffer
, uint32_t bufferlen
);
24 // field_value - retrieve the value of a field from the supplied message
25 // these return false if the field was not found
27 bool field_value(uint8_t *msg
, const char *label
, R
&ret
);
29 bool field_value(uint8_t *msg
, const char *label
, Vector3f
&ret
);
30 bool field_value(uint8_t *msg
, const char *label
,
31 char *buffer
, uint8_t bufferlen
);
34 void require_field(uint8_t *msg
, const char *label
, R
&ret
)
36 if (! field_value(msg
, label
, ret
)) {
37 field_not_found(msg
, label
);
40 void require_field(uint8_t *msg
, const char *label
, char *buffer
, uint8_t bufferlen
);
41 float require_field_float(uint8_t *msg
, const char *label
);
42 uint8_t require_field_uint8_t(uint8_t *msg
, const char *label
);
43 int32_t require_field_int32_t(uint8_t *msg
, const char *label
);
44 uint16_t require_field_uint16_t(uint8_t *msg
, const char *label
);
45 int16_t require_field_int16_t(uint8_t *msg
, const char *label
);
49 void add_field(const char *_label
, uint8_t _type
, uint8_t _offset
,
53 void field_value_for_type_at_offset(uint8_t *msg
, uint8_t type
,
54 uint8_t offset
, R
&ret
);
56 struct format_field_info
{ // parsed field information
62 struct format_field_info field_info
[LOGREADER_MAX_FIELDS
];
65 size_t size_for_type_table
[52]; // maps field type (e.g. 'f') to e.g 4 bytes
67 struct format_field_info
*find_field_info(const char *label
);
69 void parse_format_fields();
70 void init_field_types();
71 void add_field_type(char type
, size_t size
);
72 uint8_t size_for_type(char type
);
75 struct log_Format f
; // the format we are a parser for
77 void location_from_msg(uint8_t *msg
, Location
&loc
, const char *label_lat
,
78 const char *label_long
, const char *label_alt
);
80 void ground_vel_from_msg(uint8_t *msg
,
82 const char *label_speed
,
83 const char *label_course
,
84 const char *label_vz
);
86 void attitude_from_msg(uint8_t *msg
,
88 const char *label_roll
,
89 const char *label_pitch
,
90 const char *label_yaw
);
91 [[noreturn
]] void field_not_found(uint8_t *msg
, const char *label
);
95 bool MsgHandler::field_value(uint8_t *msg
, const char *label
, R
&ret
)
97 struct format_field_info
*info
= find_field_info(label
);
102 uint8_t offset
= info
->offset
;
107 field_value_for_type_at_offset(msg
, info
->type
, offset
, ret
);
114 inline void MsgHandler::field_value_for_type_at_offset(uint8_t *msg
,
119 /* we register the types - add_field_type - so can we do without
120 * this switch statement somehow? */
123 ret
= (R
)(((uint8_t*)&msg
[offset
])[0]);
127 ret
= (R
)(((int16_t*)&msg
[offset
])[0]);
130 ret
= (R
)(((uint16_t*)&msg
[offset
])[0]);
133 ret
= (R
)(((uint16_t*)&msg
[offset
])[0]);
136 ret
= (R
)(((float*)&msg
[offset
])[0]);
140 ret
= (R
)(((uint32_t*)&msg
[offset
])[0]);
144 ret
= (R
)(((int32_t*)&msg
[offset
])[0]);
147 ret
= (R
)(((int64_t*)&msg
[offset
])[0]);
150 ret
= (R
)(((uint64_t*)&msg
[offset
])[0]);
153 ::printf("Unhandled format type (%c)\n", type
);