// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "Constants.hpp" #include "service-bluetooth/ServiceBluetooth.hpp" #include "service-bluetooth/BluetoothMessage.hpp" #include #include #include #include #include #include #include #include "service-bluetooth/messages/Status.hpp" #include "service-bluetooth/messages/SetStatus.hpp" #include #include #include #include ServiceBluetooth::ServiceBluetooth() : sys::Service(service::name::bluetooth) { auto settings = std::make_unique(this); settingsHolder = std::make_shared(std::move(settings)); LOG_INFO("[ServiceBluetooth] Initializing"); } ServiceBluetooth::~ServiceBluetooth() { LOG_INFO("[ServiceBluetooth] Cleaning resources"); } // This code is experimental: // this means it is an init point of bluetooth feature handling sys::ReturnCodes ServiceBluetooth::InitHandler() { LOG_ERROR("Bluetooth experimental!"); worker = std::make_unique(this); connect(message::bluetooth::RequestBondedDevices(), [&](sys::Message *msg) { auto bondedDevicesStr = std::visit(bluetooth::StringVisitor(), this->settingsHolder->getValue(bluetooth::Settings::BondedDevices)); return std::make_shared( SettingsSerializer::fromString(bondedDevicesStr)); }); connect(message::bluetooth::RequestStatus(), [&](sys::Message *msg) { BluetoothStatus status; auto state = std::visit(bluetooth::IntVisitor(), settingsHolder->getValue(bluetooth::Settings::State)); auto visibility = std::visit(bluetooth::BoolVisitor(), settingsHolder->getValue(bluetooth::Settings::Visibility)); status.state = static_cast(state); status.visibility = visibility; return std::make_shared(status); }); connect(typeid(message::bluetooth::SetStatus), [&](sys::Message *msg) { auto setStatusMsg = static_cast(msg); auto btStatus = setStatusMsg->getStatus(); worker->setVisibility(btStatus.visibility); switch (btStatus.state) { case BluetoothStatus::State::On: worker->run(); break; case BluetoothStatus::State::Off: // TODO break; default: break; } return std::make_shared(btStatus); }); settingsHolder->onStateChange = [this]() { auto initialState = std::visit(bluetooth::IntVisitor(), this->settingsHolder->getValue(bluetooth::Settings::State)); if (static_cast(initialState) == BluetoothStatus::State::On) { this->worker->run(); } }; return sys::ReturnCodes::Success; } sys::ReturnCodes ServiceBluetooth::DeinitHandler() { return sys::ReturnCodes::Success; } sys::MessagePointer ServiceBluetooth::DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) { try { switch (static_cast(msg->messageType)) { case MessageType::BluetoothRequest: { BluetoothMessage *lmsg = dynamic_cast(msg); LOG_INFO("Bluetooth request!"); switch (lmsg->req) { case BluetoothMessage::Start: worker->run(); break; case BluetoothMessage::Scan: if (worker->scan()) { return std::make_shared(sys::ReturnCodes::Success); } else { return std::make_shared(sys::ReturnCodes::Failure); } case BluetoothMessage::StopScan: sendWorkerCommand(bluetooth::StopScan); break; case BluetoothMessage::PAN: { /// TODO request lwip first... /// because TODO blocking message - wrecks system LOG_INFO("Request LwIP running!"); // auto ret = message_lwip(this, LwIP_message::Request::Start); // if (ret != sys::ReturnCodes::Success) { // LOG_ERROR("Request for LwIP start failed"); // } // else { /// TODO request PPP LOG_INFO("Start PAN"); worker->start_pan(); // } } break; case BluetoothMessage::Visible: { static bool visibility = true; worker->setVisibility(visibility); visibility = !visibility; } break; case BluetoothMessage::Play: sendWorkerCommand(bluetooth::ConnectAudio); break; case BluetoothMessage::Stop: sendWorkerCommand(bluetooth::DisconnectAudio); break; default: break; } break; } case MessageType::BluetoothAddrResult: { auto addrMsg = static_cast(msg); worker->setDeviceAddress(addrMsg->addr); } break; case MessageType::BluetoothRequestStream: { auto result = std::make_shared(worker->currentProfile->getStreamData()); sys::Bus::SendUnicast(std::move(result), "ServiceAudio", this); LOG_INFO("Queues sent after a request!"); } break; default: break; } } catch (std::exception &ex) { LOG_ERROR("Exception on BtService!: %s", ex.what()); } return std::make_shared(); } sys::ReturnCodes ServiceBluetooth::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_ERROR("TODO"); return sys::ReturnCodes::Success; } void ServiceBluetooth::sendWorkerCommand(bluetooth::Command command) { xQueueSend(workerQueue, &command, portMAX_DELAY); }