mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-09 21:00:42 +02:00
MozReview-Commit-ID: KNbxVcCVqts --HG-- extra : transplant_source : %1D%18%E5%C9o%F0%29%E7%E0%93%EEcR%C7B%3BeX%B3%87
259 lines
8.1 KiB
C++
259 lines
8.1 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=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 "BluetoothService.h"
|
|
#include "BluetoothUtils.h"
|
|
#include "mozilla/dom/BluetoothGattServiceBinding.h"
|
|
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
|
|
#include "mozilla/dom/bluetooth/BluetoothGattCharacteristic.h"
|
|
#include "mozilla/dom/bluetooth/BluetoothGattService.h"
|
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
USING_BLUETOOTH_NAMESPACE
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothGattService,
|
|
mOwner,
|
|
mIncludedServices,
|
|
mCharacteristics)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothGattService)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(BluetoothGattService)
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BluetoothGattService)
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
const uint16_t BluetoothGattService::sHandleCount = 1;
|
|
|
|
// Constructor of BluetoothGattService in ATT client role
|
|
BluetoothGattService::BluetoothGattService(
|
|
nsPIDOMWindowInner* aOwner, const nsAString& aAppUuid,
|
|
const BluetoothGattServiceId& aServiceId)
|
|
: mOwner(aOwner)
|
|
, mAppUuid(aAppUuid)
|
|
, mServiceId(aServiceId)
|
|
, mAttRole(ATT_CLIENT_ROLE)
|
|
, mActive(true)
|
|
{
|
|
MOZ_ASSERT(aOwner);
|
|
MOZ_ASSERT(!mAppUuid.IsEmpty());
|
|
|
|
UuidToString(mServiceId.mId.mUuid, mUuidStr);
|
|
}
|
|
|
|
// Constructor of BluetoothGattService in ATT server role
|
|
BluetoothGattService::BluetoothGattService(
|
|
nsPIDOMWindowInner* aOwner,
|
|
const BluetoothGattServiceInit& aInit)
|
|
: mOwner(aOwner)
|
|
, mUuidStr(aInit.mUuid)
|
|
, mAttRole(ATT_SERVER_ROLE)
|
|
, mActive(false)
|
|
{
|
|
memset(&mServiceId, 0, sizeof(mServiceId));
|
|
StringToUuid(aInit.mUuid, mServiceId.mId.mUuid);
|
|
mServiceId.mIsPrimary = aInit.mIsPrimary;
|
|
}
|
|
|
|
BluetoothGattService::~BluetoothGattService()
|
|
{
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignIncludedServices(
|
|
const nsTArray<BluetoothGattServiceId>& aServiceIds)
|
|
{
|
|
mIncludedServices.Clear();
|
|
for (uint32_t i = 0; i < aServiceIds.Length(); i++) {
|
|
mIncludedServices.AppendElement(new BluetoothGattService(
|
|
GetParentObject(), mAppUuid, aServiceIds[i]));
|
|
}
|
|
|
|
BluetoothGattServiceBinding::ClearCachedIncludedServicesValue(this);
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignCharacteristics(
|
|
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics)
|
|
{
|
|
mCharacteristics.Clear();
|
|
for (uint32_t i = 0; i < aCharacteristics.Length(); i++) {
|
|
mCharacteristics.AppendElement(new BluetoothGattCharacteristic(
|
|
GetParentObject(), this, aCharacteristics[i]));
|
|
}
|
|
|
|
BluetoothGattServiceBinding::ClearCachedCharacteristicsValue(this);
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignDescriptors(
|
|
const BluetoothGattId& aCharacteristicId,
|
|
const nsTArray<BluetoothGattId>& aDescriptorIds)
|
|
{
|
|
size_t index = mCharacteristics.IndexOf(aCharacteristicId);
|
|
NS_ENSURE_TRUE_VOID(index != mCharacteristics.NoIndex);
|
|
|
|
RefPtr<BluetoothGattCharacteristic> characteristic =
|
|
mCharacteristics.ElementAt(index);
|
|
characteristic->AssignDescriptors(aDescriptorIds);
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignAppUuid(const nsAString& aAppUuid)
|
|
{
|
|
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
|
|
|
|
mAppUuid = aAppUuid;
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignServiceHandle(
|
|
const BluetoothAttributeHandle& aServiceHandle)
|
|
{
|
|
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
|
|
MOZ_ASSERT(!mActive);
|
|
MOZ_ASSERT(!mServiceHandle.mHandle);
|
|
|
|
mServiceHandle = aServiceHandle;
|
|
mActive = true;
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignCharacteristicHandle(
|
|
const BluetoothUuid& aCharacteristicUuid,
|
|
const BluetoothAttributeHandle& aCharacteristicHandle)
|
|
{
|
|
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
|
|
MOZ_ASSERT(mActive);
|
|
|
|
size_t index = mCharacteristics.IndexOf(aCharacteristicUuid);
|
|
NS_ENSURE_TRUE_VOID(index != mCharacteristics.NoIndex);
|
|
mCharacteristics[index]->AssignCharacteristicHandle(aCharacteristicHandle);
|
|
}
|
|
|
|
void
|
|
BluetoothGattService::AssignDescriptorHandle(
|
|
const BluetoothUuid& aDescriptorUuid,
|
|
const BluetoothAttributeHandle& aCharacteristicHandle,
|
|
const BluetoothAttributeHandle& aDescriptorHandle)
|
|
{
|
|
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
|
|
MOZ_ASSERT(mActive);
|
|
|
|
size_t index = mCharacteristics.IndexOf(aCharacteristicHandle);
|
|
NS_ENSURE_TRUE_VOID(index != mCharacteristics.NoIndex);
|
|
mCharacteristics[index]->AssignDescriptorHandle(aDescriptorUuid,
|
|
aDescriptorHandle);
|
|
}
|
|
|
|
uint16_t
|
|
BluetoothGattService::GetHandleCount() const
|
|
{
|
|
uint16_t count = sHandleCount;
|
|
for (size_t i = 0; i < mCharacteristics.Length(); ++i) {
|
|
count += mCharacteristics[i]->GetHandleCount();
|
|
}
|
|
return count;
|
|
}
|
|
|
|
JSObject*
|
|
BluetoothGattService::WrapObject(JSContext* aContext,
|
|
JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return BluetoothGattServiceBinding::Wrap(aContext, this, aGivenProto);
|
|
}
|
|
|
|
already_AddRefed<BluetoothGattService>
|
|
BluetoothGattService::Constructor(const GlobalObject& aGlobal,
|
|
const BluetoothGattServiceInit& aInit,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
|
if (!window) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<BluetoothGattService> service = new BluetoothGattService(window,
|
|
aInit);
|
|
|
|
return service.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
BluetoothGattService::AddCharacteristic(
|
|
const nsAString& aCharacteristicUuid,
|
|
const GattPermissions& aPermissions,
|
|
const GattCharacteristicProperties& aProperties,
|
|
const ArrayBuffer& aValue,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
|
if (!global) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
|
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
|
|
|
BT_ENSURE_TRUE_REJECT(mAttRole == ATT_SERVER_ROLE,
|
|
promise,
|
|
NS_ERROR_UNEXPECTED);
|
|
|
|
/* The service should not be actively acting with the Bluetooth backend.
|
|
* Otherwise, characteristics cannot be added into the service. */
|
|
BT_ENSURE_TRUE_REJECT(!mActive, promise, NS_ERROR_UNEXPECTED);
|
|
|
|
RefPtr<BluetoothGattCharacteristic> characteristic =
|
|
new BluetoothGattCharacteristic(GetParentObject(),
|
|
this,
|
|
aCharacteristicUuid,
|
|
aPermissions,
|
|
aProperties,
|
|
aValue);
|
|
|
|
mCharacteristics.AppendElement(characteristic);
|
|
promise->MaybeResolve(characteristic);
|
|
|
|
return promise.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
BluetoothGattService::AddIncludedService(BluetoothGattService& aIncludedService,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
|
if (!global) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
|
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
|
|
|
BT_ENSURE_TRUE_REJECT(mAttRole == ATT_SERVER_ROLE,
|
|
promise,
|
|
NS_ERROR_UNEXPECTED);
|
|
|
|
/* The service should not be actively acting with the Bluetooth backend.
|
|
* Otherwise, included services cannot be added into the service. */
|
|
BT_ENSURE_TRUE_REJECT(!mActive, promise, NS_ERROR_UNEXPECTED);
|
|
|
|
/* The included service itself should be actively acting with the Bluetooth
|
|
* backend. Otherwise, that service cannot be included by any services. */
|
|
BT_ENSURE_TRUE_REJECT(aIncludedService.mActive,
|
|
promise,
|
|
NS_ERROR_UNEXPECTED);
|
|
|
|
mIncludedServices.AppendElement(&aIncludedService);
|
|
promise->MaybeResolveWithUndefined();
|
|
|
|
return promise.forget();
|
|
}
|