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

mavlink / MAVSDK / 16665088909

01 Aug 2025 02:55AM UTC coverage: 46.166% (-0.1%) from 46.31%
16665088909

push

github

web-flow
Merge pull request #2630 from mavlink/pr-segfault-fixes

Stack-use-after-free and thread-safety fixes, CI additions, clang-format-19

241 of 320 new or added lines in 32 files covered. (75.31%)

39 existing lines in 10 files now uncovered.

16101 of 34876 relevant lines covered (46.17%)

361.1 hits per line

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

86.96
/src/mavsdk/plugins/component_metadata_server/component_metadata_server_impl.cpp
1
#include "component_metadata_server_impl.h"
2
#include "mavlink_address.h"
3
#include "mavlink_request_message_handler.h"
4
#include "callback_list.tpp"
5
#include "unused.h"
6
#include "fs_utils.h"
7
#include "crc32.h"
8

9
#include <string>
10
#include <json/json.h>
11

12
namespace mavsdk {
13

14
ComponentMetadataServerImpl::ComponentMetadataServerImpl(
1✔
15
    std::shared_ptr<ServerComponent> server_component) :
1✔
16
    ServerPluginImplBase(server_component)
1✔
17
{
18
    if (const char* env_p = std::getenv("MAVSDK_COMPONENT_METADATA_DEBUGGING")) {
1✔
19
        if (std::string(env_p) == "1") {
1✔
20
            LogDebug() << "Verbose component metadata logging is on";
1✔
21
            _verbose_debugging = true;
1✔
22
        }
23
    }
24

25
    _server_component_impl->register_plugin(this);
1✔
26
}
1✔
27

28
ComponentMetadataServerImpl::~ComponentMetadataServerImpl()
2✔
29
{
30
    _server_component_impl->unregister_plugin(this);
1✔
31
    if (_metadata_set) {
1✔
32
        std::error_code ec;
1✔
33
        std::filesystem::remove_all(_tmp_path, ec);
1✔
34
        if (ec) {
1✔
NEW
35
            LogErr() << "Error removing " << _tmp_path << ": " << ec.message();
×
36
        }
37
    }
38
}
2✔
39

40
void ComponentMetadataServerImpl::init()
1✔
41
{
42
    _server_component_impl->mavlink_request_message_handler().register_handler(
1✔
43
        MAVLINK_MSG_ID_COMPONENT_METADATA,
44
        [this](
1✔
45
            uint8_t source_sys_id, uint8_t source_comp_id, MavlinkRequestMessageHandler::Params) {
1✔
46
            UNUSED(source_sys_id);
1✔
47
            UNUSED(source_comp_id);
1✔
48
            return process_component_metadata_requested();
1✔
49
        },
50
        this);
51
}
1✔
52

53
void ComponentMetadataServerImpl::deinit()
1✔
54
{
55
    _server_component_impl->mavlink_request_message_handler().unregister_all_handlers(this);
1✔
56
}
1✔
57

58
std::optional<MAV_RESULT> ComponentMetadataServerImpl::process_component_metadata_requested()
1✔
59
{
60
    if (_verbose_debugging) {
1✔
61
        LogDebug() << "MAVLINK_MSG_ID_COMPONENT_METADATA request received";
1✔
62
    }
63

64
    const std::lock_guard lg{_mutex};
1✔
65

66
    if (!_metadata_set) {
1✔
67
        return MAV_RESULT_TEMPORARILY_REJECTED;
×
68
    }
69

70
    char general_metadata_uri[MAVLINK_MSG_COMPONENT_METADATA_FIELD_URI_LEN];
71
    snprintf(
1✔
72
        general_metadata_uri, sizeof(general_metadata_uri), "mftp://%s", kComponentGeneralFilename);
73
    _server_component_impl->queue_message([&](MavlinkAddress mavlink_address, uint8_t channel) {
1✔
74
        mavlink_message_t message;
75
        mavlink_msg_component_metadata_pack_chan(
2✔
76
            mavlink_address.system_id,
1✔
77
            mavlink_address.component_id,
1✔
78
            channel,
79
            &message,
80
            _server_component_impl->get_time().elapsed_ms(),
1✔
81
            _comp_info_general_crc,
82
            general_metadata_uri);
1✔
83
        return message;
1✔
84
    });
85

86
    return MAV_RESULT_ACCEPTED;
1✔
87
}
1✔
88
void ComponentMetadataServerImpl::set_metadata(
1✔
89
    const std::vector<ComponentMetadataServer::Metadata>& metadata)
90
{
91
    const std::lock_guard lg{_mutex};
1✔
92
    if (_metadata_set) {
1✔
93
        LogErr() << "metadata already set";
×
94
        return;
×
95
    }
96

97
    // Create tmp directory as ftp root directory
98
    const auto tmp_option = create_tmp_directory("mavsdk-component-metadata-server");
2✔
99
    if (!tmp_option) {
1✔
100
        LogErr() << "Failed to create tmp directory";
×
101
        return;
×
102
    }
103
    _tmp_path = *tmp_option;
1✔
104

105
    if (_verbose_debugging) {
1✔
106
        LogDebug() << "Storing metadata under " << _tmp_path;
1✔
107
    }
108

109
    // Write files
110
    for (const auto& single_metadata : metadata) {
3✔
111
        Crc32 crc{};
2✔
112
        crc.add(
2✔
113
            reinterpret_cast<const uint8_t*>(single_metadata.json_metadata.data()),
2✔
114
            single_metadata.json_metadata.length());
2✔
115

116
        _metadata.emplace_back(single_metadata.type, crc.get());
2✔
117
        const std::filesystem::path path = _tmp_path / _metadata.back().filename;
2✔
118
        std::ofstream file(path, std::fstream::trunc | std::fstream::binary | std::fstream::out);
2✔
119
        if (!file) {
2✔
120
            LogErr() << "Failed to open " << path;
×
121
            continue;
×
122
        }
123
        file.write(single_metadata.json_metadata.data(), single_metadata.json_metadata.length());
2✔
124
    }
2✔
125

126
    if (!generate_component_metadata_general_file()) {
1✔
127
        return;
×
128
    }
129

130
    _metadata_set = true;
1✔
131
    _server_component_impl->mavlink_ftp_server().set_root_directory(_tmp_path.string());
1✔
132
}
1✔
133

134
bool ComponentMetadataServerImpl::generate_component_metadata_general_file()
1✔
135
{
136
    Json::Value root;
1✔
137
    root["version"] = 1;
1✔
138
    Json::Value metadata_types = Json::arrayValue;
1✔
139
    for (const auto& metadata : _metadata) {
3✔
140
        Json::Value metadata_type;
2✔
141
        metadata_type["type"] = Json::Int{metadata.type};
2✔
142
        metadata_type["uri"] = "mftp://" + metadata.filename;
2✔
143
        metadata_type["fileCrc"] = Json::UInt{metadata.crc};
2✔
144
        metadata_types.append(metadata_type);
2✔
145
    }
2✔
146
    root["metadataTypes"] = metadata_types;
1✔
147

148
    const std::filesystem::path path = _tmp_path / kComponentGeneralFilename;
1✔
149
    std::ofstream file(path, std::fstream::trunc | std::fstream::binary | std::fstream::out);
1✔
150
    if (!file) {
1✔
151
        LogErr() << "Failed to open " << path;
×
152
        return false;
×
153
    }
154
    const std::string json_data = root.toStyledString();
1✔
155
    Crc32 crc{};
1✔
156
    crc.add(reinterpret_cast<const uint8_t*>(json_data.data()), json_data.length());
1✔
157
    _comp_info_general_crc = crc.get();
1✔
158
    file.write(json_data.data(), json_data.length());
1✔
159
    return true;
1✔
160
}
1✔
161

162
ComponentMetadataServerImpl::Metadata::Metadata(
2✔
163
    ComponentMetadataServer::MetadataType metadata_type, uint32_t crc_data) :
2✔
164
    crc(crc_data)
2✔
165
{
166
    switch (metadata_type) {
2✔
167
        case ComponentMetadataServer::MetadataType::Parameter:
1✔
168
            type = COMP_METADATA_TYPE_PARAMETER;
1✔
169
            filename = "parameters.json";
1✔
170
            break;
1✔
171
        case ComponentMetadataServer::MetadataType::Events:
1✔
172
            type = COMP_METADATA_TYPE_EVENTS;
1✔
173
            filename = "events.json";
1✔
174
            break;
1✔
175
        case ComponentMetadataServer::MetadataType::Actuators:
×
176
            type = COMP_METADATA_TYPE_ACTUATORS;
×
177
            filename = "actuators.json";
×
178
            break;
×
179
    }
180
}
2✔
181
} // 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

© 2025 Coveralls, Inc