mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 20:17:37 +00:00
322 lines
8.1 KiB
C++
322 lines
8.1 KiB
C++
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "BluetoothGattManager.h"
|
|
#include "BluetoothCommon.h"
|
|
#include "BluetoothUtils.h"
|
|
#include "BluetoothInterface.h"
|
|
|
|
#include "mozilla/Services.h"
|
|
#include "mozilla/StaticPtr.h"
|
|
#include "MainThreadUtils.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
using namespace mozilla;
|
|
USING_BLUETOOTH_NAMESPACE
|
|
|
|
namespace {
|
|
StaticRefPtr<BluetoothGattManager> sBluetoothGattManager;
|
|
static BluetoothGattInterface* sBluetoothGattInterface;
|
|
static BluetoothGattClientInterface* sBluetoothGattClientInterface;
|
|
} // anonymous namespace
|
|
|
|
bool BluetoothGattManager::mInShutdown = false;
|
|
|
|
/*
|
|
* Static functions
|
|
*/
|
|
|
|
BluetoothGattManager*
|
|
BluetoothGattManager::Get()
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
// If sBluetoothGattManager already exists, exit early
|
|
if (sBluetoothGattManager) {
|
|
return sBluetoothGattManager;
|
|
}
|
|
|
|
// If we're in shutdown, don't create a new instance
|
|
NS_ENSURE_FALSE(mInShutdown, nullptr);
|
|
|
|
// Create a new instance, register, and return
|
|
BluetoothGattManager* manager = new BluetoothGattManager();
|
|
sBluetoothGattManager = manager;
|
|
return sBluetoothGattManager;
|
|
}
|
|
|
|
class InitGattResultHandler MOZ_FINAL : public BluetoothGattResultHandler
|
|
{
|
|
public:
|
|
InitGattResultHandler(BluetoothProfileResultHandler* aRes)
|
|
: mRes(aRes)
|
|
{ }
|
|
|
|
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
|
{
|
|
BT_WARNING("BluetoothGattInterface::Init failed: %d",
|
|
(int)aStatus);
|
|
if (mRes) {
|
|
mRes->OnError(NS_ERROR_FAILURE);
|
|
}
|
|
}
|
|
|
|
void Init() MOZ_OVERRIDE
|
|
{
|
|
if (mRes) {
|
|
mRes->Init();
|
|
}
|
|
}
|
|
|
|
private:
|
|
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
|
};
|
|
|
|
// static
|
|
void
|
|
BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
|
|
{
|
|
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
|
|
if (!btInf) {
|
|
BT_LOGR("Error: Bluetooth interface not available");
|
|
if (aRes) {
|
|
aRes->OnError(NS_ERROR_FAILURE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
sBluetoothGattInterface = btInf->GetBluetoothGattInterface();
|
|
if (!sBluetoothGattInterface) {
|
|
BT_LOGR("Error: Bluetooth GATT interface not available");
|
|
if (aRes) {
|
|
aRes->OnError(NS_ERROR_FAILURE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
sBluetoothGattClientInterface =
|
|
sBluetoothGattInterface->GetBluetoothGattClientInterface();
|
|
NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
|
|
|
|
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
|
|
sBluetoothGattInterface->Init(gattManager,
|
|
new InitGattResultHandler(aRes));
|
|
}
|
|
|
|
class CleanupResultHandler MOZ_FINAL : public BluetoothGattResultHandler
|
|
{
|
|
public:
|
|
CleanupResultHandler(BluetoothProfileResultHandler* aRes)
|
|
: mRes(aRes)
|
|
{ }
|
|
|
|
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
|
{
|
|
BT_WARNING("BluetoothGattInterface::Cleanup failed: %d",
|
|
(int)aStatus);
|
|
if (mRes) {
|
|
mRes->OnError(NS_ERROR_FAILURE);
|
|
}
|
|
}
|
|
|
|
void Cleanup() MOZ_OVERRIDE
|
|
{
|
|
sBluetoothGattClientInterface = nullptr;
|
|
sBluetoothGattInterface = nullptr;
|
|
if (mRes) {
|
|
mRes->Deinit();
|
|
}
|
|
}
|
|
|
|
private:
|
|
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
|
};
|
|
|
|
class CleanupResultHandlerRunnable MOZ_FINAL : public nsRunnable
|
|
{
|
|
public:
|
|
CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
|
|
: mRes(aRes)
|
|
{
|
|
MOZ_ASSERT(mRes);
|
|
}
|
|
|
|
NS_IMETHOD Run() MOZ_OVERRIDE
|
|
{
|
|
mRes->Deinit();
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
|
};
|
|
|
|
// static
|
|
void
|
|
BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (sBluetoothGattInterface) {
|
|
sBluetoothGattInterface->Cleanup(new CleanupResultHandler(aRes));
|
|
} else if (aRes) {
|
|
// We dispatch a runnable here to make the profile resource handler
|
|
// behave as if GATT was initialized.
|
|
nsRefPtr<nsRunnable> r = new CleanupResultHandlerRunnable(aRes);
|
|
if (NS_FAILED(NS_DispatchToMainThread(r))) {
|
|
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Notification Handlers
|
|
//
|
|
void
|
|
BluetoothGattManager::RegisterClientNotification(int aStatus,
|
|
int aClientIf,
|
|
const BluetoothUuid& aAppUuid)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ScanResultNotification(
|
|
const nsAString& aBdAddr, int aRssi,
|
|
const BluetoothGattAdvData& aAdvData)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ConnectNotification(int aConnId,
|
|
int aStatus,
|
|
int aClientIf,
|
|
const nsAString& aBdAddr)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::DisconnectNotification(int aConnId,
|
|
int aStatus,
|
|
int aClientIf,
|
|
const nsAString& aBdAddr)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::SearchCompleteNotification(int aConnId, int aStatus)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::SearchResultNotification(
|
|
int aConnId, const BluetoothGattServiceId& aServiceId)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::GetCharacteristicNotification(
|
|
int aConnId, int aStatus,
|
|
const BluetoothGattServiceId& aServiceId,
|
|
const BluetoothGattId& aCharId,
|
|
int aCharProperty)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::GetDescriptorNotification(
|
|
int aConnId, int aStatus,
|
|
const BluetoothGattServiceId& aServiceId,
|
|
const BluetoothGattId& aCharId,
|
|
const BluetoothGattId& aDescriptorId)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::GetIncludedServiceNotification(
|
|
int aConnId, int aStatus,
|
|
const BluetoothGattServiceId& aServiceId,
|
|
const BluetoothGattServiceId& aIncludedServId)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::RegisterNotificationNotification(
|
|
int aConnId, int aIsRegister, int aStatus,
|
|
const BluetoothGattServiceId& aServiceId,
|
|
const BluetoothGattId& aCharId)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::NotifyNotification(
|
|
int aConnId, const BluetoothGattNotifyParam& aNotifyParam)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ReadCharacteristicNotification(
|
|
int aConnId, int aStatus, const BluetoothGattReadParam& aReadParam)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::WriteCharacteristicNotification(
|
|
int aConnId, int aStatus, const BluetoothGattWriteParam& aWriteParam)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ReadDescriptorNotification(
|
|
int aConnId, int aStatus, const BluetoothGattReadParam& aReadParam)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::WriteDescriptorNotification(
|
|
int aConnId, int aStatus, const BluetoothGattWriteParam& aWriteParam)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ExecuteWriteNotification(int aConnId, int aStatus)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ReadRemoteRssiNotification(int aClientIf,
|
|
const nsAString& aBdAddr,
|
|
int aRssi,
|
|
int aStatus)
|
|
{ }
|
|
|
|
void
|
|
BluetoothGattManager::ListenNotification(int aStatus,
|
|
int aServerIf)
|
|
{ }
|
|
|
|
BluetoothGattManager::BluetoothGattManager()
|
|
{ }
|
|
|
|
BluetoothGattManager::~BluetoothGattManager()
|
|
{
|
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
|
NS_ENSURE_TRUE_VOID(obs);
|
|
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
|
|
BT_WARNING("Failed to remove shutdown observer!");
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BluetoothGattManager::Observe(nsISupports* aSubject,
|
|
const char* aTopic,
|
|
const char16_t* aData)
|
|
{
|
|
MOZ_ASSERT(sBluetoothGattManager);
|
|
|
|
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
|
HandleShutdown();
|
|
return NS_OK;
|
|
}
|
|
|
|
MOZ_ASSERT(false, "BluetoothGattManager got unexpected topic!");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
void
|
|
BluetoothGattManager::HandleShutdown()
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
mInShutdown = true;
|
|
sBluetoothGattManager = nullptr;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(BluetoothGattManager, nsIObserver)
|