M module-apps/messages/AppMessage.hpp => module-apps/messages/AppMessage.hpp +2 -2
@@ 196,8 196,8 @@ namespace app
gui::InputEvent event;
public:
- AppInputEventMessage(gui::InputEvent evt) : AppMessage(MessageType::AppInputEvent), event{evt} {};
- virtual ~AppInputEventMessage(){};
+ explicit AppInputEventMessage(gui::InputEvent evt) : AppMessage(MessageType::AppInputEvent), event{evt}
+ {}
const gui::InputEvent &getEvent()
{
M module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.cpp => module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.cpp +9 -0
@@ 3,6 3,7 @@
#include "BluetoothAudioDevice.hpp"
+#include <Audio/AudioCommon.hpp>
#include <Audio/Stream.hpp>
#include <cassert>
@@ 37,6 38,14 @@ auto BluetoothAudioDevice::Stop() -> audio::AudioDevice::RetCode
auto BluetoothAudioDevice::OutputVolumeCtrl(float vol) -> audio::AudioDevice::RetCode
{
+ constexpr auto avrcpMaxVolume = std::uint8_t{0x7F}; // from AVRCP documentation
+ const auto volumeToSet = static_cast<std::uint8_t>((vol / audio::maxVolume) * avrcpMaxVolume);
+ const auto status = avrcp_controller_set_absolute_volume(ctx->avrcp_cid, volumeToSet);
+ if (status != ERROR_CODE_SUCCESS) {
+ LOG_ERROR("Can't set volume level. Status %x", status);
+ return audio::AudioDevice::RetCode::Failure;
+ }
+ currentFormat.outputVolume = vol;
return audio::AudioDevice::RetCode::Success;
}
M module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.hpp => module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.hpp +1 -1
@@ 44,4 44,4 @@ namespace bluetooth
static constexpr Capabilities btCapabilities = {.usesDMA = false, .minBlockSize = 512U, .maxBlockSize = 512U};
};
-}; // namespace bluetooth
+} // namespace bluetooth
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp +1 -1
@@ 142,7 142,7 @@ namespace bluetooth
AVRCP::mediaTracker.local_seid = avdtp_local_seid(local_stream_endpoint);
avdtp_source_register_delay_reporting_category(AVRCP::mediaTracker.local_seid);
- AVRCP::init();
+ AVRCP::init(const_cast<sys::Service *>(ownerService));
// Initialize SDP,
sdp_init();
M module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp +22 -16
@@ 1,8 1,11 @@
-// 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
#include "AVRCP.hpp"
+#include <service-bluetooth/Constants.hpp>
+#include <service-bluetooth/messages/AudioVolume.hpp>
+
namespace bluetooth
{
@@ 11,6 14,7 @@ namespace bluetooth
MediaContext AVRCP::mediaTracker;
std::array<uint8_t, 200> AVRCP::sdpTargetServiceBuffer;
std::array<uint8_t, 200> AVRCP::sdpControllerServiceBuffer;
+ sys::Service *AVRCP::ownerService = nullptr;
void AVRCP::packetHandler(uint8_t packetType, uint16_t channel, uint8_t *packet, uint16_t size)
{
@@ 64,10 68,11 @@ namespace bluetooth
}
}
- void AVRCP::targetPacketHandler(uint8_t packetType, uint16_t channel, uint8_t *packet, uint16_t size)
+ void AVRCP::targetPacketHandler(uint8_t packetType,
+ [[maybe_unused]] uint16_t channel,
+ uint8_t *packet,
+ [[maybe_unused]] uint16_t size)
{
- UNUSED(channel);
- UNUSED(size);
uint8_t status = ERROR_CODE_SUCCESS;
if (packetType != HCI_EVENT_PACKET) {
@@ 102,9 107,6 @@ namespace bluetooth
AVRCP::playInfo.song_position_ms,
AVRCP::playInfo.status);
break;
- // case AVRCP_SUBEVENT_NOW_PLAYING_INFO_QUERY:
- // status = avrcp_target_now_playing_info(avrcp_cid);
- // break;
case AVRCP_SUBEVENT_OPERATION: {
auto operation_id = (avrcp_operation_id_t)avrcp_subevent_operation_get_operation_id(packet);
switch (operation_id) {
@@ 136,10 138,11 @@ namespace bluetooth
}
}
- void AVRCP::controllerPacketHandler(uint8_t packetType, uint16_t channel, uint8_t *packet, uint16_t size)
+ void AVRCP::controllerPacketHandler(uint8_t packetType,
+ [[maybe_unused]] uint16_t channel,
+ [[maybe_unused]] uint8_t *packet,
+ uint16_t size)
{
- UNUSED(channel);
- UNUSED(size);
uint8_t status = 0xFF;
if (packetType != HCI_EVENT_PACKET) {
@@ 160,10 163,12 @@ namespace bluetooth
}
switch (packet[2]) {
- case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
- LOG_INFO("AVRCP Controller: notification absolute volume changed %d %%\n",
- avrcp_subevent_notification_volume_changed_get_absolute_volume(packet) * 100 / 127);
- break;
+ case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED: {
+ const auto volume = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet);
+ auto &busProxy = AVRCP::ownerService->bus;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::AudioVolume>(volume), service::name::bluetooth);
+ LOG_INFO("AVRCP Controller: notification absolute volume changed %d %%\n", volume * 100 / 127);
+ } break;
case AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID:
LOG_INFO("Remote supports EVENT_ID 0x%02x\n", avrcp_subevent_get_capability_event_id_get_event_id(packet));
break;
@@ 176,8 181,9 @@ namespace bluetooth
break;
}
}
- void AVRCP::init()
+ void AVRCP::init(sys::Service *service)
{
+ AVRCP::ownerService = service;
// Initialize AVRCP Service.
avrcp_init();
avrcp_register_packet_handler(&packetHandler);
@@ 189,4 195,4 @@ namespace bluetooth
avrcp_controller_register_packet_handler(&controllerPacketHandler);
}
-} // namespace Bt
+} // namespace bluetooth
M module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.hpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.hpp +3 -2
@@ 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
@@ 46,6 46,7 @@ namespace bluetooth
static std::array<uint8_t, SDP_BUFFER_LENGTH> sdpTargetServiceBuffer;
static std::array<uint8_t, SDP_BUFFER_LENGTH> sdpControllerServiceBuffer;
+ static sys::Service *ownerService;
static avrcp_track_t tracks[3];
static int currentTrackIndex;
@@ 55,6 56,6 @@ namespace bluetooth
static void packetHandler(uint8_t packetType, uint16_t channel, uint8_t *packet, uint16_t size);
static void targetPacketHandler(uint8_t packetType, uint16_t channel, uint8_t *packet, uint16_t size);
static void controllerPacketHandler(uint8_t packetType, uint16_t channel, uint8_t *packet, uint16_t size);
- static void init();
+ static void init(sys::Service *service);
};
} // namespace Bt
M module-bluetooth/Bluetooth/interface/profiles/ProfileManager.cpp => module-bluetooth/Bluetooth/interface/profiles/ProfileManager.cpp +1 -1
@@ 15,7 15,7 @@ namespace bluetooth
{
if (!initialized) {
profilesList = {{AudioProfile::A2DP, std::make_shared<bluetooth::A2DP>()},
- {AudioProfile::HSP, std::make_shared<bluetooth::HSP>()},
+ {AudioProfile::HSP, nullptr},
{AudioProfile::HFP, nullptr},
{AudioProfile::None, nullptr}};
M module-services/service-audio/AudioServiceAPI.cpp => module-services/service-audio/AudioServiceAPI.cpp +4 -0
@@ 167,4 167,8 @@ namespace AudioServiceAPI
return serv->bus.sendUnicast(msg, service::name::audio);
}
+ bool BluetoothVolumeChanged(sys::Service *serv, const uint8_t volume)
+ {
+ return serv->bus.sendUnicast(std::make_shared<BluetoothDeviceVolumeChanged>(volume), service::name::audio);
+ }
} // namespace AudioServiceAPI
M module-services/service-audio/ServiceAudio.cpp => module-services/service-audio/ServiceAudio.cpp +10 -1
@@ 168,6 168,9 @@ ServiceAudio::ServiceAudio()
phoneModeObserver->subscribe([&](sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode) {
HandlePhoneModeChange(phoneMode, tetheringMode);
});
+
+ connect(typeid(BluetoothDeviceVolumeChanged),
+ [this](sys::Message *msg) -> sys::MessagePointer { return handleVolumeChangedOnBluetoothDevice(msg); });
}
ServiceAudio::~ServiceAudio()
@@ 685,7 688,7 @@ std::string ServiceAudio::getSetting(const Setting &setting,
std::string path = dbPath(setting, targetPlayback, targetProfile, phoneModeObserver->getCurrentPhoneMode());
if (const auto set_it = settingsCache.find(path); settingsCache.end() != set_it) {
- LOG_ERROR("Get audio setting %s = %s", path.c_str(), set_it->second.c_str());
+ LOG_INFO("Get audio setting %s = %s", path.c_str(), set_it->second.c_str());
return set_it->second;
}
@@ 772,3 775,9 @@ void ServiceAudio::settingsChanged(const std::string &name, std::string value)
}
LOG_ERROR("ServiceAudio::settingsChanged received notification about not registered setting: %s", name.c_str());
}
+auto ServiceAudio::handleVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer
+{
+ auto *msg = static_cast<BluetoothDeviceVolumeChanged *>(msgl);
+ LOG_WARN("Volume chnged on bt device to %u. Handler to be done", msg->getVolume());
+ return sys::msgHandled();
+}
M module-services/service-audio/service-audio/AudioMessage.hpp => module-services/service-audio/service-audio/AudioMessage.hpp +15 -0
@@ 278,3 278,18 @@ class AudioKeyPressedResponse : public sys::DataMessage
const ShowPopup showPopup = ShowPopup::False;
std::pair<audio::Profile::Type, audio::PlaybackType> context;
};
+
+class BluetoothDeviceVolumeChanged : public AudioMessage
+{
+ public:
+ explicit BluetoothDeviceVolumeChanged(std::uint8_t volume) : volume{volume}
+ {}
+
+ [[nodiscard]] auto getVolume() const noexcept -> std::uint8_t
+ {
+ return volume;
+ }
+
+ private:
+ const std::uint8_t volume;
+};
M module-services/service-audio/service-audio/AudioServiceAPI.hpp => module-services/service-audio/service-audio/AudioServiceAPI.hpp +3 -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
@@ 168,4 168,6 @@ namespace AudioServiceAPI
* Response will come as message AudioKeyPressedResponse
*/
bool KeyPressed(sys::Service *serv, const int step);
+
+ bool BluetoothVolumeChanged(sys::Service *serv, const uint8_t volume);
}; // namespace AudioServiceAPI
M module-services/service-audio/service-audio/ServiceAudio.hpp => module-services/service-audio/service-audio/ServiceAudio.hpp +1 -1
@@ 109,8 109,8 @@ class ServiceAudio : public sys::Service
const audio::PlaybackType &playbackType);
const std::pair<audio::Profile::Type, audio::PlaybackType> getCurrentContext();
-
void settingsChanged(const std::string &name, std::string value);
+ auto handleVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer;
};
namespace sys
M module-services/service-bluetooth/Constants.hpp => module-services/service-bluetooth/Constants.hpp +2 -2
@@ 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
@@ 6,4 6,4 @@
namespace service::name
{
inline constexpr auto bluetooth = "ServiceBluetooth";
-}
+} // namespace service::name
M module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +10 -0
@@ 10,6 10,7 @@
#include <Service/Service.hpp>
#include <Service/Message.hpp>
#include <service-db/Settings.hpp>
+#include "service-bluetooth/messages/AudioVolume.hpp"
#include "service-bluetooth/messages/Connect.hpp"
#include "service-bluetooth/messages/Disconnect.hpp"
#include "service-bluetooth/messages/Status.hpp"
@@ 26,6 27,7 @@
#include <service-desktop/service-desktop/DesktopMessages.hpp>
#include <service-desktop/endpoints/bluetooth/BluetoothEventMessages.hpp>
#include <service-desktop/endpoints/bluetooth/BluetoothHelper.hpp>
+#include <service-audio/AudioServiceAPI.hpp>
#include <BtCommand.hpp>
#include <BtKeysStorage.hpp>
#include <Timers/TimerFactory.hpp>
@@ 73,6 75,7 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
connectHandler<BluetoothAudioStartMessage>();
connectHandler<BluetoothMessage>();
connectHandler<BluetoothPairMessage>();
+ connectHandler<message::bluetooth::AudioVolume>();
connectHandler<message::bluetooth::Connect>();
connectHandler<message::bluetooth::ConnectResult>();
connectHandler<message::bluetooth::Disconnect>();
@@ 309,6 312,13 @@ auto ServiceBluetooth::handle(sdesktop::developerMode::DeveloperModeRequest *msg
}
return sys::MessageNone{};
}
+
+auto ServiceBluetooth::handle(message::bluetooth::AudioVolume *msg) -> std::shared_ptr<sys::Message>
+{
+ AudioServiceAPI::BluetoothVolumeChanged(this, msg->getVolume());
+ return sys::MessageNone{};
+}
+
void ServiceBluetooth::startTimeoutTimer()
{
if (connectionTimeoutTimer.isValid()) {
M module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp => module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp +2 -0
@@ 44,6 44,7 @@ namespace message::bluetooth
class ConnectResult;
class Disconnect;
class DisconnectResult;
+ class AudioVolume;
} // namespace message::bluetooth
@@ 91,6 92,7 @@ class ServiceBluetooth : public sys::Service
[[nodiscard]] auto handle(BluetoothAddrMessage *msg) -> std::shared_ptr<sys::Message>;
[[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>;
};
namespace sys
A module-services/service-bluetooth/service-bluetooth/messages/AudioVolume.hpp => module-services/service-bluetooth/service-bluetooth/messages/AudioVolume.hpp +24 -0
@@ 0,0 1,24 @@
+// 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 AudioVolume : public BluetoothMessage
+ {
+ public:
+ explicit AudioVolume(std::uint8_t volume) : volume{volume}
+ {}
+
+ [[nodiscard]] auto getVolume() const noexcept -> std::uint8_t
+ {
+ return volume;
+ }
+
+ private:
+ const std::uint8_t volume;
+ };
+} // namespace message::bluetooth
M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +1 -1
@@ 148,7 148,7 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
handleMinuteUpdate(msg->timestamp);
handled = true;
}
- else if (auto msg = dynamic_cast<AudioEventRequest *>(msgl); msg /*&& msgl->sender == this->GetName()*/) {
+ else if (auto msg = dynamic_cast<AudioEventRequest *>(msgl); msg) {
AudioServiceAPI::SendEvent(this, msg->getEvent());
handled = true;
}