mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1223722: Transfer Bluetooth remote names in |BluetoothValue|, r=brsun
This commit is contained in:
parent
2c0e4e0d53
commit
379142b4ff
@ -1268,7 +1268,11 @@ PackPDU(const BluetoothProperty& aIn, DaemonSocketPDU& aPDU)
|
||||
|
||||
switch (aIn.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
/* fall through */
|
||||
rv = PackPDU(PackConversion<uint8_t, uint16_t>(aIn.mRemoteName.mLength),
|
||||
PackArray<uint8_t>(aIn.mRemoteName.mName,
|
||||
aIn.mRemoteName.mLength),
|
||||
aPDU);
|
||||
break;
|
||||
case PROPERTY_REMOTE_FRIENDLY_NAME: {
|
||||
NS_ConvertUTF16toUTF8 stringUTF8(aIn.mString);
|
||||
|
||||
@ -1561,8 +1565,16 @@ UnpackPDU(DaemonSocketPDU& aPDU, BluetoothProperty& aOut)
|
||||
}
|
||||
|
||||
switch (aOut.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
/* fall through */
|
||||
case PROPERTY_BDNAME: {
|
||||
const uint8_t* data = aPDU.Consume(len);
|
||||
if (MOZ_HAL_IPC_UNPACK_WARN_IF(!data, BluetoothProperty)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
// We construct an nsCString here because the string
|
||||
// returned from the PDU is not 0-terminated.
|
||||
aOut.mRemoteName.Assign(data, len);
|
||||
}
|
||||
break;
|
||||
case PROPERTY_REMOTE_FRIENDLY_NAME: {
|
||||
const uint8_t* data = aPDU.Consume(len);
|
||||
if (MOZ_HAL_IPC_UNPACK_WARN_IF(!data, BluetoothProperty)) {
|
||||
|
@ -464,6 +464,10 @@ UnpackPDU(DaemonSocketPDU& aPDU, BluetoothRemoteName& aOut)
|
||||
if (!aPDU.Consume(1)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
auto end = std::find(aOut.mName, aOut.mName + sizeof(aOut.mName), '\0');
|
||||
|
||||
aOut.mLength = end - aOut.mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2003,7 +2003,7 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
|
||||
|
||||
// Cleanup static adapter properties and notify adapter.
|
||||
mBdAddress.Clear();
|
||||
mBdName.Truncate();
|
||||
mBdName.Clear();
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
AppendNamedValue(props, "Name", mBdName);
|
||||
@ -2109,7 +2109,7 @@ BluetoothServiceBluedroid::AdapterPropertiesNotification(
|
||||
AppendNamedValue(propertiesArray, "Address", mBdAddress);
|
||||
|
||||
} else if (p.mType == PROPERTY_BDNAME) {
|
||||
mBdName = p.mString;
|
||||
mBdName = p.mRemoteName;
|
||||
AppendNamedValue(propertiesArray, "Name", mBdName);
|
||||
|
||||
} else if (p.mType == PROPERTY_ADAPTER_SCAN_MODE) {
|
||||
@ -2179,11 +2179,11 @@ BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
|
||||
const BluetoothProperty& p = aProperties[i];
|
||||
|
||||
if (p.mType == PROPERTY_BDNAME) {
|
||||
AppendNamedValue(propertiesArray, "Name", p.mString);
|
||||
AppendNamedValue(propertiesArray, "Name", p.mRemoteName);
|
||||
|
||||
// Update <address, name> mapping
|
||||
mDeviceNameMap.Remove(aBdAddr);
|
||||
mDeviceNameMap.Put(aBdAddr, p.mString);
|
||||
mDeviceNameMap.Put(aBdAddr, p.mRemoteName);
|
||||
} else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
|
||||
uint32_t cod = p.mUint32;
|
||||
AppendNamedValue(propertiesArray, "Cod", cod);
|
||||
@ -2311,7 +2311,7 @@ BluetoothServiceBluedroid::DeviceFoundNotification(
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
BluetoothAddress bdAddr;
|
||||
nsString bdName;
|
||||
BluetoothRemoteName bdName;
|
||||
|
||||
for (int i = 0; i < aNumProperties; i++) {
|
||||
|
||||
@ -2321,8 +2321,8 @@ BluetoothServiceBluedroid::DeviceFoundNotification(
|
||||
AppendNamedValue(propertiesArray, "Address", p.mBdAddress);
|
||||
bdAddr = p.mBdAddress;
|
||||
} else if (p.mType == PROPERTY_BDNAME) {
|
||||
AppendNamedValue(propertiesArray, "Name", p.mString);
|
||||
bdName = p.mString;
|
||||
AppendNamedValue(propertiesArray, "Name", p.mRemoteName);
|
||||
bdName = p.mRemoteName;
|
||||
} else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
|
||||
AppendNamedValue(propertiesArray, "Cod", p.mUint32);
|
||||
|
||||
@ -2389,16 +2389,15 @@ BluetoothServiceBluedroid::PinRequestNotification(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothRemoteName bdName;
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
// If |aBdName| is empty, get device name from |mDeviceNameMap|;
|
||||
// Otherwise update <address, name> mapping with |aBdName|
|
||||
nsAutoString bdName;
|
||||
RemoteNameToString(aBdName, bdName);
|
||||
|
||||
if (bdName.IsEmpty()) {
|
||||
if (aBdName.IsCleared()) {
|
||||
mDeviceNameMap.Get(aRemoteBdAddr, &bdName);
|
||||
} else {
|
||||
bdName.Assign(aBdName.mName, aBdName.mLength);
|
||||
mDeviceNameMap.Remove(aRemoteBdAddr);
|
||||
mDeviceNameMap.Put(aRemoteBdAddr, bdName);
|
||||
}
|
||||
@ -2421,16 +2420,15 @@ BluetoothServiceBluedroid::SspRequestNotification(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothRemoteName bdName;
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
// If |aBdName| is empty, get device name from |mDeviceNameMap|;
|
||||
// Otherwise update <address, name> mapping with |aBdName|
|
||||
nsAutoString bdName;
|
||||
RemoteNameToString(aBdName, bdName);
|
||||
|
||||
if (bdName.IsEmpty()) {
|
||||
if (aBdName.IsCleared()) {
|
||||
mDeviceNameMap.Get(aRemoteBdAddr, &bdName);
|
||||
} else {
|
||||
bdName.Assign(aBdName.mName, aBdName.mLength);
|
||||
mDeviceNameMap.Remove(aRemoteBdAddr);
|
||||
mDeviceNameMap.Put(aRemoteBdAddr, bdName);
|
||||
}
|
||||
@ -2510,7 +2508,7 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
|
||||
}
|
||||
|
||||
// Query pairing device name from hash table
|
||||
nsString remotebdName;
|
||||
BluetoothRemoteName remotebdName;
|
||||
mDeviceNameMap.Get(aRemoteBdAddr, &remotebdName);
|
||||
|
||||
// Update bonded address array and append pairing device name
|
||||
|
@ -497,7 +497,7 @@ protected:
|
||||
|
||||
// Adapter properties
|
||||
BluetoothAddress mBdAddress;
|
||||
nsString mBdName;
|
||||
BluetoothRemoteName mBdName;
|
||||
bool mEnabled;
|
||||
bool mDiscoverable;
|
||||
bool mDiscovering;
|
||||
@ -522,7 +522,7 @@ protected:
|
||||
nsTArray<GetDeviceRequest> mGetDeviceRequests;
|
||||
|
||||
// <address, name> mapping table for remote devices
|
||||
nsDataHashtable<BluetoothAddressHashKey, nsString> mDeviceNameMap;
|
||||
nsDataHashtable<BluetoothAddressHashKey, BluetoothRemoteName> mDeviceNameMap;
|
||||
|
||||
// Arrays for SDP operations
|
||||
nsTArray<GetRemoteServiceRecordRequest> mGetRemoteServiceRecordArray;
|
||||
|
@ -713,6 +713,52 @@ struct BluetoothRemoteInfo {
|
||||
|
||||
struct BluetoothRemoteName {
|
||||
uint8_t mName[248]; /* not \0-terminated */
|
||||
uint8_t mLength;
|
||||
|
||||
BluetoothRemoteName()
|
||||
: mLength(0)
|
||||
{ }
|
||||
|
||||
explicit BluetoothRemoteName(const nsACString_internal& aString)
|
||||
: mLength(0)
|
||||
{
|
||||
MOZ_ASSERT(aString.Length() <= MOZ_ARRAY_LENGTH(mName));
|
||||
memcpy(mName, aString.Data(), aString.Length());
|
||||
mLength = aString.Length();
|
||||
}
|
||||
|
||||
BluetoothRemoteName(const BluetoothRemoteName&) = default;
|
||||
|
||||
BluetoothRemoteName& operator=(const BluetoothRemoteName&) = default;
|
||||
|
||||
bool operator==(const BluetoothRemoteName& aRhs) const
|
||||
{
|
||||
MOZ_ASSERT(mLength <= MOZ_ARRAY_LENGTH(mName));
|
||||
return (mLength == aRhs.mLength) &&
|
||||
std::equal(aRhs.mName, aRhs.mName + aRhs.mLength, mName);
|
||||
}
|
||||
|
||||
bool operator!=(const BluetoothRemoteName& aRhs) const
|
||||
{
|
||||
return !operator==(aRhs);
|
||||
}
|
||||
|
||||
void Assign(const uint8_t* aName, size_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(aLength <= MOZ_ARRAY_LENGTH(mName));
|
||||
memcpy(mName, aName, aLength);
|
||||
mLength = aLength;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
bool IsCleared() const
|
||||
{
|
||||
return !mLength;
|
||||
}
|
||||
};
|
||||
|
||||
struct BluetoothProperty {
|
||||
@ -725,8 +771,10 @@ struct BluetoothProperty {
|
||||
/* PROPERTY_BDADDR */
|
||||
BluetoothAddress mBdAddress;
|
||||
|
||||
/* PROPERTY_BDNAME
|
||||
PROPERTY_REMOTE_FRIENDLY_NAME */
|
||||
/* PROPERTY_BDNAME */
|
||||
BluetoothRemoteName mRemoteName;
|
||||
|
||||
/* PROPERTY_REMOTE_FRIENDLY_NAME */
|
||||
nsString mString;
|
||||
|
||||
/* PROPERTY_UUIDS */
|
||||
@ -764,6 +812,12 @@ struct BluetoothProperty {
|
||||
, mBdAddress(aBdAddress)
|
||||
{ }
|
||||
|
||||
explicit BluetoothProperty(BluetoothPropertyType aType,
|
||||
const BluetoothRemoteName& aRemoteName)
|
||||
: mType(aType)
|
||||
, mRemoteName(aRemoteName)
|
||||
{ }
|
||||
|
||||
explicit BluetoothProperty(BluetoothPropertyType aType,
|
||||
const nsAString& aString)
|
||||
: mType(aType)
|
||||
|
@ -150,12 +150,12 @@ NamedValueToProperty(const BluetoothNamedValue& aValue,
|
||||
|
||||
switch (aProperty.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
if (aValue.value().type() != BluetoothValue::TnsString) {
|
||||
BT_LOGR("Bluetooth property value is not a string");
|
||||
if (aValue.value().type() != BluetoothValue::TBluetoothRemoteName) {
|
||||
BT_LOGR("Bluetooth property value is not a remote name");
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
// Set name
|
||||
aProperty.mString = aValue.value().get_nsString();
|
||||
aProperty.mRemoteName = aValue.value().get_BluetoothRemoteName();
|
||||
break;
|
||||
|
||||
case PROPERTY_ADAPTER_SCAN_MODE:
|
||||
@ -191,13 +191,14 @@ NamedValueToProperty(const BluetoothNamedValue& aValue,
|
||||
void
|
||||
RemoteNameToString(const BluetoothRemoteName& aRemoteName, nsAString& aString)
|
||||
{
|
||||
MOZ_ASSERT(aRemoteName.mLength <= sizeof(aRemoteName.mName));
|
||||
|
||||
auto name = reinterpret_cast<const char*>(aRemoteName.mName);
|
||||
|
||||
/* The content in |BluetoothRemoteName| is not a C string and not
|
||||
* terminated by \0. We use |strnlen| to limit its length.
|
||||
* terminated by \0. We use |mLength| to limit its length.
|
||||
*/
|
||||
aString =
|
||||
NS_ConvertUTF8toUTF16(name, strnlen(name, sizeof(aRemoteName.mName)));
|
||||
aString = NS_ConvertUTF8toUTF16(name, aRemoteName.mLength);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -456,7 +456,7 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
}
|
||||
}
|
||||
} else if (name.EqualsLiteral("Name")) {
|
||||
mName = value.get_nsString();
|
||||
RemoteNameToString(value.get_BluetoothRemoteName(), mName);
|
||||
} else if (name.EqualsLiteral("Address")) {
|
||||
AddressToString(value.get_BluetoothAddress(), mAddress);
|
||||
} else if (name.EqualsLiteral("Discoverable")) {
|
||||
@ -788,9 +788,10 @@ BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
|
||||
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Wrap property to set and runnable to handle result
|
||||
nsString name(aName);
|
||||
BluetoothNamedValue property(NS_LITERAL_STRING("Name"),
|
||||
BluetoothValue(name));
|
||||
BluetoothValue(
|
||||
BluetoothRemoteName(
|
||||
NS_ConvertUTF16toUTF8(aName))));
|
||||
BT_ENSURE_SUCCESS_REJECT(
|
||||
bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER, property,
|
||||
new BluetoothVoidReplyRunnable(nullptr, promise)),
|
||||
@ -1035,9 +1036,12 @@ BluetoothAdapter::IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tbool);
|
||||
return aValue.get_bool() ? mState != BluetoothAdapterState::Enabled
|
||||
: mState != BluetoothAdapterState::Disabled;
|
||||
case BluetoothAdapterAttribute::Name:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TnsString);
|
||||
return !mName.Equals(aValue.get_nsString());
|
||||
case BluetoothAdapterAttribute::Name: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothRemoteName);
|
||||
nsAutoString name;
|
||||
RemoteNameToString(aValue.get_BluetoothRemoteName(), name);
|
||||
return !name.Equals(mName);
|
||||
}
|
||||
case BluetoothAdapterAttribute::Address: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothAddress);
|
||||
BluetoothAddress address;
|
||||
@ -1221,7 +1225,7 @@ BluetoothAdapter::HandleDevicePaired(const BluetoothValue& aValue)
|
||||
|
||||
MOZ_ASSERT(arr.Length() == 3 &&
|
||||
arr[0].value().type() == BluetoothValue::TBluetoothAddress && // Address
|
||||
arr[1].value().type() == BluetoothValue::TnsString && // Name
|
||||
arr[1].value().type() == BluetoothValue::TBluetoothRemoteName && // Name
|
||||
arr[2].value().type() == BluetoothValue::Tbool); // Paired
|
||||
MOZ_ASSERT(!arr[0].value().get_BluetoothAddress().IsCleared() &&
|
||||
arr[2].value().get_bool());
|
||||
|
@ -146,7 +146,7 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
const nsString& name = aValue.name();
|
||||
const BluetoothValue& value = aValue.value();
|
||||
if (name.EqualsLiteral("Name")) {
|
||||
mName = value.get_nsString();
|
||||
RemoteNameToString(value.get_BluetoothRemoteName(), mName);
|
||||
} else if (name.EqualsLiteral("Address")) {
|
||||
AddressToString(value.get_BluetoothAddress(), mAddress);
|
||||
} else if (name.EqualsLiteral("Cod")) {
|
||||
@ -250,9 +250,12 @@ BluetoothDevice::IsDeviceAttributeChanged(BluetoothDeviceAttribute aType,
|
||||
case BluetoothDeviceAttribute::Cod:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tuint32_t);
|
||||
return !mCod->Equals(aValue.get_uint32_t());
|
||||
case BluetoothDeviceAttribute::Name:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TnsString);
|
||||
return !mName.Equals(aValue.get_nsString());
|
||||
case BluetoothDeviceAttribute::Name: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothRemoteName);
|
||||
nsAutoString remoteNameStr;
|
||||
RemoteNameToString(aValue.get_BluetoothRemoteName(), remoteNameStr);
|
||||
return !mName.Equals(remoteNameStr);
|
||||
}
|
||||
case BluetoothDeviceAttribute::Paired:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tbool);
|
||||
return mPaired != aValue.get_bool();
|
||||
|
@ -48,13 +48,17 @@ BluetoothPairingListener::~BluetoothPairingListener()
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothPairingListener::DispatchPairingEvent(const nsAString& aName,
|
||||
const BluetoothAddress& aAddress,
|
||||
const nsAString& aPasskey,
|
||||
const nsAString& aType)
|
||||
BluetoothPairingListener::DispatchPairingEvent(
|
||||
const BluetoothRemoteName& aName,
|
||||
const BluetoothAddress& aAddress,
|
||||
const nsAString& aPasskey,
|
||||
const nsAString& aType)
|
||||
{
|
||||
MOZ_ASSERT(!aAddress.IsCleared());
|
||||
MOZ_ASSERT(!aName.IsEmpty() && !aType.IsEmpty());
|
||||
MOZ_ASSERT(!aName.IsCleared() && !aType.IsEmpty());
|
||||
|
||||
nsString nameStr;
|
||||
RemoteNameToString(aName, nameStr);
|
||||
|
||||
nsString addressStr;
|
||||
AddressToString(aAddress, addressStr);
|
||||
@ -66,7 +70,7 @@ BluetoothPairingListener::DispatchPairingEvent(const nsAString& aName,
|
||||
aPasskey);
|
||||
|
||||
BluetoothPairingEventInit init;
|
||||
init.mDeviceName = aName;
|
||||
init.mDeviceName = nameStr;
|
||||
init.mHandle = handle;
|
||||
|
||||
RefPtr<BluetoothPairingEvent> event =
|
||||
@ -92,12 +96,12 @@ BluetoothPairingListener::Notify(const BluetoothSignal& aData)
|
||||
|
||||
MOZ_ASSERT(arr.Length() == 4 &&
|
||||
arr[0].value().type() == BluetoothValue::TBluetoothAddress && // address
|
||||
arr[1].value().type() == BluetoothValue::TnsString && // name
|
||||
arr[1].value().type() == BluetoothValue::TBluetoothRemoteName && // name
|
||||
arr[2].value().type() == BluetoothValue::TnsString && // passkey
|
||||
arr[3].value().type() == BluetoothValue::TnsString); // type
|
||||
|
||||
BluetoothAddress address = arr[0].value().get_BluetoothAddress();
|
||||
nsString name = arr[1].value().get_nsString();
|
||||
const BluetoothRemoteName& name = arr[1].value().get_BluetoothRemoteName();
|
||||
nsString passkey = arr[2].value().get_nsString();
|
||||
nsString type = arr[3].value().get_nsString();
|
||||
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
static already_AddRefed<BluetoothPairingListener>
|
||||
Create(nsPIDOMWindow* aWindow);
|
||||
|
||||
void DispatchPairingEvent(const nsAString& aName,
|
||||
void DispatchPairingEvent(const BluetoothRemoteName& aName,
|
||||
const BluetoothAddress& aAddress,
|
||||
const nsAString& aPasskey,
|
||||
const nsAString& aType);
|
||||
|
@ -79,6 +79,36 @@ struct ParamTraits<mozilla::dom::bluetooth::BluetoothPinCode>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::bluetooth::BluetoothRemoteName>
|
||||
{
|
||||
typedef mozilla::dom::bluetooth::BluetoothRemoteName paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mLength);
|
||||
for (size_t i = 0; i < aParam.mLength; ++i) {
|
||||
WriteParam(aMsg, aParam.mName[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (!ReadParam(aMsg, aIter, &aResult->mLength)) {
|
||||
return false;
|
||||
}
|
||||
if (aResult->mLength > MOZ_ARRAY_LENGTH(aResult->mName)) {
|
||||
return false;
|
||||
}
|
||||
for (uint8_t i = 0; i < aResult->mLength; ++i) {
|
||||
if (!ReadParam(aMsg, aIter, aResult->mName + i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::bluetooth::BluetoothSspVariant>
|
||||
: public ContiguousEnumSerializer<
|
||||
|
@ -22,6 +22,8 @@ using mozilla::dom::bluetooth::BluetoothGattServiceId
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothGattWriteType
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothRemoteName
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothSspVariant
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothStatus
|
||||
@ -57,6 +59,7 @@ union BluetoothValue
|
||||
BluetoothAddress;
|
||||
BluetoothAddress[];
|
||||
BluetoothAttributeHandle;
|
||||
BluetoothRemoteName;
|
||||
BluetoothUuid;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user