M module-bluetooth/Bluetooth/CommandHandler.cpp => module-bluetooth/Bluetooth/CommandHandler.cpp +6 -0
@@ 69,6 69,12 @@ namespace bluetooth
return switchAudioProfile();
case bluetooth::Command::None:
return Error::Success;
+ case Command::StartRinging:
+ return profileManager->startRinging();
+ case Command::StopRinging:
+ return profileManager->stopRinging();
+ case Command::StartRouting:
+ return profileManager->initializeCall();
case Command::StartStream:
profileManager->start();
return Error::Success;
M module-bluetooth/Bluetooth/CommandHandler.hpp => module-bluetooth/Bluetooth/CommandHandler.hpp +3 -0
@@ 35,6 35,9 @@ namespace bluetooth
PowerOff,
Pair,
Unpair,
+ StartRinging,
+ StopRinging,
+ StartRouting,
StartStream,
StopStream,
SwitchProfile,
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp +15 -0
@@ 95,6 95,21 @@ namespace bluetooth
pimpl->stop();
}
+ auto A2DP::startRinging() const noexcept -> Error::Code
+ {
+ return Error::SystemError;
+ }
+
+ auto A2DP::stopRinging() const noexcept -> Error::Code
+ {
+ return Error::SystemError;
+ }
+
+ auto A2DP::initializeCall() const noexcept -> Error::Code
+ {
+ return Error::SystemError;
+ }
+
void A2DP::setAudioDevice(std::shared_ptr<bluetooth::BluetoothAudioDevice> audioDevice)
{
pimpl->setAudioDevice(std::move(audioDevice));
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.hpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.hpp +6 -0
@@ 30,6 30,12 @@ namespace bluetooth
void disconnect() override;
void start() override;
void stop() override;
+ /// @return SystemError - it's not posible to start ringing while there's A2DP active
+ [[nodiscard]] auto startRinging() const noexcept -> Error::Code override;
+ /// @return SystemError - it's not posible to stop ringing while there's A2DP active
+ [[nodiscard]] auto stopRinging() const noexcept -> Error::Code override;
+ /// @return SystemError - it's not posible to start routing while there's A2DP active
+ [[nodiscard]] auto initializeCall() const noexcept -> Error::Code override;
void setAudioDevice(std::shared_ptr<bluetooth::BluetoothAudioDevice> audioDevice) override;
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp +59 -3
@@ 8,6 8,7 @@
#include <log/log.hpp>
#include <service-evtmgr/Constants.hpp>
#include <service-audio/AudioMessage.hpp>
+#include <service-cellular/service-cellular/CellularServiceAPI.hpp>
#include <BluetoothWorker.hpp>
extern "C"
@@ 20,6 21,16 @@ extern "C"
namespace bluetooth
{
+ bool CellularInterfaceImpl::answerIncomingCall(sys::Service *service)
+ {
+ return CellularServiceAPI::AnswerIncomingCall(service);
+ }
+
+ bool CellularInterfaceImpl::hangupCall(sys::Service *service)
+ {
+ return CellularServiceAPI::HangupCall(service);
+ }
+
HSP::HSP() : pimpl(std::make_unique<HSPImpl>(HSPImpl()))
{}
@@ 71,6 82,24 @@ namespace bluetooth
pimpl->stop();
}
+ auto HSP::startRinging() const noexcept -> Error::Code
+ {
+ pimpl->startRinging();
+ return Error::Success;
+ }
+
+ auto HSP::stopRinging() const noexcept -> Error::Code
+ {
+ pimpl->stopRinging();
+ return Error::Success;
+ }
+
+ auto HSP::initializeCall() const noexcept -> Error::Code
+ {
+ pimpl->initializeCall();
+ return Error::Success;
+ }
+
HSP::~HSP() = default;
uint16_t HSP::HSPImpl::scoHandle = HCI_CON_HANDLE_INVALID;
@@ 78,6 107,7 @@ namespace bluetooth
std::array<char, commandBufferLength> HSP::HSPImpl::ATcommandBuffer;
std::array<uint8_t, serviceBufferLength> HSP::HSPImpl::serviceBuffer;
std::unique_ptr<SCO> HSP::HSPImpl::sco;
+ std::unique_ptr<CellularInterface> HSP::HSPImpl::cellularInterface = nullptr;
const sys::Service *HSP::HSPImpl::ownerService;
std::string HSP::HSPImpl::agServiceName = "PurePhone HSP";
bool HSP::HSPImpl::isConnected = false;
@@ 153,6 183,7 @@ namespace bluetooth
else {
scoHandle = hsp_subevent_audio_connection_complete_get_handle(event);
LOG_DEBUG("Audio connection established with SCO handle 0x%04x.\n", scoHandle);
+ cellularInterface->answerIncomingCall(const_cast<sys::Service *>(ownerService));
hci_request_sco_can_send_now_event();
RunLoop::trigger();
}
@@ 160,6 191,7 @@ namespace bluetooth
case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE:
LOG_DEBUG("Audio connection released.\n\n");
sendAudioEvent(audio::EventType::BlutoothHSPDeviceState, audio::Event::DeviceState::Disconnected);
+ cellularInterface->hangupCall(const_cast<sys::Service *>(ownerService));
scoHandle = HCI_CON_HANDLE_INVALID;
isConnected = false;
break;
@@ 185,12 217,20 @@ namespace bluetooth
}
}
+ void HSP::HSPImpl::establishAudioConnection()
+ {
+ LOG_DEBUG("Establish Audio connection to %s...\n", bd_addr_to_str(deviceAddr));
+ hsp_ag_establish_audio_connection();
+ }
+
auto HSP::HSPImpl::init() -> Error::Code
{
sco = std::make_unique<SCO>();
sco->setOwnerService(ownerService);
sco->init();
+ cellularInterface = std::make_unique<CellularInterfaceImpl>();
+
Profile::initL2cap();
Profile::initSdp();
@@ 233,7 273,7 @@ namespace bluetooth
void HSP::HSPImpl::setDeviceAddress(bd_addr_t addr)
{
bd_addr_copy(deviceAddr, addr);
- LOG_INFO("Address set!");
+ LOG_DEBUG("Address set!");
}
void HSP::HSPImpl::setOwnerService(const sys::Service *service)
@@ 250,12 290,28 @@ namespace bluetooth
if (!isConnected) {
connect();
}
- LOG_DEBUG("Establish Audio connection to %s...\n", bd_addr_to_str(deviceAddr));
- hsp_ag_establish_audio_connection();
}
void HSP::HSPImpl::stop()
{
+ stopRinging();
hsp_ag_release_audio_connection();
}
+ void HSP::HSPImpl::startRinging() const noexcept
+ {
+ LOG_DEBUG("Bluetooth ring started");
+ hsp_ag_start_ringing();
+ }
+
+ void HSP::HSPImpl::stopRinging() const noexcept
+ {
+ LOG_DEBUG("Bluetooth ring stopped");
+ hsp_ag_stop_ringing();
+ }
+
+ void HSP::HSPImpl::initializeCall() const noexcept
+ {
+ stopRinging();
+ establishAudioConnection();
+ }
} // namespace bluetooth
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.hpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.hpp +24 -1
@@ 9,7 9,19 @@
namespace bluetooth
{
-
+ class CellularInterface
+ {
+ public:
+ virtual ~CellularInterface() = default;
+ virtual bool answerIncomingCall(sys::Service *service) = 0;
+ virtual bool hangupCall(sys::Service *service) = 0;
+ };
+ class CellularInterfaceImpl : public CellularInterface
+ {
+ public:
+ bool answerIncomingCall(sys::Service *service) override;
+ bool hangupCall(sys::Service *service) override;
+ };
class HSP : public Profile
{
static constexpr auto CLASS_OF_DEVICE = 0x400204;
@@ 31,6 43,17 @@ namespace bluetooth
void disconnect() override;
void start() override;
void stop() override;
+ /// @brief Starts ring
+ /// @return Success
+ [[nodiscard]] auto startRinging() const noexcept -> Error::Code override;
+ /// @brief Stops ring
+ /// @return Success
+ [[nodiscard]] auto stopRinging() const noexcept -> Error::Code override;
+ /// @brief Initializes bluetooth audio call which is divided into two parts:
+ /// - Ring stop
+ /// - SCO link establishment
+ /// @return Success
+ [[nodiscard]] auto initializeCall() const noexcept -> Error::Code override;
void setAudioDevice(std::shared_ptr<bluetooth::BluetoothAudioDevice> audioDevice) override
{}
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSPImpl.hpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSPImpl.hpp +6 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 19,6 19,9 @@ namespace bluetooth
auto init() -> Error::Code;
void start();
void stop();
+ void startRinging() const noexcept;
+ void stopRinging() const noexcept;
+ void initializeCall() const noexcept;
void connect();
void disconnect();
void setDeviceAddress(bd_addr_t addr);
@@ 29,11 32,13 @@ namespace bluetooth
static void sendAudioEvent(audio::EventType event, audio::Event::DeviceState state);
static void processHCIEvent(uint8_t *event);
static void processHSPEvent(uint8_t *event);
+ static void establishAudioConnection();
static std::array<uint8_t, serviceBufferLength> serviceBuffer;
static constexpr uint8_t rfcommChannelNr = 1;
static std::string agServiceName;
static uint16_t scoHandle;
static std::unique_ptr<SCO> sco;
+ static std::unique_ptr<CellularInterface> cellularInterface;
static std::array<char, commandBufferLength> ATcommandBuffer;
static bd_addr_t deviceAddr;
static const sys::Service *ownerService;
M module-bluetooth/Bluetooth/interface/profiles/Profile.hpp => module-bluetooth/Bluetooth/interface/profiles/Profile.hpp +9 -0
@@ 24,6 24,15 @@ namespace bluetooth
virtual void stop() = 0;
virtual void disconnect() = 0;
virtual void setAudioDevice(std::shared_ptr<bluetooth::BluetoothAudioDevice> audioDevice) = 0;
+ /// Starts ringing
+ /// @return Error code that determines, whether operation was successful or not
+ [[nodiscard]] virtual auto startRinging() const noexcept -> Error::Code = 0;
+ /// Stops ringing
+ /// @return Error code that determines, whether operation was successful or not
+ [[nodiscard]] virtual auto stopRinging() const noexcept -> Error::Code = 0;
+ /// Initializes call
+ /// @return Error code that determines, whether operation was successful or not
+ [[nodiscard]] virtual auto initializeCall() const noexcept -> Error::Code = 0;
protected:
static void initSdp();
M module-bluetooth/Bluetooth/interface/profiles/ProfileManager.cpp => module-bluetooth/Bluetooth/interface/profiles/ProfileManager.cpp +15 -0
@@ 95,6 95,21 @@ namespace bluetooth
return Error::Success;
}
+ auto ProfileManager::startRinging() -> Error::Code
+ {
+ return currentProfilePtr->startRinging();
+ }
+
+ auto ProfileManager::stopRinging() -> Error::Code
+ {
+ return currentProfilePtr->stopRinging();
+ }
+
+ auto ProfileManager::initializeCall() -> Error::Code
+ {
+ return currentProfilePtr->initializeCall();
+ }
+
auto ProfileManager::setAudioDevice(std::shared_ptr<BluetoothAudioDevice> device) -> Error::Code
{
if (currentProfilePtr == nullptr) {
M module-bluetooth/Bluetooth/interface/profiles/ProfileManager.hpp => module-bluetooth/Bluetooth/interface/profiles/ProfileManager.hpp +3 -0
@@ 46,6 46,9 @@ namespace bluetooth
auto start() -> Error::Code;
auto stop() -> Error::Code;
+ auto startRinging() -> Error::Code;
+ auto stopRinging() -> Error::Code;
+ auto initializeCall() -> Error::Code;
auto setAudioDevice(std::shared_ptr<BluetoothAudioDevice> device) -> Error::Code;
A module-bluetooth/bt_hsp_incoming_connection_establishment.puml => module-bluetooth/bt_hsp_incoming_connection_establishment.puml +15 -0
@@ 0,0 1,15 @@
+@startuml
+
+participant "Bluetooth Headset" as HS
+participant "Pure Phone" as AG
+
+ activate HS
+ activate AG
+ AG -> HS : Connection establishment
+ AG -> HS : Ring
+ ...
+ -> HS : User initiated action
+ HS -> AG : AT+CKPD=200
+ AG -> HS : OK
+ AG -> HS : SCO link establishment
+@enduml<
\ No newline at end of file
A module-bluetooth/bt_hsp_incoming_connection_establishment.svg => module-bluetooth/bt_hsp_incoming_connection_establishment.svg +28 -0
@@ 0,0 1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="301px" preserveAspectRatio="none" style="width:412px;height:301px;" version="1.1" viewBox="0 0 412 301" width="412px" zoomAndPan="magnify"><defs><filter height="300%" id="fcrkdomc6dxrv" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="58.2656" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="150" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150" x2="150" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="160" x2="160" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150" x2="160" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="117.5313" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="150" y="134.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150" x2="150" y1="134.5625" y2="252.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="160" x2="160" y1="134.5625" y2="252.0938"/><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="58.2656" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="351" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="351" x2="351" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="361" x2="361" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="351" x2="361" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="117.5313" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="351" y="134.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="351" x2="351" y1="134.5625" y2="252.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="361" x2="361" y1="134.5625" y2="252.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="155" x2="155" y1="38.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="155" x2="155" y1="106.5625" y2="134.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="155" x2="155" y1="134.5625" y2="261.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="355.5" x2="355.5" y1="38.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="355.5" x2="355.5" y1="106.5625" y2="134.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="355.5" x2="355.5" y1="134.5625" y2="261.0938"/><rect fill="#FEFECE" filter="url(#fcrkdomc6dxrv)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="144" x="81" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="130" x="88" y="22.9951">Bluetooth Headset</text><rect fill="#FEFECE" filter="url(#fcrkdomc6dxrv)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="144" x="81" y="260.0938"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="130" x="88" y="280.0889">Bluetooth Headset</text><rect fill="#FEFECE" filter="url(#fcrkdomc6dxrv)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="95" x="306.5" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="81" x="313.5" y="22.9951">Pure Phone</text><rect fill="#FEFECE" filter="url(#fcrkdomc6dxrv)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="95" x="306.5" y="260.0938"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="81" x="313.5" y="280.0889">Pure Phone</text><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="58.2656" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="150" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150" x2="150" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="160" x2="160" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150" x2="160" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="117.5313" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="150" y="134.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150" x2="150" y1="134.5625" y2="252.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="160" x2="160" y1="134.5625" y2="252.0938"/><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="58.2656" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="351" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="351" x2="351" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="361" x2="361" y1="48.2969" y2="106.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="351" x2="361" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fcrkdomc6dxrv)" height="117.5313" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="351" y="134.5625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="351" x2="351" y1="134.5625" y2="252.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="361" x2="361" y1="134.5625" y2="252.0938"/><polygon fill="#A80036" points="171,65.4297,161,69.4297,171,73.4297,167,69.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="165" x2="350" y1="69.4297" y2="69.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="167" x="177" y="64.3638">Connection establishment</text><polygon fill="#A80036" points="171,94.5625,161,98.5625,171,102.5625,167,98.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="165" x2="350" y1="98.5625" y2="98.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="27" x="177" y="93.4966">Ring</text><polygon fill="#A80036" points="138,151.6953,148,155.6953,138,159.6953,142,155.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="3" x2="144" y1="155.6953" y2="155.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="128" x="10" y="150.6294">User initiated action</text><polygon fill="#A80036" points="339,180.8281,349,184.8281,339,188.8281,343,184.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="160" x2="345" y1="184.8281" y2="184.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="97" x="167" y="179.7622">AT+CKPD=200</text><polygon fill="#A80036" points="171,209.9609,161,213.9609,171,217.9609,167,213.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="165" x2="350" y1="213.9609" y2="213.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="18" x="177" y="208.895">OK</text><polygon fill="#A80036" points="171,239.0938,161,243.0938,171,247.0938,167,243.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="165" x2="350" y1="243.0938" y2="243.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="148" x="177" y="238.0278">SCO link establishment</text><!--
+@startuml
+
+participant "Bluetooth Headset" as HS
+participant "Pure Phone" as AG
+
+ activate HS
+ activate AG
+ AG -> HS : Connection establishment
+ AG -> HS : Ring
+ ...
+ -> HS : User initiated action
+ HS -> AG : AT+CKPD=200
+ AG -> HS : OK
+ AG -> HS : SCO link establishment
+@enduml
+
+PlantUML version 1.2018.13(Mon Nov 26 18:11:51 CET 2018)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 11.0.10+9-Ubuntu-0ubuntu1.20.04
+Operating System: Linux
+OS Version: 5.8.0-50-generic
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg><
\ No newline at end of file
A module-bluetooth/bt_hsp_ring_handler.puml => module-bluetooth/bt_hsp_ring_handler.puml +15 -0
@@ 0,0 1,15 @@
+@startuml
+start
+note right
+ Ringing
+end note
+while (Call terminated) is (no)
+ if (Answer a call) then (no)
+ else (yes)
+ :SCO link established;
+ break;
+ endif
+endwhile
+:Stop Ringing;
+stop
+@enduml
A module-bluetooth/bt_hsp_ring_handler.svg => module-bluetooth/bt_hsp_ring_handler.svg +28 -0
@@ 0,0 1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="360px" preserveAspectRatio="none" style="width:237px;height:360px;" version="1.1" viewBox="0 0 237 360" width="237px" zoomAndPan="magnify"><defs><filter height="300%" id="f1j9yvllgez01x" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><path d="M147.5,10 L147.5,18.5664 L127.5,22.5664 L147.5,26.5664 L147.5,35.1328 A0,0 0 0 0 147.5,35.1328 L214.5,35.1328 A0,0 0 0 0 214.5,35.1328 L214.5,20 L204.5,10 L147.5,10 A0,0 0 0 0 147.5,10 " fill="#FBFB77" filter="url(#f1j9yvllgez01x)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M204.5,10 L204.5,20 L214.5,20 L204.5,10 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="46" x="153.5" y="27.0669">Ringing</text><ellipse cx="117.5" cy="22.5664" fill="#000000" filter="url(#f1j9yvllgez01x)" rx="10" ry="10" style="stroke: none; stroke-width: 1.0;"/><rect fill="#FEFECE" filter="url(#f1j9yvllgez01x)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="147" x="44" y="159.2456"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="127" x="54" y="180.3843">SCO link established</text><polygon fill="#FEFECE" filter="url(#f1j9yvllgez01x)" points="79.5,110.8433,155.5,110.8433,167.5,122.8433,155.5,134.8433,79.5,134.8433,67.5,122.8433,79.5,110.8433" style="stroke: #A80036; stroke-width: 1.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="20" x="121.5" y="145.0537">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="76" x="79.5" y="126.6514">Answer a call</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="14" x="167.5" y="120.249">no</text><polygon fill="#FEFECE" filter="url(#f1j9yvllgez01x)" points="74,55.1328,161,55.1328,173,67.1328,161,79.1328,74,79.1328,62,67.1328,74,55.1328" style="stroke: #A80036; stroke-width: 1.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="14" x="121.5" y="89.3433">no</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="87" x="74" y="70.9409">Call terminated</text><rect fill="#FEFECE" filter="url(#f1j9yvllgez01x)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="99" x="68" y="275.2144"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="79" x="78" y="296.353">Stop Ringing</text><ellipse cx="117.5" cy="339.1831" fill="none" filter="url(#f1j9yvllgez01x)" rx="10" ry="10" style="stroke: #000000; stroke-width: 1.0;"/><ellipse cx="118" cy="339.6831" fill="#000000" filter="url(#f1j9yvllgez01x)" rx="6" ry="6" style="stroke: none; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="117.5" y1="193.2144" y2="207.2144"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="24" y1="207.2144" y2="207.2144"/><polygon fill="#A80036" points="34,203.2144,24,207.2144,34,211.2144,30,207.2144" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="117.5" y1="134.8433" y2="159.2456"/><polygon fill="#A80036" points="113.5,149.2456,117.5,159.2456,121.5,149.2456,117.5,153.2456" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="167.5" x2="225" y1="122.8433" y2="122.8433"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="225" x2="225" y1="67.1328" y2="122.8433"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="225" x2="173" y1="67.1328" y2="67.1328"/><polygon fill="#A80036" points="183,63.1328,173,67.1328,183,71.1328,179,67.1328" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="117.5" y1="79.1328" y2="110.8433"/><polygon fill="#A80036" points="113.5,100.8433,117.5,110.8433,121.5,100.8433,117.5,104.8433" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="62" x2="24" y1="67.1328" y2="67.1328"/><polygon fill="#A80036" points="20,162.3276,24,172.3276,28,162.3276,24,166.3276" style="stroke: #A80036; stroke-width: 1.5;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="24" x2="24" y1="67.1328" y2="255.2144"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="24" x2="117.5" y1="255.2144" y2="255.2144"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="117.5" y1="255.2144" y2="275.2144"/><polygon fill="#A80036" points="113.5,265.2144,117.5,275.2144,121.5,265.2144,117.5,269.2144" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="117.5" y1="32.5664" y2="55.1328"/><polygon fill="#A80036" points="113.5,45.1328,117.5,55.1328,121.5,45.1328,117.5,49.1328" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="117.5" x2="117.5" y1="309.1831" y2="329.1831"/><polygon fill="#A80036" points="113.5,319.1831,117.5,329.1831,121.5,319.1831,117.5,323.1831" style="stroke: #A80036; stroke-width: 1.0;"/><!--
+@startuml
+start
+note right
+ Ringing
+end note
+while (Call terminated) is (no)
+ if (Answer a call) then (no)
+ else (yes)
+ :SCO link established;
+ break;
+ endif
+endwhile
+:Stop Ringing;
+stop
+@enduml
+
+PlantUML version 1.2018.13(Mon Nov 26 18:11:51 CET 2018)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 11.0.10+9-Ubuntu-0ubuntu1.20.04
+Operating System: Linux
+OS Version: 5.8.0-50-generic
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg><
\ No newline at end of file
A module-bluetooth/bt_hsp_ring_trigger.puml => module-bluetooth/bt_hsp_ring_trigger.puml +14 -0
@@ 0,0 1,14 @@
+@startuml
+start
+note right
+ Call incoming
+end note
+:Service Cellular;
+:Application call;
+:Service Audio;
+:Service Bluetooth;
+if (Current profile allows ringing) then (yes)
+ :Ring;
+endif
+stop
+@enduml
A module-bluetooth/bt_hsp_ring_trigger.svg => module-bluetooth/bt_hsp_ring_trigger.svg +27 -0
@@ 0,0 1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="448px" preserveAspectRatio="none" style="width:263px;height:448px;" version="1.1" viewBox="0 0 263 448" width="263px" zoomAndPan="magnify"><defs><filter height="300%" id="fxo3rzh2br75o" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><path d="M145,10 L145,18.5664 L125,22.5664 L145,26.5664 L145,35.1328 A0,0 0 0 0 145,35.1328 L251,35.1328 A0,0 0 0 0 251,35.1328 L251,20 L241,10 L145,10 A0,0 0 0 0 145,10 " fill="#FBFB77" filter="url(#fxo3rzh2br75o)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M241,10 L241,20 L251,20 L241,10 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="85" x="151" y="27.0669">Call incoming</text><ellipse cx="115" cy="22.5664" fill="#000000" filter="url(#fxo3rzh2br75o)" rx="10" ry="10" style="stroke: none; stroke-width: 1.0;"/><rect fill="#FEFECE" filter="url(#fxo3rzh2br75o)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="115" x="57.5" y="55.1328"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="95" x="67.5" y="76.2715">Service Cellular</text><rect fill="#FEFECE" filter="url(#fxo3rzh2br75o)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="114" x="58" y="109.1016"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="94" x="68" y="130.2402">Application call</text><rect fill="#FEFECE" filter="url(#fxo3rzh2br75o)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="104" x="63" y="163.0703"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="84" x="73" y="184.209">Service Audio</text><rect fill="#FEFECE" filter="url(#fxo3rzh2br75o)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="130" x="50" y="217.0391"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="110" x="60" y="238.1777">Service Bluetooth</text><rect fill="#FEFECE" filter="url(#fxo3rzh2br75o)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="47" x="91.5" y="319.4102"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="27" x="101.5" y="340.5488">Ring</text><polygon fill="#FEFECE" filter="url(#fxo3rzh2br75o)" points="32,271.0078,198,271.0078,210,283.0078,198,295.0078,32,295.0078,20,283.0078,32,271.0078" style="stroke: #A80036; stroke-width: 1.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="20" x="119" y="305.2183">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="166" x="32" y="286.8159">Current profile allows ringing</text><polygon fill="#FEFECE" filter="url(#fxo3rzh2br75o)" points="115,373.3789,127,385.3789,115,397.3789,103,385.3789,115,373.3789" style="stroke: #A80036; stroke-width: 1.5;"/><ellipse cx="115" cy="427.3789" fill="none" filter="url(#fxo3rzh2br75o)" rx="10" ry="10" style="stroke: #000000; stroke-width: 1.0;"/><ellipse cx="115.5" cy="427.8789" fill="#000000" filter="url(#fxo3rzh2br75o)" rx="6" ry="6" style="stroke: none; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="32.5664" y2="55.1328"/><polygon fill="#A80036" points="111,45.1328,115,55.1328,119,45.1328,115,49.1328" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="89.1016" y2="109.1016"/><polygon fill="#A80036" points="111,99.1016,115,109.1016,119,99.1016,115,103.1016" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="143.0703" y2="163.0703"/><polygon fill="#A80036" points="111,153.0703,115,163.0703,119,153.0703,115,157.0703" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="197.0391" y2="217.0391"/><polygon fill="#A80036" points="111,207.0391,115,217.0391,119,207.0391,115,211.0391" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="295.0078" y2="319.4102"/><polygon fill="#A80036" points="111,309.4102,115,319.4102,119,309.4102,115,313.4102" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="210" x2="222" y1="283.0078" y2="283.0078"/><polygon fill="#A80036" points="218,326.3945,222,336.3945,226,326.3945,222,330.3945" style="stroke: #A80036; stroke-width: 1.5;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="222" x2="222" y1="283.0078" y2="385.3789"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="222" x2="127" y1="385.3789" y2="385.3789"/><polygon fill="#A80036" points="137,381.3789,127,385.3789,137,389.3789,133,385.3789" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="353.3789" y2="373.3789"/><polygon fill="#A80036" points="111,363.3789,115,373.3789,119,363.3789,115,367.3789" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="251.0078" y2="271.0078"/><polygon fill="#A80036" points="111,261.0078,115,271.0078,119,261.0078,115,265.0078" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="115" x2="115" y1="397.3789" y2="417.3789"/><polygon fill="#A80036" points="111,407.3789,115,417.3789,119,407.3789,115,411.3789" style="stroke: #A80036; stroke-width: 1.0;"/><!--
+@startuml
+start
+note right
+ Call incoming
+end note
+:Service Cellular;
+:Application call;
+:Service Audio;
+:Service Bluetooth;
+if (Current profile allows ringing) then (yes)
+ :Ring;
+endif
+stop
+@enduml
+
+PlantUML version 1.2018.13(Mon Nov 26 18:11:51 CET 2018)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 11.0.10+9-Ubuntu-0ubuntu1.20.04
+Operating System: Linux
+OS Version: 5.8.0-50-generic
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg><
\ No newline at end of file
M module-services/service-audio/ServiceAudio.cpp => module-services/service-audio/ServiceAudio.cpp +16 -3
@@ 10,6 10,8 @@
#include <service-bluetooth/Constants.hpp>
#include <service-bluetooth/ServiceBluetoothCommon.hpp>
#include <service-bluetooth/BluetoothMessage.hpp>
+#include <service-bluetooth/messages/AudioRouting.hpp>
+#include <service-bluetooth/messages/Ring.hpp>
#include <service-db/Settings.hpp>
#include <service-evtmgr/EventManagerServiceAPI.hpp>
@@ 319,9 321,16 @@ std::unique_ptr<AudioResponseMessage> ServiceAudio::HandleStart(const Operation:
auto input = audioMux.GetPlaybackInput(playbackType);
// stop bluetooth stream if available
if (bluetoothConnected) {
- LOG_DEBUG("Sending Bluetooth start stream request");
- bus.sendUnicast(std::make_shared<BluetoothMessage>(BluetoothMessage::Request::Play),
- service::name::bluetooth);
+ if (playbackType == audio::PlaybackType::CallRingtone) {
+ LOG_DEBUG("Sending Bluetooth start ringing");
+ bus.sendUnicast(std::make_shared<message::bluetooth::Ring>(message::bluetooth::Ring::State::Enable),
+ service::name::bluetooth);
+ }
+ else {
+ LOG_DEBUG("Sending Bluetooth start stream request");
+ bus.sendUnicast(std::make_shared<BluetoothMessage>(BluetoothMessage::Request::Play),
+ service::name::bluetooth);
+ }
}
AudioStart(input);
@@ 334,6 343,10 @@ std::unique_ptr<AudioResponseMessage> ServiceAudio::HandleStart(const Operation:
}
else if (opType == Operation::Type::Router) {
auto input = audioMux.GetRoutingInput(true);
+ if (bluetoothConnected) {
+ LOG_DEBUG("Sending Bluetooth start routing");
+ bus.sendUnicast(std::make_shared<message::bluetooth::StartAudioRouting>(), service::name::bluetooth);
+ }
AudioStart(input);
return std::make_unique<AudioStartRoutingResponse>(retCode, retToken);
}
M module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +18 -0
@@ 11,6 11,7 @@
#include <Service/Message.hpp>
#include <service-db/Settings.hpp>
#include "service-bluetooth/messages/AudioVolume.hpp"
+#include "service-bluetooth/messages/AudioRouting.hpp"
#include "service-bluetooth/messages/Connect.hpp"
#include "service-bluetooth/messages/Disconnect.hpp"
#include "service-bluetooth/messages/Status.hpp"
@@ 18,6 19,7 @@
#include "service-bluetooth/messages/BondedDevices.hpp"
#include "service-bluetooth/messages/Unpair.hpp"
#include "service-bluetooth/messages/SetDeviceName.hpp"
+#include "service-bluetooth/messages/Ring.hpp"
#include "SystemManager/messages/SentinelRegistrationMessage.hpp"
@@ 76,6 78,8 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
connectHandler<BluetoothMessage>();
connectHandler<BluetoothPairMessage>();
connectHandler<message::bluetooth::AudioVolume>();
+ connectHandler<message::bluetooth::Ring>();
+ connectHandler<message::bluetooth::StartAudioRouting>();
connectHandler<message::bluetooth::Connect>();
connectHandler<message::bluetooth::ConnectResult>();
connectHandler<message::bluetooth::Disconnect>();
@@ 319,6 323,20 @@ auto ServiceBluetooth::handle(message::bluetooth::AudioVolume *msg) -> std::shar
return sys::MessageNone{};
}
+auto ServiceBluetooth::handle(message::bluetooth::Ring *msg) -> std::shared_ptr<sys::Message>
+{
+ const auto enableRing = msg->enabled();
+ sendWorkerCommand(bluetooth::Command(enableRing ? bluetooth::Command::Type::StartRinging
+ : bluetooth::Command::Type::StopRinging));
+ return std::make_shared<sys::ResponseMessage>();
+}
+
+auto ServiceBluetooth::handle(message::bluetooth::StartAudioRouting *msg) -> std::shared_ptr<sys::Message>
+{
+ sendWorkerCommand(bluetooth::Command(bluetooth::Command::Type::StartRouting));
+ return std::make_shared<sys::ResponseMessage>();
+}
+
void ServiceBluetooth::startTimeoutTimer()
{
if (connectionTimeoutTimer.isValid()) {
M module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp => module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp +4 -1
@@ 45,7 45,8 @@ namespace message::bluetooth
class Disconnect;
class DisconnectResult;
class AudioVolume;
-
+ class Ring;
+ class StartAudioRouting;
} // namespace message::bluetooth
class ServiceBluetooth : public sys::Service
@@ 93,6 94,8 @@ class ServiceBluetooth : public sys::Service
[[nodiscard]] auto handle(sdesktop::developerMode::DeveloperModeRequest *msg) -> std::shared_ptr<sys::Message>;
[[nodiscard]] auto handle(BluetoothAudioStartMessage *msg) -> std::shared_ptr<sys::Message>;
[[nodiscard]] auto handle(message::bluetooth::AudioVolume *msg) -> std::shared_ptr<sys::Message>;
+ [[nodiscard]] auto handle(message::bluetooth::Ring *msg) -> std::shared_ptr<sys::Message>;
+ [[nodiscard]] auto handle(message::bluetooth::StartAudioRouting *msg) -> std::shared_ptr<sys::Message>;
};
namespace sys
A module-services/service-bluetooth/service-bluetooth/messages/AudioRouting.hpp => module-services/service-bluetooth/service-bluetooth/messages/AudioRouting.hpp +12 -0
@@ 0,0 1,12 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "service-bluetooth/BluetoothMessage.hpp"
+
+namespace message::bluetooth
+{
+ class StartAudioRouting : public BluetoothMessage
+ {};
+} // namespace message::bluetooth
A module-services/service-bluetooth/service-bluetooth/messages/Ring.hpp => module-services/service-bluetooth/service-bluetooth/messages/Ring.hpp +32 -0
@@ 0,0 1,32 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "service-bluetooth/BluetoothMessage.hpp"
+
+namespace message::bluetooth
+{
+ /// @brief Message that indicates whether to enable or disable bluetooth ring
+ class Ring : public BluetoothMessage
+ {
+ public:
+ enum class State : bool
+ {
+ Enable,
+ Disable
+ };
+
+ explicit Ring(State state) : state{state}
+ {}
+
+ /// @return True if bluetooth should ring, false otherwise
+ [[nodiscard]] auto enabled() const noexcept -> bool
+ {
+ return state == State::Enable;
+ }
+
+ private:
+ const State state;
+ };
+} // namespace message::bluetooth
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +9 -6
@@ 500,7 500,8 @@ void ServiceCellular::registerMessageHandlers()
connect(typeid(CellularHangupCallMessage), [&](sys::Message *request) -> sys::MessagePointer {
auto msg = static_cast<CellularHangupCallMessage *>(request);
- return handleCellularHangupCallMessage(msg);
+ handleCellularHangupCallMessage(msg);
+ return sys::MessageNone{};
});
connect(typeid(db::QueryResponse), [&](sys::Message *request) -> sys::MessagePointer {
@@ 2291,8 2292,7 @@ auto ServiceCellular::handleCellularCallRequestMessage(CellularCallRequestMessag
return std::make_shared<CellularResponseMessage>(request->isHandled());
}
-auto ServiceCellular::handleCellularHangupCallMessage(CellularHangupCallMessage *msg)
- -> std::shared_ptr<CellularResponseMessage>
+void ServiceCellular::handleCellularHangupCallMessage(CellularHangupCallMessage *msg)
{
auto channel = cmux->get(TS0710::Channel::Commands);
LOG_INFO("CellularHangupCall");
@@ 2303,14 2303,17 @@ auto ServiceCellular::handleCellularHangupCallMessage(CellularHangupCallMessage
if (!ongoingCall.endCall(CellularCall::Forced::True)) {
LOG_ERROR("Failed to end ongoing call");
}
- return std::make_shared<CellularResponseMessage>(true, msg->messageType);
+ bus.sendMulticast(std::make_shared<CellularResponseMessage>(true, msg->messageType),
+ sys::BusChannel::ServiceCellularNotifications);
}
else {
LOG_ERROR("Call not aborted");
- return std::make_shared<CellularResponseMessage>(false, msg->messageType);
+ bus.sendMulticast(std::make_shared<CellularResponseMessage>(false, msg->messageType),
+ sys::BusChannel::ServiceCellularNotifications);
}
}
- return std::make_shared<CellularResponseMessage>(false, msg->messageType);
+ bus.sendMulticast(std::make_shared<CellularResponseMessage>(false, msg->messageType),
+ sys::BusChannel::ServiceCellularNotifications);
}
auto ServiceCellular::handleDBQueryResponseMessage(db::QueryResponse *msg) -> std::shared_ptr<sys::ResponseMessage>
M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +1 -1
@@ 341,7 341,7 @@ class ServiceCellular : public sys::Service
auto handleCellularAnswerIncomingCallMessage(CellularMessage *msg) -> std::shared_ptr<CellularResponseMessage>;
auto handleCellularCallRequestMessage(CellularCallRequestMessage *msg) -> std::shared_ptr<CellularResponseMessage>;
- auto handleCellularHangupCallMessage(CellularHangupCallMessage *msg) -> std::shared_ptr<CellularResponseMessage>;
+ void handleCellularHangupCallMessage(CellularHangupCallMessage *msg);
auto handleDBQueryResponseMessage(db::QueryResponse *msg) -> std::shared_ptr<sys::ResponseMessage>;
auto handleCellularListCallsMessage(CellularMessage *msg) -> std::shared_ptr<sys::ResponseMessage>;
auto handleDBNotificatioMessage(db::NotificationMessage *msg) -> std::shared_ptr<sys::ResponseMessage>;
M module-utils/log/Logger.cpp => module-utils/log/Logger.cpp +1 -0
@@ 15,6 15,7 @@ namespace Log
{"ServiceCellular", logger_level::LOGINFO},
{"ServiceAntenna", logger_level::LOGINFO},
{"ServiceAudio", logger_level::LOGINFO},
+ {"ServiceBluetooth", logger_level::LOGINFO},
{"ServiceFota", logger_level::LOGINFO},
{"ServiceEink", logger_level::LOGINFO},
{"ServiceDB", logger_level::LOGINFO},