Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 101 additions & 65 deletions Bluetooth/Bluetooth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
// For example, the exposed "startScan" method is mapped to "startScanWrapper()" and that one calls to "startDeviceDiscovery()" internally,
// which finally calls to "BTRMGR_StartDeviceDiscovery()" in Bluetooth Manager.

//#define BLUETOOTH_DEBUG

#define API_VERSION_NUMBER_MAJOR 1
#define API_VERSION_NUMBER_MINOR 1
#define API_VERSION_NUMBER_PATCH 0
Expand Down Expand Up @@ -643,22 +645,27 @@ namespace WPEFramework

bool Bluetooth::setDevicePairing(long long int deviceID, bool pair)
{
BTRMGR_Result_t rc = BTRMGR_RESULT_SUCCESS;
BTRMgrDeviceHandle deviceHandle = (BTRMgrDeviceHandle) deviceID;
if (pair)
{
rc = BTRMGR_PairDevice(0, deviceHandle);
} else{
rc = BTRMGR_UnpairDevice(0, deviceHandle);
}

BTRMGR_Result_t rc = pair ? BTRMGR_PairDevice(0, deviceHandle) : BTRMGR_UnpairDevice(0, deviceHandle);

if (BTRMGR_RESULT_SUCCESS != rc)
{
LOGERR("Failed to do %s ", (pair ? "Pair" : "Unpair"));
} else {
return false;
}

string deviceId = std::to_string(deviceHandle);

Core::hresult result = pair ? m_bluetoothDeviceManager.addDevice(deviceId) : m_bluetoothDeviceManager.removeDevice(deviceId);

if (Core::ERROR_NONE == result) {
LOGINFO("Successfully done %s ", (pair ? "Pair" : "Unpair"));
} else {
LOGERR("Failed to update cache: result=%d", result);
}
return BTRMGR_RESULT_SUCCESS == rc;

return true;
}

bool Bluetooth::setBluetoothEnabled(const string &enabled)
Expand Down Expand Up @@ -1904,81 +1911,110 @@ namespace WPEFramework

