• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mavlink / MAVSDK / 20183898345

13 Dec 2025 12:37AM UTC coverage: 47.268%. First build
20183898345

Pull #2737

github

web-flow
Merge c80a4ea11 into ffe67358f
Pull Request #2737: Add RemoteId plugin

0 of 569 new or added lines in 2 files covered. (0.0%)

17657 of 37355 relevant lines covered (47.27%)

459.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/mavsdk/plugins/remote_id/remote_id_impl.cpp
1
#include "remote_id_impl.h"
2
#include "mavlink_address.h"
3
#include "callback_list.tpp"
4

5
#include <cstring>
6

7
namespace mavsdk {
8

NEW
9
RemoteIdImpl::RemoteIdImpl(System& system) : PluginImplBase(system)
×
10
{
NEW
11
    _system_impl->register_plugin(this);
×
NEW
12
}
×
13

NEW
14
RemoteIdImpl::RemoteIdImpl(std::shared_ptr<System> system) : PluginImplBase(std::move(system))
×
15
{
NEW
16
    _system_impl->register_plugin(this);
×
NEW
17
}
×
18

NEW
19
RemoteIdImpl::~RemoteIdImpl()
×
20
{
NEW
21
    _system_impl->unregister_plugin(this);
×
NEW
22
}
×
23

NEW
24
void RemoteIdImpl::init()
×
25
{
NEW
26
    _system_impl->register_mavlink_message_handler(
×
27
        MAVLINK_MSG_ID_OPEN_DRONE_ID_ARM_STATUS,
NEW
28
        [this](const mavlink_message_t& message) { process_arm_status(message); },
×
29
        this);
NEW
30
}
×
31

NEW
32
void RemoteIdImpl::deinit()
×
33
{
NEW
34
    _system_impl->unregister_all_mavlink_message_handlers_blocking(this);
×
NEW
35
}
×
36

NEW
37
void RemoteIdImpl::enable() {}
×
38

NEW
39
void RemoteIdImpl::disable() {}
×
40

NEW
41
void RemoteIdImpl::process_arm_status(const mavlink_message_t& message)
×
42
{
43
    mavlink_open_drone_id_arm_status_t arm_status_msg;
NEW
44
    mavlink_msg_open_drone_id_arm_status_decode(&message, &arm_status_msg);
×
45

NEW
46
    RemoteId::ArmStatus new_status;
×
NEW
47
    new_status.status = (arm_status_msg.status == MAV_ODID_ARM_STATUS_GOOD_TO_ARM) ?
×
48
                            RemoteId::ArmStatus::Status::GoodToArm :
49
                            RemoteId::ArmStatus::Status::PreArmFailGeneric;
NEW
50
    new_status.error = std::string(
×
NEW
51
        arm_status_msg.error, strnlen(arm_status_msg.error, sizeof(arm_status_msg.error)));
×
52

53
    {
NEW
54
        std::lock_guard<std::mutex> lock(_arm_status_mutex);
×
NEW
55
        _arm_status = new_status;
×
NEW
56
    }
×
57

NEW
58
    std::lock_guard<std::mutex> lock(_subscription_mutex);
×
NEW
59
    _arm_status_subscriptions.queue(
×
NEW
60
        new_status, [this](const auto& func) { _system_impl->call_user_callback(func); });
×
NEW
61
}
×
62

63
RemoteId::ArmStatusHandle
NEW
64
RemoteIdImpl::subscribe_arm_status(const RemoteId::ArmStatusCallback& callback)
×
65
{
NEW
66
    std::lock_guard<std::mutex> lock(_subscription_mutex);
×
NEW
67
    return _arm_status_subscriptions.subscribe(callback);
×
NEW
68
}
×
69

NEW
70
void RemoteIdImpl::unsubscribe_arm_status(RemoteId::ArmStatusHandle handle)
×
71
{
NEW
72
    std::lock_guard<std::mutex> lock(_subscription_mutex);
×
NEW
73
    _arm_status_subscriptions.unsubscribe(handle);
×
NEW
74
}
×
75

NEW
76
RemoteId::ArmStatus RemoteIdImpl::arm_status() const
×
77
{
NEW
78
    std::lock_guard<std::mutex> lock(_arm_status_mutex);
×
NEW
79
    return _arm_status;
×
NEW
80
}
×
81

NEW
82
RemoteId::Result RemoteIdImpl::set_basic_id(RemoteId::BasicId basic_id)
×
83
{
NEW
84
    uint8_t id_type = static_cast<uint8_t>(basic_id.id_type);
×
NEW
85
    uint8_t ua_type = static_cast<uint8_t>(basic_id.ua_type);
×
86

87
    // Prepare uas_id (max 20 bytes, null-padded)
NEW
88
    uint8_t uas_id[20] = {};
×
NEW
89
    const size_t copy_len = std::min(basic_id.uas_id.size(), sizeof(uas_id));
×
NEW
90
    std::memcpy(uas_id, basic_id.uas_id.data(), copy_len);
×
91

92
    // id_or_mac is only used for received data, set to zero
NEW
93
    uint8_t id_or_mac[20] = {};
×
94

NEW
95
    return _system_impl->queue_message([&](MavlinkAddress mavlink_address, uint8_t channel) {
×
96
        mavlink_message_t message;
NEW
97
        mavlink_msg_open_drone_id_basic_id_pack_chan(
×
NEW
98
            mavlink_address.system_id,
×
NEW
99
            mavlink_address.component_id,
×
100
            channel,
101
            &message,
NEW
102
            _system_impl->get_system_id(),
×
NEW
103
            _system_impl->get_autopilot_id(),
×
NEW
104
            id_or_mac,
×
NEW
105
            id_type,
×
NEW
106
            ua_type,
×
NEW
107
            uas_id);
×
NEW
108
        return message;
×
NEW
109
    }) ?
×
110
               RemoteId::Result::Success :
NEW
111
               RemoteId::Result::Error;
×
112
}
113

NEW
114
RemoteId::Result RemoteIdImpl::set_location(RemoteId::Location location)
×
115
{
NEW
116
    uint8_t status = static_cast<uint8_t>(location.status);
×
NEW
117
    uint8_t height_reference = static_cast<uint8_t>(location.height_reference);
×
NEW
118
    uint8_t horizontal_accuracy = static_cast<uint8_t>(location.horizontal_accuracy);
×
NEW
119
    uint8_t vertical_accuracy = static_cast<uint8_t>(location.vertical_accuracy);
×
NEW
120
    uint8_t barometer_accuracy = static_cast<uint8_t>(location.barometer_accuracy);
×
NEW
121
    uint8_t speed_accuracy = static_cast<uint8_t>(location.speed_accuracy);
×
NEW
122
    uint8_t timestamp_accuracy = static_cast<uint8_t>(location.timestamp_accuracy);
×
123

124
    // Convert units
NEW
125
    int32_t latitude = static_cast<int32_t>(location.latitude_deg * 1e7);
×
NEW
126
    int32_t longitude = static_cast<int32_t>(location.longitude_deg * 1e7);
×
NEW
127
    uint16_t direction = static_cast<uint16_t>(location.direction_deg * 100);
×
NEW
128
    uint16_t speed_horizontal = static_cast<uint16_t>(location.speed_horizontal_m_s * 100.0f);
×
NEW
129
    int16_t speed_vertical = static_cast<int16_t>(location.speed_vertical_m_s * 100.0f);
×
130

131
    // Convert timestamp from UTC microseconds to seconds after the full hour
132
    // timestamp = ((time_week_ms % (60*60*1000))) / 1000
NEW
133
    uint64_t time_us = location.time_utc_us;
×
NEW
134
    uint64_t time_ms = time_us / 1000;
×
NEW
135
    float timestamp = static_cast<float>((time_ms % (60ULL * 60ULL * 1000ULL))) / 1000.0f;
×
136

137
    // id_or_mac is only used for received data, set to zero
NEW
138
    uint8_t id_or_mac[20] = {};
×
139

NEW
140
    return _system_impl->queue_message([&](MavlinkAddress mavlink_address, uint8_t channel) {
×
141
        mavlink_message_t message;
NEW
142
        mavlink_msg_open_drone_id_location_pack_chan(
×
NEW
143
            mavlink_address.system_id,
×
NEW
144
            mavlink_address.component_id,
×
145
            channel,
146
            &message,
NEW
147
            _system_impl->get_system_id(),
×
NEW
148
            _system_impl->get_autopilot_id(),
×
NEW
149
            id_or_mac,
×
NEW
150
            status,
×
NEW
151
            direction,
×
NEW
152
            speed_horizontal,
×
NEW
153
            speed_vertical,
×
NEW
154
            latitude,
×
NEW
155
            longitude,
×
NEW
156
            location.altitude_barometric_m,
×
157
            location.altitude_geodetic_m,
NEW
158
            height_reference,
×
159
            location.height_m,
NEW
160
            horizontal_accuracy,
×
NEW
161
            vertical_accuracy,
×
NEW
162
            barometer_accuracy,
×
NEW
163
            speed_accuracy,
×
NEW
164
            timestamp,
×
NEW
165
            timestamp_accuracy);
×
NEW
166
        return message;
×
NEW
167
    }) ?
×
168
               RemoteId::Result::Success :
NEW
169
               RemoteId::Result::Error;
×
170
}
171

NEW
172
RemoteId::Result RemoteIdImpl::set_system(RemoteId::SystemId system)
×
173
{
NEW
174
    uint8_t operator_location_type = static_cast<uint8_t>(system.operator_location_type);
×
NEW
175
    uint8_t classification_type = static_cast<uint8_t>(system.classification_type);
×
NEW
176
    uint8_t category_eu = static_cast<uint8_t>(system.category_eu);
×
NEW
177
    uint8_t class_eu = static_cast<uint8_t>(system.class_eu);
×
178

179
    // Convert units
NEW
180
    int32_t operator_latitude = static_cast<int32_t>(system.operator_latitude_deg * 1e7);
×
NEW
181
    int32_t operator_longitude = static_cast<int32_t>(system.operator_longitude_deg * 1e7);
×
NEW
182
    uint16_t area_count = static_cast<uint16_t>(system.area_count);
×
NEW
183
    uint16_t area_radius = static_cast<uint16_t>(system.area_radius_m);
×
184

185
    // Convert timestamp from UTC microseconds to Unix seconds since 2019-01-01
186
    // Unix epoch for 2019-01-01 00:00:00 UTC is 1546300800
NEW
187
    constexpr uint64_t EPOCH_2019 = 1546300800ULL;
×
NEW
188
    uint64_t time_us = system.time_utc_us;
×
NEW
189
    uint64_t unix_seconds = time_us / 1000000ULL;
×
NEW
190
    uint32_t timestamp = 0;
×
NEW
191
    if (unix_seconds >= EPOCH_2019) {
×
NEW
192
        timestamp = static_cast<uint32_t>(unix_seconds - EPOCH_2019);
×
193
    }
194

195
    // id_or_mac is only used for received data, set to zero
NEW
196
    uint8_t id_or_mac[20] = {};
×
197

NEW
198
    return _system_impl->queue_message([&](MavlinkAddress mavlink_address, uint8_t channel) {
×
199
        mavlink_message_t message;
NEW
200
        mavlink_msg_open_drone_id_system_pack_chan(
×
NEW
201
            mavlink_address.system_id,
×
NEW
202
            mavlink_address.component_id,
×
203
            channel,
204
            &message,
NEW
205
            _system_impl->get_system_id(),
×
NEW
206
            _system_impl->get_autopilot_id(),
×
NEW
207
            id_or_mac,
×
NEW
208
            operator_location_type,
×
NEW
209
            classification_type,
×
NEW
210
            operator_latitude,
×
NEW
211
            operator_longitude,
×
NEW
212
            area_count,
×
NEW
213
            area_radius,
×
NEW
214
            system.area_ceiling_m,
×
215
            system.area_floor_m,
NEW
216
            category_eu,
×
NEW
217
            class_eu,
×
218
            system.operator_altitude_geo_m,
NEW
219
            timestamp);
×
NEW
220
        return message;
×
NEW
221
    }) ?
×
222
               RemoteId::Result::Success :
NEW
223
               RemoteId::Result::Error;
×
224
}
225

NEW
226
RemoteId::Result RemoteIdImpl::set_operator_id(RemoteId::OperatorId operator_id)
×
227
{
NEW
228
    uint8_t operator_id_type = static_cast<uint8_t>(operator_id.operator_id_type);
×
229

230
    // Prepare operator_id string (max 20 bytes, null-padded)
NEW
231
    char operator_id_str[20] = {};
×
NEW
232
    const size_t copy_len = std::min(operator_id.operator_id.size(), sizeof(operator_id_str));
×
NEW
233
    std::memcpy(operator_id_str, operator_id.operator_id.data(), copy_len);
×
234

235
    // id_or_mac is only used for received data, set to zero
NEW
236
    uint8_t id_or_mac[20] = {};
×
237

NEW
238
    return _system_impl->queue_message([&](MavlinkAddress mavlink_address, uint8_t channel) {
×
239
        mavlink_message_t message;
NEW
240
        mavlink_msg_open_drone_id_operator_id_pack_chan(
×
NEW
241
            mavlink_address.system_id,
×
NEW
242
            mavlink_address.component_id,
×
243
            channel,
244
            &message,
NEW
245
            _system_impl->get_system_id(),
×
NEW
246
            _system_impl->get_autopilot_id(),
×
NEW
247
            id_or_mac,
×
NEW
248
            operator_id_type,
×
NEW
249
            operator_id_str);
×
NEW
250
        return message;
×
NEW
251
    }) ?
×
252
               RemoteId::Result::Success :
NEW
253
               RemoteId::Result::Error;
×
254
}
255

NEW
256
RemoteId::Result RemoteIdImpl::set_self_id(RemoteId::SelfId self_id)
×
257
{
NEW
258
    uint8_t description_type = static_cast<uint8_t>(self_id.description_type);
×
259

260
    // Prepare description string (max 23 bytes, null-padded)
NEW
261
    char description[23] = {};
×
NEW
262
    const size_t copy_len = std::min(self_id.description.size(), sizeof(description));
×
NEW
263
    std::memcpy(description, self_id.description.data(), copy_len);
×
264

265
    // id_or_mac is only used for received data, set to zero
NEW
266
    uint8_t id_or_mac[20] = {};
×
267

NEW
268
    return _system_impl->queue_message([&](MavlinkAddress mavlink_address, uint8_t channel) {
×
269
        mavlink_message_t message;
NEW
270
        mavlink_msg_open_drone_id_self_id_pack_chan(
×
NEW
271
            mavlink_address.system_id,
×
NEW
272
            mavlink_address.component_id,
×
273
            channel,
274
            &message,
NEW
275
            _system_impl->get_system_id(),
×
NEW
276
            _system_impl->get_autopilot_id(),
×
NEW
277
            id_or_mac,
×
NEW
278
            description_type,
×
NEW
279
            description);
×
NEW
280
        return message;
×
NEW
281
    }) ?
×
282
               RemoteId::Result::Success :
NEW
283
               RemoteId::Result::Error;
×
284
}
285

286
} // namespace mavsdk
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc