~aleteoryx/muditaos

ref: 81e49a91cef1b9407d6e77a63cca09aac9fba22b muditaos/module-bluetooth/Bluetooth/CommandHandler.cpp -rw-r--r-- 4.5 KiB
81e49a91 — Pawel Olejniczak [EGD-2630] Add pairing passkey handling on bluetooth settings side 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "CommandHandler.hpp"

#include <utility>
#include <service-bluetooth/ServiceBluetooth.hpp>
#include <service-bluetooth/SettingsHolder.hpp>

#include <Service/Service.hpp>

#include "Device.hpp"
#include "BtCommand.hpp"

extern "C"
{
#include <module-bluetooth/lib/btstack/src/btstack_util.h>
}

namespace bluetooth
{
    namespace
    {
        [[nodiscard]] auto toString(bluetooth::Error::Code code) -> std::string
        {
            return utils::enumToString(code);
        }
    } // namespace

    CommandHandler::CommandHandler(sys::Service *service,
                                   std::shared_ptr<bluetooth::SettingsHolder> settings,
                                   std::shared_ptr<bluetooth::Profile> currentProfile,
                                   std::shared_ptr<bluetooth::AbstractDriver> driver)
        : service{service}, settings{std::move(settings)}, currentProfile{std::move(currentProfile)}, driver{std::move(
                                                                                                          driver)}
    {}

    Error::Code CommandHandler::handle(Command command)
    {
        switch (command.getType()) {
        case bluetooth::Command::PowerOn:
            return Error::Success;
        case bluetooth::Command::StartScan:
            return scan();
        case bluetooth::Command::StopScan:
            return stopScan();
        case bluetooth::Command::StartPan:
            return startPan();
        case bluetooth::Command::Pair:
            return pair(command.getArgument().value());
        case bluetooth::Command::VisibilityOn:
            return setVisibility(true);
        case bluetooth::Command::VisibilityOff:
            return setVisibility(false);
        case bluetooth::Command::ConnectAudio:
            return establishAudioConnection();
        case bluetooth::Command::DisconnectAudio:
            return disconnectAudioConnection();
        case bluetooth::Command::PowerOff:
            return Error::Success;
        case bluetooth::Command::None:
            return Error::Success;
        }
        return Error::LibraryError;
    }

    Error::Code CommandHandler::scan()
    {

        if (const auto ret = driver->scan(); ret.err != bluetooth::Error::Success) {
            LOG_ERROR("Cant start scan!: %s %" PRIu32 "", toString(ret.err).c_str(), ret.lib_code);
            return ret.err;
        }

        LOG_INFO("Scan started!");
        static_cast<ServiceBluetooth *>(service)->scanStartedCallback();
        // open new scan window
        return Error::Success;
    }

    Error::Code CommandHandler::stopScan()
    {
        driver->stopScan();
        static_cast<ServiceBluetooth *>(service)->scanStoppedCallback();
        return Error::Success;
    }

    Error::Code CommandHandler::startPan()
    {
        bluetooth::PAN::bnep_setup();
        if (const auto err = bluetooth::PAN::bnep_start(); err.err != bluetooth::Error::Success) {
            LOG_ERROR("PAN setup error: %s %" PRIu32, toString(err.err).c_str(), err.lib_code);
            return err.err;
        }
        return bluetooth::Error::Success;
    }

    Error::Code CommandHandler::setVisibility(bool visibility)
    {
        driver->setVisibility(visibility);
        settings->setValue(bluetooth::Settings::Visibility, static_cast<int>(visibility));
        return Error::Success;
    }

    Error::Code CommandHandler::establishAudioConnection()
    {
        currentProfile->setOwnerService(service);
        if (const auto status = currentProfile->init(); status != bluetooth::Error::Success) {
            return status;
        }

        currentProfile->connect();
        return Error::Success;
    }

    Error::Code CommandHandler::disconnectAudioConnection()
    {
        currentProfile->disconnect();
        return Error::Success;
    }
    Error::Code CommandHandler::pair(CommandArgument arg)
    {
        try {
            auto addrString = std::get<std::string>(arg);
            bd_addr_t addr;
            if (sscanf_bd_addr(addrString.c_str(), addr) != 0) {
                LOG_INFO("Pairing with %s", addrString.c_str());
                driver->pair(addr);
            }
            else {
                return Error::SystemError;
            }
        }
        catch (const std::bad_variant_access &) {
            return Error::SystemError;
        }
        return Error::Success;
    }
} // namespace bluetooth