void Bluetooth::onPowerModeChanged(const WPEFramework::Exchange::IPowerManager::PowerState currentState, const WPEFramework::Exchange::IPowerManager::PowerState newState)
{
// Disabling until integration phase
#if 0

static const char* powerStateNames[] = {
"POWER_STATE_UNKNOWN",
"POWER_STATE_OFF",
"POWER_STATE_STANDBY",
"POWER_STATE_ON",
"POWER_STATE_STANDBY_LIGHT_SLEEP",
"POWER_STATE_STANDBY_DEEP_SLEEP"
};

LOGINFO("%s --> %s\n", powerStateNames[currentState], powerStateNames[newState]);

if ((WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_ON == currentState || WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_UNKNOWN == currentState) &&
(WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_OFF == newState || WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY == newState || WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY_LIGHT_SLEEP == newState)) {

JsonArray connectedDevices = getConnectedDevices();

LOGINFO("connectedDevices.Length()=%d\n", connectedDevices.Length());

for (uint16_t i = 0; i < connectedDevices.Length(); i++) {
JsonObject device = connectedDevices[i].Object();
string deviceStr;
device.ToString(deviceStr);
LOGINFO("connectedDevices[%d] = %s\n", i, deviceStr.c_str());
if (device.HasLabel("autoconnect") && !device["autoconnect"].Boolean()) {
// Only disconnect if autoConnect was explicitly set false (HasLabel), to preserve backward compatibility.
#ifdef BLUETOOTH_DEBUG
static const char* powerStateNames[] = {
"POWER_STATE_UNKNOWN",
"POWER_STATE_OFF",
"POWER_STATE_STANDBY",
"POWER_STATE_ON",
"POWER_STATE_STANDBY_LIGHT_SLEEP",
"POWER_STATE_STANDBY_DEEP_SLEEP"
};

LOGINFO("%s --> %s\n", powerStateNames[currentState], powerStateNames[newState]);
#else
LOGINFO("Power mode changed: %d --> %d\n", currentState, newState);
#endif

if (newState == currentState) {
LOGINFO("Power state unchanged, ignoring transition\n");
return;
}

// ON --> OFF
if ((WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_ON == currentState ||
WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_UNKNOWN == currentState) &&
(WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_OFF == newState ||
WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY == newState ||
WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY_LIGHT_SLEEP == newState)) {

std::unordered_map<std::string, BluetoothDeviceInfo> pairedDeviceInfos = m_bluetoothDeviceManager.getPairedDeviceInfos();

for (const auto& entry : pairedDeviceInfos) {
const std::string& deviceIdStr = entry.first;
const BluetoothDeviceInfo& deviceInfo = entry.second;
LOGINFO("pairedDeviceInfos[%s] = { deviceType=%s, autoConnectStatus=%d, lastConnectTimeUtc=%s }\n",
deviceIdStr.c_str(), deviceInfo.deviceType.c_str(), static_cast<int>(deviceInfo.autoConnectStatus), deviceInfo.lastConnectTimeUtc.c_str());

if (deviceInfo.deviceType == "HUMAN INTERFACE DEVICE") {
// Don't disconnect RCU devices on power off/standby, as they are needed to wake up the device.
continue;
}

if (deviceInfo.autoConnectStatus == AutoConnectStatus::AUTO_CONNECT_STATUS_DISABLED) {
// Only disconnect if autoConnect was explicitly set false to preserve backward compatibility.
try {
long long int deviceID = stoll(device["deviceID"].String());
bool bSuccess = setDeviceConnection(deviceID, false, device["deviceType"].String());
LOGINFO("POWER OFF/STANDBY: Disconnecting deviceID=%llu, success=%s\n", deviceID, bSuccess ? "true" : "false");
long long int deviceId = stoll(deviceIdStr);
bool bSuccess = setDeviceConnection(deviceId, false, deviceInfo.deviceType);
LOGINFO("POWER OFF/STANDBY: Disconnecting deviceID=%lld, success=%s\n", deviceId, bSuccess ? "true" : "false");
} catch (const std::exception& e) {
LOGERR("Failed to parse deviceID: %s\n", e.what());
LOGERR("Failed to parse deviceId: %s\n", e.what());
}
}
}
} else if (WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_ON == newState ) {
JsonArray pairedDevices = getPairedDevices();

LOGINFO("pairedDevices.Length()=%d\n", pairedDevices.Length());
for (uint16_t i = 0; i < pairedDevices.Length(); i++) {
JsonObject device = pairedDevices[i].Object();
string deviceStr;
device.ToString(deviceStr);
LOGINFO("pairedDevices[%d] = %s\n", i, deviceStr.c_str());
}
// X --> ON
else if (WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_ON == newState ) {
std::unordered_map<std::string, BluetoothDeviceInfo> pairedDeviceInfos = m_bluetoothDeviceManager.getPairedDeviceInfos();

LOGINFO("pairedDeviceInfos.size()=%zu\n", pairedDeviceInfos.size());

uint16_t pairedDevicesCount = 0;

for (const auto& entry : pairedDeviceInfos) {
const std::string& deviceIdStr = entry.first;
const BluetoothDeviceInfo& deviceInfo = entry.second;
LOGINFO("pairedDeviceInfos[%s] = { deviceType=%s, autoConnectStatus=%d, lastConnectTimeUtc=%s }\n",
deviceIdStr.c_str(), deviceInfo.deviceType.c_str(), static_cast<int>(deviceInfo.autoConnectStatus), deviceInfo.lastConnectTimeUtc.c_str());

if (deviceInfo.deviceType != "HUMAN INTERFACE DEVICE") {
++pairedDevicesCount;
}
}

if (pairedDevices.Length() > 0) {
if (pairedDevicesCount > 0) {
setBluetoothEnabled(ENABLE_BLUETOOTH_ENABLED);
}
} else if (WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY_DEEP_SLEEP == newState ) {
}
// X --> DEEP_SLEEP
else if (WPEFramework::Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY_DEEP_SLEEP == newState ) {

std::unordered_map<std::string, BluetoothDeviceInfo> pairedDeviceInfos = m_bluetoothDeviceManager.getPairedDeviceInfos();

JsonArray connectedDevices = getConnectedDevices();
LOGINFO("pairedDeviceInfos.size()=%zu\n", pairedDeviceInfos.size());

LOGINFO("connectedDevices.Length()=%d\n", connectedDevices.Length());
for (const auto& entry : pairedDeviceInfos) {
const std::string& deviceIdStr = entry.first;
const BluetoothDeviceInfo& deviceInfo = entry.second;
LOGINFO("pairedDeviceInfos[%s] = { deviceType=%s, autoConnectStatus=%d, lastConnectTimeUtc=%s }\n",
deviceIdStr.c_str(), deviceInfo.deviceType.c_str(), static_cast<int>(deviceInfo.autoConnectStatus), deviceInfo.lastConnectTimeUtc.c_str());

if (deviceInfo.deviceType == "HUMAN INTERFACE DEVICE") {
// Don't disconnect RCU devices when entering DEEP_SLEEP, as they are needed to wake up the device.
continue;
}

for (uint16_t i = 0; i < connectedDevices.Length(); i++) {
JsonObject device = connectedDevices[i].Object();
string deviceStr;
device.ToString(deviceStr);
LOGINFO("connectedDevices[%d] = %s\n", i, deviceStr.c_str());
try {
long long int deviceID = stoll(device["deviceID"].String());
bool bSuccess = setDeviceConnection(deviceID, false, device["deviceType"].String());
LOGINFO("POWER_STATE_STANDBY_DEEP_SLEEP: Disconnecting deviceID=%llu, success=%s\n", deviceID, bSuccess ? "true" : "false");
long long int deviceId = std::stoll(deviceIdStr);
bool bSuccess = setDeviceConnection(deviceId, false, deviceInfo.deviceType);
LOGINFO("POWER_STATE_STANDBY_DEEP_SLEEP: Disconnecting deviceId=%lld, success=%s\n", deviceId, bSuccess ? "true" : "false");
} catch (const std::exception& e) {
LOGERR("Failed to parse deviceID: %s\n", e.what());
LOGERR("Failed to parse deviceId: %s\n", e.what());
}
}
} else {
LOGWARN("Unhandled transition\n");
}

#endif
}

void Bluetooth::notifyAutoConnectStatusChanged(const string& deviceID, const bool enable)
Expand Down
Loading