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

mavlink / MAVSDK / 16613073909

30 Jul 2025 03:56AM UTC coverage: 44.304% (-2.0%) from 46.31%
16613073909

Pull #2626

github

web-flow
Merge ed7bedb1f into c0a7c02a0
Pull Request #2626: core: flush after each Log* line

188 of 290 new or added lines in 23 files covered. (64.83%)

414 existing lines in 21 files now uncovered.

15335 of 34613 relevant lines covered (44.3%)

286.22 hits per line

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

75.94
/src/mavsdk/plugins/ftp/ftp_impl.cpp
1
#include <algorithm>
2
#include <functional>
3
#include <iostream>
4

5
#include "ftp_impl.h"
6
#include "system.h"
7

8
namespace mavsdk {
9

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

15
FtpImpl::FtpImpl(std::shared_ptr<System> system) : PluginImplBase(std::move(system))
24✔
16
{
17
    _system_impl->register_plugin(this);
24✔
18
}
24✔
19

20
FtpImpl::~FtpImpl()
48✔
21
{
22
    _system_impl->unregister_plugin(this);
24✔
23
}
48✔
24

25
void FtpImpl::init() {}
24✔
26

27
void FtpImpl::deinit() {}
24✔
28

29
void FtpImpl::enable() {}
24✔
30

31
void FtpImpl::disable() {}
24✔
32

33
void FtpImpl::download_async(
14✔
34
    const std::string& remote_path,
35
    const std::string& local_folder,
36
    bool use_burst,
37
    Ftp::DownloadCallback callback)
38
{
39
    _system_impl->mavlink_ftp_client().download_async(
14✔
40
        remote_path,
41
        local_folder,
42
        use_burst,
43
        [callback, this](
529✔
44
            MavlinkFtpClient::ClientResult result, MavlinkFtpClient::ProgressData progress_data) {
1,058✔
45
            if (callback) {
529✔
46
                _system_impl->call_user_callback(
1,058✔
47
                    [temp_callback = callback, result, progress_data, this]() {
48
                        temp_callback(
49
                            result_from_mavlink_ftp_result(result),
50
                            progress_data_from_mavlink_ftp_progress_data(progress_data));
51
                    });
52
            }
53
        });
529✔
54
}
14✔
55

56
void FtpImpl::upload_async(
7✔
57
    const std::string& local_file_path,
58
    const std::string& remote_folder,
59
    Ftp::UploadCallback callback)
60
{
61
    _system_impl->mavlink_ftp_client().upload_async(
7✔
62
        local_file_path,
63
        remote_folder,
64
        [callback, this](
104✔
65
            MavlinkFtpClient::ClientResult result, MavlinkFtpClient::ProgressData progress_data) {
208✔
66
            if (callback) {
104✔
67
                _system_impl->call_user_callback(
208✔
68
                    [temp_callback = callback, result, progress_data, this]() {
69
                        temp_callback(
70
                            result_from_mavlink_ftp_result(result),
71
                            progress_data_from_mavlink_ftp_progress_data(progress_data));
72
                    });
73
            }
74
        });
104✔
75
}
7✔
76

77
std::pair<Ftp::Result, Ftp::ListDirectoryData> FtpImpl::list_directory(const std::string& path)
2✔
78
{
79
    std::promise<std::pair<Ftp::Result, Ftp::ListDirectoryData>> prom;
2✔
80
    auto fut = prom.get_future();
2✔
81

82
    list_directory_async(path, [&prom](Ftp::Result result, Ftp::ListDirectoryData data) {
2✔
83
        prom.set_value(std::pair<Ftp::Result, Ftp::ListDirectoryData>(result, data));
2✔
84
    });
2✔
85
    return fut.get();
2✔
86
}
2✔
87

88
void FtpImpl::list_directory_async(const std::string& path, Ftp::ListDirectoryCallback callback)
2✔
89
{
90
    _system_impl->mavlink_ftp_client().list_directory_async(
2✔
91
        path,
92
        [callback, this](
2✔
93
            MavlinkFtpClient::ClientResult result,
94
            std::vector<std::string> dirs,
95
            std::vector<std::string> files) {
2✔
96
            if (callback) {
2✔
97
                _system_impl->call_user_callback([=]() {
4✔
98
                    callback(
99
                        result_from_mavlink_ftp_result(result),
100
                        Ftp::ListDirectoryData{dirs, files});
101
                });
102
            }
103
        });
2✔
104
}
2✔
105

106
Ftp::Result FtpImpl::create_directory(const std::string& path)
3✔
107
{
108
    std::promise<Ftp::Result> prom{};
3✔
109
    auto fut = prom.get_future();
3✔
110

111
    create_directory_async(path, [&prom](Ftp::Result result) { prom.set_value(result); });
6✔
112
    return fut.get();
3✔
113
}
3✔
114

115
void FtpImpl::create_directory_async(const std::string& path, Ftp::ResultCallback callback)
3✔
116
{
117
    _system_impl->mavlink_ftp_client().create_directory_async(
3✔
118
        path, [callback, this](MavlinkFtpClient::ClientResult result) {
9✔
119
            if (callback) {
3✔
120
                _system_impl->call_user_callback([temp_callback = callback, result, this]() {
6✔
121
                    temp_callback(result_from_mavlink_ftp_result(result));
122
                });
123
            }
124
        });
3✔
125
}
3✔
126

127
Ftp::Result FtpImpl::remove_directory(const std::string& path)
2✔
128
{
129
    std::promise<Ftp::Result> prom{};
2✔
130
    auto fut = prom.get_future();
2✔
131

132
    remove_directory_async(path, [&prom](Ftp::Result result) { prom.set_value(result); });
4✔
133

134
    return fut.get();
2✔
135
}
2✔
136

137
void FtpImpl::remove_directory_async(const std::string& path, Ftp::ResultCallback callback)
2✔
138
{
139
    _system_impl->mavlink_ftp_client().remove_directory_async(
2✔
140
        path, [callback, this](MavlinkFtpClient::ClientResult result) {
6✔
141
            if (callback) {
2✔
142
                _system_impl->call_user_callback([temp_callback = callback, result, this]() {
4✔
143
                    temp_callback(result_from_mavlink_ftp_result(result));
144
                });
145
            }
146
        });
2✔
147
}
2✔
148

149
Ftp::Result FtpImpl::remove_file(const std::string& path)
4✔
150
{
151
    // Add corruption detection
152
    const uint32_t STACK_GUARD = 0xDEADBEEF;
4✔
153
    uint32_t guard1 = STACK_GUARD;
4✔
154

155
    std::promise<Ftp::Result> prom;
4✔
156
    auto fut = prom.get_future();
4✔
157

158
    uint32_t guard2 = STACK_GUARD;
4✔
159

160
    // Store promise address for validation
161
    void* orig_prom_addr = &prom;
4✔
162
    void* orig_fut_addr = &fut;
4✔
163

164
    remove_file_async(path, [&, orig_prom_addr, orig_fut_addr](Ftp::Result result) {
4✔
165
        LogInfo() << "Setting promise value for remove_file";
4✔
166

167
        // Check for corruption before fulfillment
168
        if (guard1 != STACK_GUARD || guard2 != STACK_GUARD) {
4✔
NEW
169
            LogErr() << "Stack corruption detected around promise! guard1=" << std::hex << guard1
×
NEW
170
                     << " guard2=" << guard2;
×
NEW
171
            std::abort();
×
172
        }
173

174
        if (&prom != orig_prom_addr || &fut != orig_fut_addr) {
4✔
NEW
175
            LogErr() << "Promise/future address changed! prom: " << &prom << " vs "
×
NEW
176
                     << orig_prom_addr << " fut: " << &fut << " vs " << orig_fut_addr;
×
NEW
177
            std::abort();
×
178
        }
179

180
        prom.set_value(result);
4✔
181
    });
4✔
182

183
    // Check corruption before get()
184
    if (guard1 != STACK_GUARD || guard2 != STACK_GUARD) {
4✔
NEW
185
        LogErr() << "Stack corruption detected before fut.get()! guard1=" << std::hex << guard1
×
NEW
186
                 << " guard2=" << guard2;
×
NEW
187
        std::abort();
×
188
    }
189

190
    // Try to detect future corruption before calling get() - no exceptions available
191
    auto status = fut.wait_for(std::chrono::seconds(0));
4✔
192
    LogInfo() << "Future wait_for succeeded, status=" << (int)status;
4✔
193

194
    return fut.get();
4✔
195
}
4✔
196

197
void FtpImpl::remove_file_async(const std::string& path, Ftp::ResultCallback callback)
4✔
198
{
199
    _system_impl->mavlink_ftp_client().remove_file_async(
4✔
200
        path, [callback, this](MavlinkFtpClient::ClientResult result) {
12✔
201
            if (callback) {
4✔
202
                _system_impl->call_user_callback([temp_callback = callback, result, this]() {
8✔
203
                    temp_callback(result_from_mavlink_ftp_result(result));
204
                });
205
            }
206
        });
4✔
207
}
4✔
208

209
Ftp::Result FtpImpl::rename(const std::string& from_path, const std::string& to_path)
2✔
210
{
211
    // Add corruption detection
212
    const uint32_t STACK_GUARD = 0xDEADBEEF;
2✔
213
    uint32_t guard1 = STACK_GUARD;
2✔
214

215
    std::promise<Ftp::Result> prom{};
2✔
216
    auto fut = prom.get_future();
2✔
217

218
    uint32_t guard2 = STACK_GUARD;
2✔
219

220
    // Store promise address for validation
221
    void* orig_prom_addr = &prom;
2✔
222
    void* orig_fut_addr = &fut;
2✔
223

224
    rename_async(from_path, to_path, [&, orig_prom_addr, orig_fut_addr](Ftp::Result result) {
2✔
225
        LogInfo() << "Setting promise value for rename";
2✔
226

227
        // Check for corruption before fulfillment
228
        if (guard1 != STACK_GUARD || guard2 != STACK_GUARD) {
2✔
NEW
229
            LogErr() << "Stack corruption detected around promise! guard1=" << std::hex << guard1
×
NEW
230
                     << " guard2=" << guard2;
×
NEW
231
            std::abort();
×
232
        }
233

234
        if (&prom != orig_prom_addr || &fut != orig_fut_addr) {
2✔
NEW
235
            LogErr() << "Promise/future address changed! prom: " << &prom << " vs "
×
NEW
236
                     << orig_prom_addr << " fut: " << &fut << " vs " << orig_fut_addr;
×
NEW
237
            std::abort();
×
238
        }
239

240
        prom.set_value(result);
2✔
241
    });
2✔
242

243
    // Check corruption before get()
244
    if (guard1 != STACK_GUARD || guard2 != STACK_GUARD) {
2✔
NEW
245
        LogErr() << "Stack corruption detected before fut.get()! guard1=" << std::hex << guard1
×
NEW
246
                 << " guard2=" << guard2;
×
NEW
247
        std::abort();
×
248
    }
249

250
    // Try to detect future corruption before calling get() - no exceptions available
251
    auto status = fut.wait_for(std::chrono::seconds(0));
2✔
252
    LogInfo() << "Future wait_for succeeded, status=" << (int)status;
2✔
253

254
    return fut.get();
2✔
255
}
2✔
256

257
void FtpImpl::rename_async(
2✔
258
    const std::string& from_path, const std::string& to_path, Ftp::ResultCallback callback)
259
{
260
    _system_impl->mavlink_ftp_client().rename_async(
2✔
261
        from_path, to_path, [callback, this](MavlinkFtpClient::ClientResult result) {
6✔
262
            if (callback) {
2✔
263
                _system_impl->call_user_callback([temp_callback = callback, result, this]() {
4✔
264
                    temp_callback(result_from_mavlink_ftp_result(result));
265
                });
266
            }
267
        });
2✔
268
}
2✔
269

270
std::pair<Ftp::Result, bool>
271
FtpImpl::are_files_identical(const std::string& local_path, const std::string& remote_path)
3✔
272
{
273
    // Add corruption detection
274
    const uint32_t STACK_GUARD = 0xDEADBEEF;
3✔
275
    uint32_t guard1 = STACK_GUARD;
3✔
276

277
    std::promise<std::pair<Ftp::Result, bool>> prom{};
3✔
278
    auto fut = prom.get_future();
3✔
279

280
    uint32_t guard2 = STACK_GUARD;
3✔
281

282
    // Store promise address for validation
283
    void* orig_prom_addr = &prom;
3✔
284
    void* orig_fut_addr = &fut;
3✔
285

286
    are_files_identical_async(
3✔
287
        local_path,
288
        remote_path,
289
        [&, orig_prom_addr, orig_fut_addr](Ftp::Result result, bool identical) {
9✔
290
            LogInfo() << "Setting promise value for are_files_identical";
3✔
291

292
            // Check for corruption before fulfillment
293
            if (guard1 != STACK_GUARD || guard2 != STACK_GUARD) {
3✔
NEW
294
                LogErr() << "Stack corruption detected around promise! guard1=" << std::hex
×
NEW
295
                         << guard1 << " guard2=" << guard2;
×
NEW
296
                std::abort();
×
297
            }
298

299
            if (&prom != orig_prom_addr || &fut != orig_fut_addr) {
3✔
NEW
300
                LogErr() << "Promise/future address changed! prom: " << &prom << " vs "
×
NEW
301
                         << orig_prom_addr << " fut: " << &fut << " vs " << orig_fut_addr;
×
NEW
302
                std::abort();
×
303
            }
304

305
            prom.set_value(std::pair<Ftp::Result, bool>{result, identical});
3✔
306
        });
3✔
307

308
    // Check corruption before get()
309
    if (guard1 != STACK_GUARD || guard2 != STACK_GUARD) {
3✔
NEW
310
        LogErr() << "Stack corruption detected before fut.get()! guard1=" << std::hex << guard1
×
NEW
311
                 << " guard2=" << guard2;
×
NEW
312
        std::abort();
×
313
    }
314

315
    // Try to detect future corruption before calling get() - no exceptions available
316
    auto status = fut.wait_for(std::chrono::seconds(0));
3✔
317
    LogInfo() << "Future wait_for succeeded, status=" << (int)status;
3✔
318

319
    return fut.get();
3✔
320
}
3✔
321

322
void FtpImpl::are_files_identical_async(
3✔
323
    const std::string& local_path,
324
    const std::string& remote_path,
325
    Ftp::AreFilesIdenticalCallback callback)
326
{
327
    _system_impl->mavlink_ftp_client().are_files_identical_async(
3✔
328
        local_path,
329
        remote_path,
330
        [callback, this](MavlinkFtpClient::ClientResult result, bool identical) {
9✔
331
            if (callback) {
3✔
332
                _system_impl->call_user_callback(
6✔
333
                    [temp_callback = callback, result, identical, this]() {
334
                        temp_callback(result_from_mavlink_ftp_result(result), identical);
335
                    });
336
            }
337
        });
3✔
338
}
3✔
339

340
Ftp::Result FtpImpl::set_target_compid(uint8_t component_id)
×
341
{
342
    return result_from_mavlink_ftp_result(
×
343
        _system_impl->mavlink_ftp_client().set_target_compid(component_id));
×
344
}
345

346
Ftp::Result FtpImpl::result_from_mavlink_ftp_result(MavlinkFtpClient::ClientResult result)
649✔
347
{
348
    switch (result) {
649✔
349
        case MavlinkFtpClient::ClientResult::Unknown:
×
350
            return Ftp::Result::Unknown;
×
351
        case MavlinkFtpClient::ClientResult::Success:
19✔
352
            return Ftp::Result::Success;
19✔
353
        case MavlinkFtpClient::ClientResult::Next:
612✔
354
            return Ftp::Result::Next;
612✔
355
        case MavlinkFtpClient::ClientResult::Timeout:
3✔
356
            return Ftp::Result::Timeout;
3✔
357
        case MavlinkFtpClient::ClientResult::Busy:
×
358
            return Ftp::Result::Busy;
×
359
        case MavlinkFtpClient::ClientResult::FileIoError:
×
360
            return Ftp::Result::FileIoError;
×
361
        case MavlinkFtpClient::ClientResult::FileExists:
×
362
            return Ftp::Result::FileExists;
×
363
        case MavlinkFtpClient::ClientResult::FileDoesNotExist:
1✔
364
            return Ftp::Result::FileDoesNotExist;
1✔
365
        case MavlinkFtpClient::ClientResult::FileProtected:
×
366
            return Ftp::Result::FileProtected;
×
367
        case MavlinkFtpClient::ClientResult::InvalidParameter:
×
368
            return Ftp::Result::InvalidParameter;
×
369
        case MavlinkFtpClient::ClientResult::Unsupported:
×
370
            return Ftp::Result::Unsupported;
×
371
        case MavlinkFtpClient::ClientResult::ProtocolError:
14✔
372
            return Ftp::Result::ProtocolError;
14✔
373
        case MavlinkFtpClient::ClientResult::NoSystem:
×
374
            return Ftp::Result::NoSystem;
×
375
        default:
×
376
            return Ftp::Result::Unknown;
×
377
    }
378
}
379

380
Ftp::ProgressData
381
FtpImpl::progress_data_from_mavlink_ftp_progress_data(MavlinkFtpClient::ProgressData progress_data)
633✔
382
{
383
    return {progress_data.bytes_transferred, progress_data.total_bytes};
633✔
384
}
385

386
} // 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