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

mavlink / MAVSDK / 4578731844

pending completion
4578731844

push

github

GitHub
Merge pull request #2012 from mavlink/rename-parent

885 of 885 new or added lines in 31 files covered. (100.0%)

7416 of 24250 relevant lines covered (30.58%)

21.54 hits per line

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

0.0
/src/mavsdk/plugins/shell/shell_impl.cpp
1
#include "shell_impl.h"
2
#include "system.h"
3
#include "callback_list.tpp"
4

5
namespace mavsdk {
6

7
template class CallbackList<std::string>;
8

9
void ShellImpl::init()
×
10
{
11
    _system_impl->register_mavlink_message_handler(
×
12
        MAVLINK_MSG_ID_SERIAL_CONTROL,
13
        [this](const mavlink_message_t& message) { process_shell_message(message); },
×
14
        this);
15
}
×
16

17
void ShellImpl::deinit()
×
18
{
19
    _system_impl->unregister_all_mavlink_message_handlers(this);
×
20
}
×
21

22
void ShellImpl::enable() {}
×
23

24
void ShellImpl::disable() {}
×
25

26
ShellImpl::ShellImpl(System& system) : PluginImplBase(system)
×
27
{
28
    _system_impl->register_plugin(this);
×
29
}
×
30

31
ShellImpl::ShellImpl(std::shared_ptr<System> system) : PluginImplBase(std::move(system))
×
32
{
33
    _system_impl->register_plugin(this);
×
34
}
×
35

36
ShellImpl::~ShellImpl()
×
37
{
38
    _system_impl->unregister_plugin(this);
×
39
}
×
40

41
Shell::Result ShellImpl::send(std::string command)
×
42
{
43
    if (!_system_impl->is_connected()) {
×
44
        return Shell::Result::NoSystem;
×
45
    }
46

47
    // In case a newline at the end of the command is missing, we add it here.
48
    if (command.back() != '\n') {
×
49
        command.append(1, '\n');
×
50
    }
51

52
    if (!send_command_message(command)) {
×
53
        return Shell::Result::ConnectionError;
×
54
    }
55

56
    return Shell::Result::Success;
×
57
}
58

59
Shell::ReceiveHandle ShellImpl::subscribe_receive(const Shell::ReceiveCallback& callback)
×
60
{
61
    std::lock_guard<std::mutex> lock(_receive.mutex);
×
62
    return _receive.callbacks.subscribe(callback);
×
63
}
64

65
void ShellImpl::unsubscribe_receive(Shell::ReceiveHandle handle)
×
66
{
67
    std::lock_guard<std::mutex> lock(_receive.mutex);
×
68
    _receive.callbacks.unsubscribe(handle);
×
69
}
×
70

71
bool ShellImpl::send_command_message(std::string command)
×
72
{
73
    mavlink_message_t message;
×
74

75
    while (command.length() > MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN) {
×
76
        mavlink_msg_serial_control_pack(
×
77
            _system_impl->get_own_system_id(),
×
78
            _system_impl->get_own_component_id(),
×
79
            &message,
80
            static_cast<uint8_t>(SERIAL_CONTROL_DEV::SERIAL_CONTROL_DEV_SHELL),
81
            0,
82
            timeout_ms,
83
            0,
84
            static_cast<uint8_t>(MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN),
85
            reinterpret_cast<const uint8_t*>(command.c_str()),
×
86
            _system_impl->get_system_id(),
×
87
            _system_impl->get_autopilot_id());
×
88
        command.erase(0, MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN);
×
89
        if (!_system_impl->send_message(message)) {
×
90
            return false;
×
91
        }
92
    }
93

94
    uint8_t flags = 0;
×
95
    {
96
        // We only ask for a response if we have subscribed to a response.
97
        std::lock_guard<std::mutex> lock(_receive.mutex);
×
98
        if (!_receive.callbacks.empty()) {
×
99
            flags |= SERIAL_CONTROL_FLAG_RESPOND;
×
100
        }
101
    }
102

103
    uint8_t data[MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN]{};
×
104
    memcpy(data, command.c_str(), command.length());
×
105

106
    mavlink_msg_serial_control_pack(
×
107
        _system_impl->get_own_system_id(),
×
108
        _system_impl->get_own_component_id(),
×
109
        &message,
110
        static_cast<uint8_t>(SERIAL_CONTROL_DEV::SERIAL_CONTROL_DEV_SHELL),
111
        flags,
112
        timeout_ms,
113
        0,
114
        static_cast<uint8_t>(command.length()),
×
115
        data,
116
        _system_impl->get_system_id(),
×
117
        _system_impl->get_autopilot_id());
×
118

119
    return _system_impl->send_message(message);
×
120
}
121

122
void ShellImpl::process_shell_message(const mavlink_message_t& message)
×
123
{
124
    mavlink_serial_control_t serial_control;
×
125
    mavlink_msg_serial_control_decode(&message, &serial_control);
×
126

127
    // This adds an additional byte for the null termination.
128
    char str_copy[sizeof(serial_control.data) + 1]{0};
×
129

130
    const auto len =
131
        std::min(static_cast<std::size_t>(serial_control.count), sizeof(serial_control.data));
×
132

133
    memcpy(str_copy, serial_control.data, len);
×
134

135
    std::string response(str_copy);
×
136

137
    // For the NuttShell (nsh>) we see these characters being sent but we're not sure
138
    // what they are for, so we're removing them for now.
139
    auto index = response.find({32, 27, '[', 'K'});
×
140
    if (index != std::string::npos) {
×
141
        response.erase(index, 4);
×
142
    }
143

144
    std::lock_guard<std::mutex> lock(_receive.mutex);
×
145
    _receive.callbacks.queue(
×
146
        response, [this](const auto& func) { _system_impl->call_user_callback(func); });
×
147
}
×
148

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