Merge b2ginbound to central, a=merge CLOSED TREE

This commit is contained in:
Wes Kocher 2015-09-23 13:18:17 -07:00
commit bc2999da84
84 changed files with 5628 additions and 761 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -129,7 +129,7 @@
<!-- Emulator specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="8d4018ebd33ac3f1a043b2d54bc578028656a659"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="b2d449276b015d8fe6cd9ea60c389c7e6975f841"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="e002268b30ce69725e60fdc827a19d729cce7396"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
<project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="7132bc11fbc68acfebcd509095562ca04fad5584"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "aad942e6960cdd6b2d09900b157b16f4ddb9423c",
"git_revision": "8472f0c736660072799aaae60e4b6001a6aaceb4",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "1c723e1073f387534a091afba1ed5fbac0461c57",
"revision": "e4b5ba76d5a4de0cd220310e0fe2ba334f0e250a",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="aad942e6960cdd6b2d09900b157b16f4ddb9423c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8472f0c736660072799aaae60e4b6001a6aaceb4"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -684,6 +684,8 @@ GK_ATOM(onanimationstart, "onanimationstart")
GK_ATOM(onantennaavailablechange, "onantennaavailablechange")
GK_ATOM(onAppCommand, "onAppCommand")
GK_ATOM(onattributechanged, "onattributechanged")
GK_ATOM(onattributereadreq, "onattributereadreq")
GK_ATOM(onattributewritereq, "onattributewritereq")
GK_ATOM(onaudioprocess, "onaudioprocess")
GK_ATOM(onbeforecopy, "onbeforecopy")
GK_ATOM(onbeforecut, "onbeforecut")

View File

@ -166,6 +166,10 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGatt',
},
'BluetoothGattAttributeEvent': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGattAttributeEvent',
},
'BluetoothGattCharacteristic': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGattCharacteristic',
},

View File

@ -762,7 +762,7 @@ BluetoothDaemonGattModule::ServerDisconnectPeripheralCmd(
nsresult
BluetoothDaemonGattModule::ServerAddServiceCmd(
int aServerIf, const BluetoothGattServiceId& aServiceId, int aNumHandles,
int aServerIf, const BluetoothGattServiceId& aServiceId, uint16_t aNumHandles,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -774,7 +774,7 @@ BluetoothDaemonGattModule::ServerAddServiceCmd(
4)); // Number of Handles
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf), aServiceId,
PackConversion<int, int32_t>(aNumHandles), *pdu);
PackConversion<uint16_t, int32_t>(aNumHandles), *pdu);
if (NS_FAILED(rv)) {
return rv;
}
@ -788,7 +788,8 @@ BluetoothDaemonGattModule::ServerAddServiceCmd(
nsresult
BluetoothDaemonGattModule::ServerAddIncludedServiceCmd(
int aServerIf, int aServiceHandle, int aIncludedServiceHandle,
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -800,9 +801,7 @@ BluetoothDaemonGattModule::ServerAddIncludedServiceCmd(
4)); // Included Service Handle
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aServiceHandle),
PackConversion<int, int32_t>(aIncludedServiceHandle),
*pdu);
aServiceHandle, aIncludedServiceHandle, *pdu);
if (NS_FAILED(rv)) {
return rv;
}
@ -816,9 +815,9 @@ BluetoothDaemonGattModule::ServerAddIncludedServiceCmd(
nsresult
BluetoothDaemonGattModule::ServerAddCharacteristicCmd(
int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
BluetoothGattCharProp aProperties, BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid, BluetoothGattCharProp aProperties,
BluetoothGattAttrPerm aPermissions, BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -830,9 +829,10 @@ BluetoothDaemonGattModule::ServerAddCharacteristicCmd(
4 + // Properties
4)); // Permissions
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aServiceHandle),
aUuid, aProperties, aPermissions, *pdu);
nsresult rv = PackPDU(
PackConversion<int, int32_t>(aServerIf), aServiceHandle, aUuid,
PackConversion<BluetoothGattCharProp, int32_t>(aProperties),
PackConversion<BluetoothGattAttrPerm, int32_t>(aPermissions), *pdu);
if (NS_FAILED(rv)) {
return rv;
}
@ -846,8 +846,9 @@ BluetoothDaemonGattModule::ServerAddCharacteristicCmd(
nsresult
BluetoothDaemonGattModule::ServerAddDescriptorCmd(
int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
BluetoothGattAttrPerm aPermissions, BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid, BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -858,9 +859,9 @@ BluetoothDaemonGattModule::ServerAddDescriptorCmd(
16 + // UUID
4)); // Permissions
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aServiceHandle),
aUuid, aPermissions, *pdu);
nsresult rv = PackPDU(
PackConversion<int, int32_t>(aServerIf), aServiceHandle, aUuid,
PackConversion<BluetoothGattAttrPerm, int32_t>(aPermissions), *pdu);
if (NS_FAILED(rv)) {
return rv;
}
@ -874,8 +875,8 @@ BluetoothDaemonGattModule::ServerAddDescriptorCmd(
nsresult
BluetoothDaemonGattModule::ServerStartServiceCmd(
int aServerIf, int aServiceHandle, BluetoothTransport aTransport,
BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -886,8 +887,7 @@ BluetoothDaemonGattModule::ServerStartServiceCmd(
4)); // Transport
nsresult rv = PackPDU(
PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aServiceHandle),
PackConversion<int, int32_t>(aServerIf), aServiceHandle,
PackConversion<BluetoothTransport, int32_t>(aTransport), *pdu);
if (NS_FAILED(rv)) {
return rv;
@ -902,7 +902,8 @@ BluetoothDaemonGattModule::ServerStartServiceCmd(
nsresult
BluetoothDaemonGattModule::ServerStopServiceCmd(
int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -911,8 +912,8 @@ BluetoothDaemonGattModule::ServerStopServiceCmd(
4 + // Server Interface
4)); // Service Handle
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aServiceHandle), *pdu);
nsresult rv = PackPDU(
PackConversion<int, int32_t>(aServerIf), aServiceHandle, *pdu);
if (NS_FAILED(rv)) {
return rv;
}
@ -926,7 +927,8 @@ BluetoothDaemonGattModule::ServerStopServiceCmd(
nsresult
BluetoothDaemonGattModule::ServerDeleteServiceCmd(
int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -935,8 +937,8 @@ BluetoothDaemonGattModule::ServerDeleteServiceCmd(
4 + // Server Interface
4)); // Service Handle
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aServiceHandle), *pdu);
nsresult rv = PackPDU(
PackConversion<int, int32_t>(aServerIf), aServiceHandle, *pdu);
if (NS_FAILED(rv)) {
return rv;
}
@ -950,7 +952,8 @@ BluetoothDaemonGattModule::ServerDeleteServiceCmd(
nsresult
BluetoothDaemonGattModule::ServerSendIndicationCmd(
int aServerIf, int aAttributeHandle, int aConnId, int aLength, bool aConfirm,
int aServerIf, const BluetoothAttributeHandle& aCharacteristicHandle,
int aConnId, int aLength, bool aConfirm,
uint8_t* aValue, BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -960,7 +963,7 @@ BluetoothDaemonGattModule::ServerSendIndicationCmd(
0));
nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
PackConversion<int, int32_t>(aAttributeHandle),
aCharacteristicHandle,
PackConversion<int, int32_t>(aConnId),
PackConversion<int, int32_t>(aLength),
PackConversion<bool, int32_t>(aConfirm),
@ -978,7 +981,7 @@ BluetoothDaemonGattModule::ServerSendIndicationCmd(
nsresult
BluetoothDaemonGattModule::ServerSendResponseCmd(
int aConnId, int aTransId, BluetoothGattStatus aStatus,
int aConnId, int aTransId, uint16_t aStatus,
const BluetoothGattResponse& aResponse,
BluetoothGattResultHandler* aRes)
{
@ -994,7 +997,7 @@ BluetoothDaemonGattModule::ServerSendResponseCmd(
aResponse.mHandle,
aResponse.mOffset,
PackConversion<BluetoothGattAuthReq, uint8_t>(aResponse.mAuthReq),
PackConversion<BluetoothGattStatus, int32_t>(aStatus),
PackConversion<uint16_t, int32_t>(aStatus),
aResponse.mLength,
PackArray<uint8_t>(aResponse.mValue, aResponse.mLength), *pdu);
@ -1938,7 +1941,7 @@ public:
operator () (int& aArg1,
int& aArg2,
nsString& aArg3,
int& aArg4,
BluetoothAttributeHandle& aArg4,
int& aArg5,
bool& aArg6) const
{
@ -2003,7 +2006,7 @@ public:
operator () (int& aArg1,
int& aArg2,
nsString& aArg3,
int& aArg4,
BluetoothAttributeHandle& aArg4,
int& aArg5,
int& aArg6,
nsAutoArrayPtr<uint8_t>& aArg7,
@ -2696,7 +2699,7 @@ BluetoothDaemonGattInterface::DisconnectPeripheral(
/* Add a services / a characteristic / a descriptor */
void
BluetoothDaemonGattInterface::AddService(
int aServerIf, const BluetoothGattServiceId& aServiceId, int aNumHandles,
int aServerIf, const BluetoothGattServiceId& aServiceId, uint16_t aNumHandles,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2711,7 +2714,8 @@ BluetoothDaemonGattInterface::AddService(
void
BluetoothDaemonGattInterface::AddIncludedService(
int aServerIf, int aServiceHandle, int aIncludedServiceHandle,
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2726,9 +2730,9 @@ BluetoothDaemonGattInterface::AddIncludedService(
void
BluetoothDaemonGattInterface::AddCharacteristic(
int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
BluetoothGattCharProp aProperties, BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid, BluetoothGattCharProp aProperties,
BluetoothGattAttrPerm aPermissions, BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2742,8 +2746,9 @@ BluetoothDaemonGattInterface::AddCharacteristic(
void
BluetoothDaemonGattInterface::AddDescriptor(
int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
BluetoothGattAttrPerm aPermissions, BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid, BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2758,8 +2763,8 @@ BluetoothDaemonGattInterface::AddDescriptor(
/* Start / Stop / Delete a service */
void
BluetoothDaemonGattInterface::StartService(
int aServerIf, int aServiceHandle, BluetoothTransport aTransport,
BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2773,7 +2778,8 @@ BluetoothDaemonGattInterface::StartService(
void
BluetoothDaemonGattInterface::StopService(
int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2786,7 +2792,8 @@ BluetoothDaemonGattInterface::StopService(
void
BluetoothDaemonGattInterface::DeleteService(
int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
int aServerIf, const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
@ -2800,14 +2807,14 @@ BluetoothDaemonGattInterface::DeleteService(
void
BluetoothDaemonGattInterface::SendIndication(
int aServerIf, int aAttributeHandle, int aConnId,
const nsTArray<uint8_t>& aValue, bool aConfirm,
int aServerIf, const BluetoothAttributeHandle& aCharacteristicHandle,
int aConnId, const nsTArray<uint8_t>& aValue, bool aConfirm,
BluetoothGattResultHandler* aRes)
{
MOZ_ASSERT(mModule);
nsresult rv = mModule->ServerSendIndicationCmd(
aServerIf, aAttributeHandle, aConnId,
aServerIf, aCharacteristicHandle, aConnId,
aValue.Length() * sizeof(uint8_t), aConfirm,
const_cast<uint8_t*>(aValue.Elements()), aRes);
@ -2818,7 +2825,7 @@ BluetoothDaemonGattInterface::SendIndication(
void
BluetoothDaemonGattInterface::SendResponse(
int aConnId, int aTransId, BluetoothGattStatus aStatus,
int aConnId, int aTransId, uint16_t aStatus,
const BluetoothGattResponse& aResponse,
BluetoothGattResultHandler* aRes)
{

View File

@ -247,54 +247,59 @@ public:
/* Add a services / a characteristic / a descriptor */
nsresult ServerAddServiceCmd(int aServerIf,
const BluetoothGattServiceId& aServiceId,
int aNumHandles,
uint16_t aNumHandles,
BluetoothGattResultHandler* aRes);
nsresult ServerAddIncludedServiceCmd(int aServerIf,
int aServiceHandle,
int aIncludedServiceHandle,
BluetoothGattResultHandler* aRes);
nsresult ServerAddIncludedServiceCmd(
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothGattResultHandler* aRes);
nsresult ServerAddCharacteristicCmd(int aServerIf,
int aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattCharProp aProperties,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes);
nsresult ServerAddCharacteristicCmd(
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattCharProp aProperties,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes);
nsresult ServerAddDescriptorCmd(int aServerIf,
int aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes);
nsresult ServerAddDescriptorCmd(
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes);
/* Start / Stop / Delete a service */
nsresult ServerStartServiceCmd(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothTransport aTransport,
BluetoothGattResultHandler* aRes);
nsresult ServerStopServiceCmd(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes);
nsresult ServerDeleteServiceCmd(int aServerIf,
int aServiceHandle,
BluetoothGattResultHandler* aRes);
nsresult ServerDeleteServiceCmd(
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes);
/* Send an indication or a notification */
nsresult ServerSendIndicationCmd(int aServerIf,
int aAttributeHandle,
int aConnId,
int aLength,
bool aConfirm,
uint8_t* aValue,
BluetoothGattResultHandler* aRes);
nsresult ServerSendIndicationCmd(
int aServerIf,
const BluetoothAttributeHandle& aCharacteristicHandle,
int aConnId,
int aLength,
bool aConfirm,
uint8_t* aValue,
BluetoothGattResultHandler* aRes);
/* Send a response for an incoming indication */
nsresult ServerSendResponseCmd(int aConnId,
int aTransId,
BluetoothGattStatus aStatus,
uint16_t aStatus,
const BluetoothGattResponse& aResponse,
BluetoothGattResultHandler* aRes);
// TODO: Add L support
@ -602,52 +607,65 @@ protected:
typedef mozilla::ipc::DaemonNotificationRunnable4<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, BluetoothGattServiceId, int,
BluetoothGattStatus, int, const BluetoothGattServiceId&, int>
BluetoothGattStatus, int, BluetoothGattServiceId, BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothGattServiceId&,
const BluetoothAttributeHandle&>
ServerServiceAddedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable4<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, int, int>
BluetoothGattStatus, int, BluetoothAttributeHandle,
BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothAttributeHandle&,
const BluetoothAttributeHandle&>
ServerIncludedServiceAddedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable5<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, BluetoothUuid, int, int,
BluetoothGattStatus, int, const BluetoothUuid&, int, int>
BluetoothGattStatus, int, BluetoothUuid, BluetoothAttributeHandle,
BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothUuid&,
const BluetoothAttributeHandle&, const BluetoothAttributeHandle&>
ServerCharacteristicAddedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable5<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, BluetoothUuid, int, int,
BluetoothGattStatus, int, const BluetoothUuid&, int, int>
BluetoothGattStatus, int, BluetoothUuid, BluetoothAttributeHandle,
BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothUuid&,
const BluetoothAttributeHandle&, const BluetoothAttributeHandle&>
ServerDescriptorAddedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable3<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, int>
BluetoothGattStatus, int, BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothAttributeHandle&>
ServerServiceStartedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable3<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, int>
BluetoothGattStatus, int, BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothAttributeHandle&>
ServerServiceStoppedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable3<
NotificationHandlerWrapper, void,
BluetoothGattStatus, int, int>
BluetoothGattStatus, int, BluetoothAttributeHandle,
BluetoothGattStatus, int, const BluetoothAttributeHandle&>
ServerServiceDeletedNotification;
typedef mozilla::ipc::DaemonNotificationRunnable6<
NotificationHandlerWrapper, void,
int, int, nsString, int, int, bool,
int, int, const nsAString&, int, int, bool>
int, int, nsString, BluetoothAttributeHandle, int, bool,
int, int, const nsAString&, const BluetoothAttributeHandle&, int, bool>
ServerRequestReadNotification;
typedef mozilla::ipc::DaemonNotificationRunnable9<
NotificationHandlerWrapper, void,
int, int, nsString, int, int, int, nsAutoArrayPtr<uint8_t>, bool, bool,
int, int, const nsAString&, int, int, int, const uint8_t*, bool, bool>
int, int, nsString, BluetoothAttributeHandle, int, int,
nsAutoArrayPtr<uint8_t>, bool, bool,
int, int, const nsAString&, const BluetoothAttributeHandle&, int, int,
const uint8_t*, bool, bool>
ServerRequestWriteNotification;
typedef mozilla::ipc::DaemonNotificationRunnable4<
@ -929,40 +947,40 @@ public:
/* Add a services / a characteristic / a descriptor */
void AddService(int aServerIf,
const BluetoothGattServiceId& aServiceId,
int aNumHandles,
uint16_t aNumHandles,
BluetoothGattResultHandler* aRes) override;
void AddIncludedService(int aServerIf,
int aServiceHandle,
int aIncludedServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothGattResultHandler* aRes) override;
void AddCharacteristic(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattCharProp aProperties,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes) override;
void AddDescriptor(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes) override;
/* Start / Stop / Delete a service */
void StartService(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothTransport aTransport,
BluetoothGattResultHandler* aRes) override;
void StopService(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes) override;
void DeleteService(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes) override;
/* Send an indication or a notification */
void SendIndication(
int aServerIf,
int aAttributeHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
int aConnId,
const nsTArray<uint8_t>& aValue,
bool aConfirm, /* true: indication, false: notification */
@ -971,7 +989,7 @@ public:
/* Send a response for an incoming indication */
void SendResponse(int aConnId,
int aTransId,
BluetoothGattStatus aStatus,
uint16_t aStatus,
const BluetoothGattResponse& aResponse,
BluetoothGattResultHandler* aRes) override;

View File

@ -466,6 +466,17 @@ Convert(uint8_t aIn, BluetoothStatus& aOut)
return NS_OK;
}
nsresult
Convert(int32_t aIn, BluetoothAttributeHandle& aOut)
{
if (NS_WARN_IF(aIn < 0x0000) || NS_WARN_IF(aIn > 0xFFFF)) {
aOut.mHandle = 0x0000; // silences compiler warning
return NS_ERROR_ILLEGAL_VALUE;
}
aOut.mHandle = static_cast<uint16_t>(aIn);
return NS_OK;
}
nsresult
Convert(int32_t aIn, BluetoothGattStatus& aOut)
{
@ -634,6 +645,13 @@ Convert(const BluetoothAddress& aIn, nsAString& aOut)
return NS_OK;
}
nsresult
Convert(const BluetoothAttributeHandle& aIn, int32_t& aOut)
{
aOut = static_cast<int32_t>(aIn.mHandle);
return NS_OK;
}
nsresult
Convert(BluetoothAvrcpEvent aIn, uint8_t& aOut)
{
@ -1080,6 +1098,12 @@ PackPDU(const BluetoothAddress& aIn, DaemonSocketPDU& aPDU)
return PackPDU(PackArray<uint8_t>(aIn.mAddr, sizeof(aIn.mAddr)), aPDU);
}
nsresult
PackPDU(const BluetoothAttributeHandle& aIn, DaemonSocketPDU& aPDU)
{
return PackPDU(PackConversion<BluetoothAttributeHandle, int32_t>(aIn), aPDU);
}
nsresult
PackPDU(const BluetoothAvrcpAttributeTextPairs& aIn,
DaemonSocketPDU& aPDU)
@ -1456,6 +1480,13 @@ UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAclState& aOut)
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothAclState>(aOut));
}
nsresult
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAttributeHandle& aOut)
{
return UnpackPDU(
aPDU, UnpackConversion<int32_t, BluetoothAttributeHandle>(aOut));
}
nsresult
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpEvent& aOut)
{

View File

@ -198,6 +198,9 @@ Convert(uint8_t aIn, BluetoothSspVariant& aOut);
nsresult
Convert(uint8_t aIn, BluetoothStatus& aOut);
nsresult
Convert(int32_t aIn, BluetoothAttributeHandle& aOut);
nsresult
Convert(int32_t aIn, BluetoothGattStatus& aOut);
@ -219,6 +222,9 @@ Convert(BluetoothAclState aIn, bool& aOut);
nsresult
Convert(const BluetoothAddress& aIn, nsAString& aOut);
nsresult
Convert(const BluetoothAttributeHandle& aIn, int32_t& aOut);
nsresult
Convert(BluetoothAvrcpEvent aIn, uint8_t& aOut);
@ -298,6 +304,9 @@ Convert(nsresult aIn, BluetoothStatus& aOut);
nsresult
PackPDU(const BluetoothAddress& aIn, DaemonSocketPDU& aPDU);
nsresult
PackPDU(const BluetoothAttributeHandle& aIn, DaemonSocketPDU& aPDU);
nsresult
PackPDU(const BluetoothAvrcpAttributeTextPairs& aIn,
DaemonSocketPDU& aPDU);
@ -430,6 +439,9 @@ UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAddress& aOut)
return aPDU.Read(aOut.mAddr, sizeof(aOut.mAddr));
}
nsresult
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAttributeHandle& aOut);
nsresult
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpEvent& aOut);

File diff suppressed because it is too large Load Diff

View File

@ -103,6 +103,65 @@ public:
void UnregisterServer(int aServerIf,
BluetoothReplyRunnable* aRunnable);
void ServerAddService(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable);
void ServerAddIncludedService(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable);
void ServerAddCharacteristic(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable);
void ServerAddDescriptor(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable);
void ServerRemoveService(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable);
void ServerStartService(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable);
void ServerStopService(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable);
void ServerSendResponse(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable);
void ServerSendIndication(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable);
private:
~BluetoothGattManager();
@ -129,6 +188,15 @@ private:
class ConnectPeripheralResultHandler;
class DisconnectPeripheralResultHandler;
class UnregisterServerResultHandler;
class ServerAddServiceResultHandler;
class ServerAddIncludedServiceResultHandler;
class ServerAddCharacteristicResultHandler;
class ServerAddDescriptorResultHandler;
class ServerRemoveDescriptorResultHandler;
class ServerStartServiceResultHandler;
class ServerStopServiceResultHandler;
class ServerSendResponseResultHandler;
class ServerSendIndicationResultHandler;
BluetoothGattManager();
@ -227,6 +295,73 @@ private:
bool aConnected,
const nsAString& aBdAddr) override;
void
ServiceAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothGattServiceId& aServiceId,
const BluetoothAttributeHandle& aServiceHandle) override;
void
IncludedServiceAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle) override;
void
CharacteristicAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothUuid& aCharId,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle) override;
void
DescriptorAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothUuid& aCharId,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aDescriptorHandle) override;
void
ServiceStartedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle) override;
void
ServiceStoppedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle) override;
void
ServiceDeletedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle) override;
void
RequestReadNotification(int aConnId,
int aTransId,
const nsAString& aBdAddr,
const BluetoothAttributeHandle& aAttributeHandle,
int aOffset,
bool aIsLong) override;
void
RequestWriteNotification(int aConnId,
int aTransId,
const nsAString& aBdAddr,
const BluetoothAttributeHandle& aAttributeHandle,
int aOffset,
int aLength,
const uint8_t* aValue,
bool aNeedResponse,
bool aIsPrepareWrite) override;
static bool mInShutdown;
};

View File

@ -603,6 +603,183 @@ BluetoothServiceBluedroid::UnregisterGattServerInternal(
gatt->UnregisterServer(aServerIf, aRunnable);
}
void
BluetoothServiceBluedroid::GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerAddService(aAppUuid, aServiceId, aHandleCount, aRunnable);
}
void
BluetoothServiceBluedroid::GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerAddIncludedService(aAppUuid,
aServiceHandle,
aIncludedServiceHandle,
aRunnable);
}
void
BluetoothServiceBluedroid::GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerAddCharacteristic(aAppUuid,
aServiceHandle,
aCharacteristicUuid,
aPermissions,
aProperties,
aRunnable);
}
void
BluetoothServiceBluedroid::GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerAddDescriptor(aAppUuid,
aServiceHandle,
aCharacteristicHandle,
aDescriptorUuid,
aPermissions,
aRunnable);
}
void
BluetoothServiceBluedroid::GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerRemoveService(aAppUuid, aServiceHandle, aRunnable);
}
void
BluetoothServiceBluedroid::GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerStartService(aAppUuid, aServiceHandle, aRunnable);
}
void
BluetoothServiceBluedroid::GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerStopService(aAppUuid, aServiceHandle, aRunnable);
}
void
BluetoothServiceBluedroid::GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerSendResponse(
aAppUuid, aAddress, aStatus, aRequestId, aRsp, aRunnable);
}
void
BluetoothServiceBluedroid::GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ServerSendIndication(aAppUuid,
aAddress,
aCharacteristicHandle,
aConfirm,
aValue,
aRunnable);
}
nsresult
BluetoothServiceBluedroid::GetAdaptersInternal(
BluetoothReplyRunnable* aRunnable)

View File

@ -310,6 +310,74 @@ public:
UnregisterGattServerInternal(int aServerIf,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable) override;
//
// Bluetooth notifications
//

View File

@ -4438,3 +4438,89 @@ BluetoothDBusService::UnregisterGattServerInternal(
int aServerIf, BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable)
{
}

View File

@ -321,6 +321,74 @@ public:
UnregisterGattServerInternal(int aServerIf,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable) override;
private:
nsresult SendGetPropertyMessage(const nsAString& aPath,
const char* aInterface,

View File

@ -112,6 +112,68 @@ extern bool gBluetoothDebugFlag;
#define BT_ENSURE_SUCCESS_REJECT(rv, promise, ret) \
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), promise, ret)
/**
* Resolve |promise| with |value| and return |ret| if |x| is false.
*/
#define BT_ENSURE_TRUE_RESOLVE_RETURN(x, promise, value, ret) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
BT_LOGR("BT_ENSURE_TRUE_RESOLVE_RETURN(" #x ") failed"); \
(promise)->MaybeResolve(value); \
return ret; \
} \
} while(0)
/**
* Resolve |promise| with |value| and return if |x| is false.
*/
#define BT_ENSURE_TRUE_RESOLVE_VOID(x, promise, value) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
BT_LOGR("BT_ENSURE_TRUE_RESOLVE_VOID(" #x ") failed"); \
(promise)->MaybeResolve(value); \
return; \
} \
} while(0)
/**
* Reject |promise| with |value| and return |ret| if |x| is false.
*/
#define BT_ENSURE_TRUE_REJECT_RETURN(x, promise, value, ret) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
BT_LOGR("BT_ENSURE_TRUE_REJECT_RETURN(" #x ") failed"); \
(promise)->MaybeReject(value); \
return ret; \
} \
} while(0)
/**
* Reject |promise| with |value| and return if |x| is false.
*/
#define BT_ENSURE_TRUE_REJECT_VOID(x, promise, value) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
BT_LOGR("BT_ENSURE_TRUE_REJECT_VOID(" #x ") failed"); \
(promise)->MaybeReject(value); \
return; \
} \
} while(0)
/**
* Reject |promise| with |value| and return |ret| if nsresult |rv|
* is not successful.
*/
#define BT_ENSURE_SUCCESS_REJECT_RETURN(rv, promise, value, ret) \
BT_ENSURE_TRUE_REJECT_RETURN(NS_SUCCEEDED(rv), promise, value, ret)
/**
* Reject |promise| with |value| and return if nsresult |rv|
* is not successful.
*/
#define BT_ENSURE_SUCCESS_REJECT_VOID(rv, promise, value) \
BT_ENSURE_TRUE_REJECT_VOID(NS_SUCCEEDED(rv), promise, value)
#define BEGIN_BLUETOOTH_NAMESPACE \
namespace mozilla { namespace dom { namespace bluetooth {
#define END_BLUETOOTH_NAMESPACE \
@ -212,6 +274,13 @@ extern bool gBluetoothDebugFlag;
*/
#define ATTRIBUTE_CHANGED_ID "attributechanged"
/**
* When the local GATT server received attribute read/write requests, we'll
* dispatch an event.
*/
#define ATTRIBUTE_READ_REQUEST "attributereadreq"
#define ATTRIBUTE_WRITE_REQUEST "attributewritereq"
// Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx)
#define BLUETOOTH_ADDRESS_LENGTH 17
#define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00"
@ -601,6 +670,11 @@ struct BluetoothAvrcpPlayerSettings {
uint8_t mValues[256];
};
enum BluetoothAttRole {
ATT_SERVER_ROLE,
ATT_CLIENT_ROLE
};
enum BluetoothGattStatus {
GATT_STATUS_SUCCESS,
GATT_STATUS_INVALID_HANDLE,
@ -628,7 +702,8 @@ enum BluetoothGattAuthReq {
GATT_AUTH_REQ_NO_MITM,
GATT_AUTH_REQ_MITM,
GATT_AUTH_REQ_SIGNED_NO_MITM,
GATT_AUTH_REQ_SIGNED_MITM
GATT_AUTH_REQ_SIGNED_MITM,
GATT_AUTH_REQ_END_GUARD
};
enum BluetoothGattWriteType {
@ -754,12 +829,34 @@ struct BluetoothGattTestParam {
uint16_t mU5;
};
struct BluetoothGattResponse {
struct BluetoothAttributeHandle {
uint16_t mHandle;
BluetoothAttributeHandle()
: mHandle(0x0000)
{ }
bool operator==(const BluetoothAttributeHandle& aOther) const
{
return mHandle == aOther.mHandle;
}
};
struct BluetoothGattResponse {
BluetoothAttributeHandle mHandle;
uint16_t mOffset;
uint16_t mLength;
BluetoothGattAuthReq mAuthReq;
uint8_t mValue[BLUETOOTH_GATT_MAX_ATTR_LEN];
bool operator==(const BluetoothGattResponse& aOther) const
{
return mHandle == aOther.mHandle &&
mOffset == aOther.mOffset &&
mLength == aOther.mLength &&
mAuthReq == aOther.mAuthReq &&
!memcmp(mValue, aOther.mValue, mLength);
}
};
/**
@ -771,7 +868,7 @@ enum BluetoothGapDataType {
GAP_INCOMPLETE_UUID16 = 0X02, // Incomplete List of 16-bit Service Class UUIDs
GAP_COMPLETE_UUID16 = 0X03, // Complete List of 16-bit Service Class UUIDs
GAP_INCOMPLETE_UUID32 = 0X04, // Incomplete List of 32-bit Service Class UUIDs
GAP_COMPLETE_UUID32 = 0X05, // Complete List of 32-bit Service Class UUIDs»
GAP_COMPLETE_UUID32 = 0X05, // Complete List of 32-bit Service Class UUIDs
GAP_INCOMPLETE_UUID128 = 0X06, // Incomplete List of 128-bit Service Class UUIDs
GAP_COMPLETE_UUID128 = 0X07, // Complete List of 128-bit Service Class UUIDs
GAP_SHORTENED_NAME = 0X08, // Shortened Local Name

View File

@ -589,53 +589,60 @@ BluetoothGattNotificationHandler::ConnectionNotification(
void
BluetoothGattNotificationHandler::ServiceAddedNotification(
BluetoothGattStatus aStatus, int aServerIf,
const BluetoothGattServiceId& aServiceId, int aServiceHandle)
const BluetoothGattServiceId& aServiceId,
const BluetoothAttributeHandle& aServiceHandle)
{ }
void
BluetoothGattNotificationHandler::IncludedServiceAddedNotification(
BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle,
int aIncludedServiceHandle)
BluetoothGattStatus aStatus, int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle)
{ }
void
BluetoothGattNotificationHandler::CharacteristicAddedNotification(
BluetoothGattStatus aStatus, int aServerIf, const BluetoothUuid& aCharId,
int aServiceHandle, int aCharacteristicHandle)
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle)
{ }
void
BluetoothGattNotificationHandler::DescriptorAddedNotification(
BluetoothGattStatus aStatus, int aServerIf, const BluetoothUuid& aCharId,
int aServiceHandle, int aDescriptorHandle)
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aDescriptorHandle)
{ }
void
BluetoothGattNotificationHandler::ServiceStartedNotification(
BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle)
BluetoothGattStatus aStatus, int aServerIf,
const BluetoothAttributeHandle& aServiceHandle)
{ }
void
BluetoothGattNotificationHandler::ServiceStoppedNotification(
BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle)
BluetoothGattStatus aStatus, int aServerIf,
const BluetoothAttributeHandle& aServiceHandle)
{ }
void
BluetoothGattNotificationHandler::ServiceDeletedNotification(
BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle)
BluetoothGattStatus aStatus, int aServerIf,
const BluetoothAttributeHandle& aServiceHandle)
{ }
void
BluetoothGattNotificationHandler::RequestReadNotification(
int aConnId, int aTransId, const nsAString& aBdAddr, int aAttributeHandle,
int aOffset, bool aIsLong)
int aConnId, int aTransId, const nsAString& aBdAddr,
const BluetoothAttributeHandle& aAttributeHandle, int aOffset, bool aIsLong)
{ }
void
BluetoothGattNotificationHandler::RequestWriteNotification(
int aConnId, int aTransId, const nsAString& aBdAddr, int aAttributeHandle,
int aOffset, int aLength, const uint8_t* aValue, bool aNeedResponse,
bool aIsPrepareWrite)
int aConnId, int aTransId, const nsAString& aBdAddr,
const BluetoothAttributeHandle& aAttributeHandle, int aOffset, int aLength,
const uint8_t* aValue, bool aNeedResponse, bool aIsPrepareWrite)
{ }
void

View File

@ -569,48 +569,51 @@ public:
ServiceAddedNotification(BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothGattServiceId& aServiceId,
int aServiceHandle);
const BluetoothAttributeHandle& aServiceHandle);
virtual void
IncludedServiceAddedNotification(BluetoothGattStatus aStatus,
int aServerIf,
int aServiceHandle,
int aIncludedServiceHandle);
IncludedServiceAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle);
virtual void
CharacteristicAddedNotification(BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothUuid& aCharId,
int aServiceHandle,
int aCharacteristicHandle);
CharacteristicAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothUuid& aCharId,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle);
virtual void
DescriptorAddedNotification(BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothUuid& aCharId,
int aServiceHandle,
int aDescriptorHandle);
DescriptorAddedNotification(
BluetoothGattStatus aStatus,
int aServerIf,
const BluetoothUuid& aCharId,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aDescriptorHandle);
virtual void
ServiceStartedNotification(BluetoothGattStatus aStatus,
int aServerIf,
int aServiceHandle);
const BluetoothAttributeHandle& aServiceHandle);
virtual void
ServiceStoppedNotification(BluetoothGattStatus aStatus,
int aServerIf,
int aServiceHandle);
const BluetoothAttributeHandle& aServiceHandle);
virtual void
ServiceDeletedNotification(BluetoothGattStatus aStatus,
int aServerIf,
int aServiceHandle);
const BluetoothAttributeHandle& aServiceHandle);
virtual void
RequestReadNotification(int aConnId,
int aTransId,
const nsAString& aBdAddr,
int aAttributeHandle,
const BluetoothAttributeHandle& aAttributeHandle,
int aOffset,
bool aIsLong);
@ -618,7 +621,7 @@ public:
RequestWriteNotification(int aConnId,
int aTransId,
const nsAString& aBdAddr,
int aAttributeHandle,
const BluetoothAttributeHandle& aAttributeHandle,
int aOffset,
int aLength,
const uint8_t* aValue,
@ -871,49 +874,50 @@ public:
/* Add a services / a characteristic / a descriptor */
virtual void AddService(int aServerIf,
const BluetoothGattServiceId& aServiceId,
int aNumHandles,
uint16_t aNumHandles,
BluetoothGattResultHandler* aRes) = 0;
virtual void AddIncludedService(int aServerIf,
int aServiceHandle,
int aIncludedServiceHandle,
BluetoothGattResultHandler* aRes) = 0;
virtual void AddIncludedService(
int aServerIf,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothGattResultHandler* aRes) = 0;
virtual void AddCharacteristic(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattCharProp aProperties,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes) = 0;
virtual void AddDescriptor(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattResultHandler* aRes) = 0;
/* Start / Stop / Delete a service */
virtual void StartService(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothTransport aTransport,
BluetoothGattResultHandler* aRes) = 0;
virtual void StopService(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes) = 0;
virtual void DeleteService(int aServerIf,
int aServiceHandle,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothGattResultHandler* aRes) = 0;
/* Send an indication or a notification */
virtual void SendIndication(int aServerIf,
int aAttributeHandle,
int aConnId,
const nsTArray<uint8_t>& aValue,
bool aConfirm, /* true: indication */
/* false: notification */
BluetoothGattResultHandler* aRes) = 0;
virtual void SendIndication(
int aServerIf,
const BluetoothAttributeHandle& aCharacteristicHandle,
int aConnId,
const nsTArray<uint8_t>& aValue,
bool aConfirm, /* true: indication; false: notification */
BluetoothGattResultHandler* aRes) = 0;
/* Send a response for an incoming indication */
virtual void SendResponse(int aConnId,
int aTransId,
BluetoothGattStatus aStatus,
uint16_t aStatus,
const BluetoothGattResponse& aResponse,
BluetoothGattResultHandler* aRes) = 0;

View File

@ -6,6 +6,7 @@
#include "base/basictypes.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "DOMRequest.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
@ -58,6 +59,7 @@ BluetoothReplyRunnable::FireReplySuccess(JS::Handle<JS::Value> aVal)
mPromise->MaybeResolve(aVal);
}
OnSuccessFired();
return NS_OK;
}
@ -80,6 +82,7 @@ BluetoothReplyRunnable::FireErrorString()
mPromise->MaybeReject(rv);
}
OnErrorFired();
return NS_OK;
}
@ -118,6 +121,14 @@ BluetoothReplyRunnable::Run()
return rv;
}
void
BluetoothReplyRunnable::OnSuccessFired()
{}
void
BluetoothReplyRunnable::OnErrorFired()
{}
BluetoothVoidReplyRunnable::BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise)
: BluetoothReplyRunnable(aReq, aPromise)
@ -126,3 +137,181 @@ BluetoothVoidReplyRunnable::BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq,
BluetoothVoidReplyRunnable::~BluetoothVoidReplyRunnable()
{}
BluetoothReplyTaskQueue::SubReplyRunnable::SubReplyRunnable(
nsIDOMDOMRequest* aReq,
Promise* aPromise,
BluetoothReplyTaskQueue* aRootQueue)
: BluetoothReplyRunnable(aReq, aPromise)
, mRootQueue(aRootQueue)
{}
BluetoothReplyTaskQueue::SubReplyRunnable::~SubReplyRunnable()
{}
BluetoothReplyTaskQueue*
BluetoothReplyTaskQueue::SubReplyRunnable::GetRootQueue() const
{
return mRootQueue;
}
void
BluetoothReplyTaskQueue::SubReplyRunnable::OnSuccessFired()
{
mRootQueue->OnSubReplySuccessFired(this);
}
void
BluetoothReplyTaskQueue::SubReplyRunnable::OnErrorFired()
{
mRootQueue->OnSubReplyErrorFired(this);
}
BluetoothReplyTaskQueue::VoidSubReplyRunnable::VoidSubReplyRunnable(
nsIDOMDOMRequest* aReq,
Promise* aPromise,
BluetoothReplyTaskQueue* aRootQueue)
: BluetoothReplyTaskQueue::SubReplyRunnable(aReq, aPromise, aRootQueue)
{}
BluetoothReplyTaskQueue::VoidSubReplyRunnable::~VoidSubReplyRunnable()
{}
bool
BluetoothReplyTaskQueue::VoidSubReplyRunnable::ParseSuccessfulReply(
JS::MutableHandle<JS::Value> aValue)
{
aValue.setUndefined();
return true;
}
BluetoothReplyTaskQueue::SubTask::SubTask(
BluetoothReplyTaskQueue* aRootQueue,
SubReplyRunnable* aReply)
: mRootQueue(aRootQueue)
, mReply(aReply)
{
if (!mReply) {
mReply = new VoidSubReplyRunnable(nullptr, nullptr, mRootQueue);
}
}
BluetoothReplyTaskQueue::SubTask::~SubTask()
{}
BluetoothReplyTaskQueue*
BluetoothReplyTaskQueue::SubTask::GetRootQueue() const
{
return mRootQueue;
}
BluetoothReplyTaskQueue::SubReplyRunnable*
BluetoothReplyTaskQueue::SubTask::GetReply() const
{
return mReply;
}
BluetoothReplyTaskQueue::BluetoothReplyTaskQueue(
BluetoothReplyRunnable* aReply)
: mReply(aReply)
{}
BluetoothReplyTaskQueue::~BluetoothReplyTaskQueue()
{
Clear();
}
void
BluetoothReplyTaskQueue::AppendTask(already_AddRefed<SubTask> aTask)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<SubTask> task(aTask);
if (task) {
mTasks.AppendElement(task.forget());
}
}
NS_IMETHODIMP
BluetoothReplyTaskQueue::Run()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mTasks.IsEmpty()) {
nsRefPtr<SubTask> task = mTasks[0];
mTasks.RemoveElementAt(0);
MOZ_ASSERT(task);
if (!task->Execute()) {
FireErrorReply();
}
}
return NS_OK;
}
void
BluetoothReplyTaskQueue::OnSubReplySuccessFired(SubReplyRunnable* aSubReply)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSubReply);
if (mTasks.IsEmpty()) {
FireSuccessReply();
} else {
if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(this)))) {
FireErrorReply();
}
}
}
void
BluetoothReplyTaskQueue::OnSubReplyErrorFired(SubReplyRunnable* aSubReply)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSubReply);
FireErrorReply();
}
void
BluetoothReplyTaskQueue::FireSuccessReply()
{
MOZ_ASSERT(NS_IsMainThread());
if (mReply) {
DispatchReplySuccess(mReply);
}
OnSuccessFired();
Clear();
}
void
BluetoothReplyTaskQueue::FireErrorReply()
{
MOZ_ASSERT(NS_IsMainThread());
if (mReply) {
DispatchReplyError(mReply, STATUS_FAIL);
}
OnErrorFired();
Clear();
}
void
BluetoothReplyTaskQueue::OnSuccessFired()
{}
void
BluetoothReplyTaskQueue::OnErrorFired()
{}
void
BluetoothReplyTaskQueue::Clear()
{
MOZ_ASSERT(NS_IsMainThread());
mReply = nullptr;
mTasks.Clear();
}

View File

@ -57,6 +57,9 @@ private:
nsresult FireReplySuccess(JS::Handle<JS::Value> aVal);
nsresult FireErrorString();
virtual void OnSuccessFired();
virtual void OnErrorFired();
/**
* Either mDOMRequest or mPromise is not nullptr to reply applications
* success or error string. One special case is internal IPC that require
@ -88,6 +91,107 @@ protected:
}
};
class BluetoothReplyTaskQueue : public nsRunnable
{
public:
NS_DECL_NSIRUNNABLE
class SubReplyRunnable : public BluetoothReplyRunnable
{
public:
SubReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise,
BluetoothReplyTaskQueue* aRootQueue);
~SubReplyRunnable();
BluetoothReplyTaskQueue* GetRootQueue() const;
private:
virtual void OnSuccessFired() override;
virtual void OnErrorFired() override;
nsRefPtr<BluetoothReplyTaskQueue> mRootQueue;
};
friend class BluetoothReplyTaskQueue::SubReplyRunnable;
class VoidSubReplyRunnable : public SubReplyRunnable
{
public:
VoidSubReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise,
BluetoothReplyTaskQueue* aRootQueue);
~VoidSubReplyRunnable();
protected:
virtual bool ParseSuccessfulReply(
JS::MutableHandle<JS::Value> aValue) override;
};
class SubTask
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SubTask)
public:
SubTask(BluetoothReplyTaskQueue* aRootQueue,
SubReplyRunnable* aReply);
BluetoothReplyTaskQueue* GetRootQueue() const;
SubReplyRunnable* GetReply() const;
/*
* Use SubReplyRunnable as the reply runnable to execute the task.
*
* Example:
* <pre>
* <code>
* bool SomeInheritedSubTask::Execute()
* {
* BluetoothService* bs = BluetoothService::Get();
* if (!bs) {
* return false;
* }
* bs->DoSomethingInternal(
* aSomeParameter,
* new SomeInheritedSubReplyRunnable(aSomeDOMRequest,
* aSomePromise,
* GetRootQueue()));
* return true;
* }
* </code>
* </pre>
*/
virtual bool Execute() = 0;
protected:
virtual ~SubTask();
private:
nsRefPtr<BluetoothReplyTaskQueue> mRootQueue;
nsRefPtr<SubReplyRunnable> mReply;
};
BluetoothReplyTaskQueue(BluetoothReplyRunnable* aReply);
void AppendTask(already_AddRefed<SubTask> aTask);
protected:
~BluetoothReplyTaskQueue();
void FireSuccessReply();
void FireErrorReply();
private:
void Clear();
void OnSubReplySuccessFired(SubReplyRunnable* aSubReply);
void OnSubReplyErrorFired(SubReplyRunnable* aSubReply);
virtual void OnSuccessFired();
virtual void OnErrorFired();
nsRefPtr<BluetoothReplyRunnable> mReply;
nsTArray<nsRefPtr<SubTask>> mTasks;
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_BluetoothReplyRunnable_h

View File

@ -508,6 +508,74 @@ public:
UnregisterGattServerInternal(int aServerIf,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable) = 0;
bool
IsEnabled() const
{

View File

@ -8,6 +8,7 @@
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "jsapi.h"
#include "mozilla/dom/BluetoothGattCharacteristicBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "nsContentUtils.h"
@ -43,12 +44,13 @@ UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
}
void
StringToUuid(const char* aString, BluetoothUuid& aUuid)
StringToUuid(const nsAString& aString, BluetoothUuid& aUuid)
{
uint32_t uuid0, uuid4;
uint16_t uuid1, uuid2, uuid3, uuid5;
sscanf(aString, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
sscanf(NS_ConvertUTF16toUTF8(aString).get(),
"%08x-%04hx-%04hx-%04hx-%08x%04hx",
&uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
uuid0 = htonl(uuid0);
@ -66,23 +68,17 @@ StringToUuid(const char* aString, BluetoothUuid& aUuid)
memcpy(&aUuid.mUuid[14], &uuid5, sizeof(uint16_t));
}
void
StringToUuid(const nsAString& aString, BluetoothUuid& aUuid)
{
StringToUuid(NS_ConvertUTF16toUTF8(aString).get(), aUuid);
}
void
nsresult
GenerateUuid(nsAString &aUuidString)
{
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsID uuid;
rv = uuidGenerator->GenerateUUIDInPlace(&uuid);
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
// Build a string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format
char uuidBuffer[NSID_LENGTH];
@ -91,8 +87,106 @@ GenerateUuid(nsAString &aUuidString)
// Remove {} and the null terminator
aUuidString.Assign(Substring(uuidString, 1, NSID_LENGTH - 3));
return NS_OK;
}
void
GattPermissionsToDictionary(BluetoothGattAttrPerm aBits,
GattPermissions& aPermissions)
{
aPermissions.mRead = aBits & GATT_ATTR_PERM_BIT_READ;
aPermissions.mReadEncrypted = aBits & GATT_ATTR_PERM_BIT_READ_ENCRYPTED;
aPermissions.mReadEncryptedMITM =
aBits & GATT_ATTR_PERM_BIT_READ_ENCRYPTED_MITM;
aPermissions.mWrite = aBits & GATT_ATTR_PERM_BIT_WRITE;
aPermissions.mWriteEncrypted = aBits & GATT_ATTR_PERM_BIT_WRITE_ENCRYPTED;
aPermissions.mWriteEncryptedMITM =
aBits & GATT_ATTR_PERM_BIT_WRITE_ENCRYPTED_MITM;
aPermissions.mWriteSigned = aBits & GATT_ATTR_PERM_BIT_WRITE_SIGNED;
aPermissions.mWriteSignedMITM = aBits & GATT_ATTR_PERM_BIT_WRITE_SIGNED_MITM;
}
void
GattPermissionsToBits(const GattPermissions& aPermissions,
BluetoothGattAttrPerm& aBits)
{
aBits = BLUETOOTH_EMPTY_GATT_ATTR_PERM;
if (aPermissions.mRead) {
aBits |= GATT_ATTR_PERM_BIT_READ;
}
if (aPermissions.mReadEncrypted) {
aBits |= GATT_ATTR_PERM_BIT_READ_ENCRYPTED;
}
if (aPermissions.mReadEncryptedMITM) {
aBits |= GATT_ATTR_PERM_BIT_READ_ENCRYPTED_MITM;
}
if (aPermissions.mWrite) {
aBits |= GATT_ATTR_PERM_BIT_WRITE;
}
if (aPermissions.mWriteEncrypted) {
aBits |= GATT_ATTR_PERM_BIT_WRITE_ENCRYPTED;
}
if (aPermissions.mWriteEncryptedMITM) {
aBits |= GATT_ATTR_PERM_BIT_WRITE_ENCRYPTED_MITM;
}
if (aPermissions.mWriteSigned) {
aBits |= GATT_ATTR_PERM_BIT_WRITE_SIGNED;
}
if (aPermissions.mWriteSignedMITM) {
aBits |= GATT_ATTR_PERM_BIT_WRITE_SIGNED_MITM;
}
}
void
GattPropertiesToDictionary(BluetoothGattCharProp aBits,
GattCharacteristicProperties& aProperties)
{
aProperties.mBroadcast = aBits & GATT_CHAR_PROP_BIT_BROADCAST;
aProperties.mRead = aBits & GATT_CHAR_PROP_BIT_READ;
aProperties.mWriteNoResponse = aBits & GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE;
aProperties.mWrite = aBits & GATT_CHAR_PROP_BIT_WRITE;
aProperties.mNotify = aBits & GATT_CHAR_PROP_BIT_NOTIFY;
aProperties.mIndicate = aBits & GATT_CHAR_PROP_BIT_INDICATE;
aProperties.mSignedWrite = aBits & GATT_CHAR_PROP_BIT_SIGNED_WRITE;
aProperties.mExtendedProps = aBits & GATT_CHAR_PROP_BIT_EXTENDED_PROPERTIES;
}
void
GattPropertiesToBits(const GattCharacteristicProperties& aProperties,
BluetoothGattCharProp& aBits)
{
aBits = BLUETOOTH_EMPTY_GATT_CHAR_PROP;
if (aProperties.mBroadcast) {
aBits |= GATT_CHAR_PROP_BIT_BROADCAST;
}
if (aProperties.mRead) {
aBits |= GATT_CHAR_PROP_BIT_READ;
}
if (aProperties.mWriteNoResponse) {
aBits |= GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE;
}
if (aProperties.mWrite) {
aBits |= GATT_CHAR_PROP_BIT_WRITE;
}
if (aProperties.mNotify) {
aBits |= GATT_CHAR_PROP_BIT_NOTIFY;
}
if (aProperties.mIndicate) {
aBits |= GATT_CHAR_PROP_BIT_INDICATE;
}
if (aProperties.mSignedWrite) {
aBits |= GATT_CHAR_PROP_BIT_SIGNED_WRITE;
}
if (aProperties.mExtendedProps) {
aBits |= GATT_CHAR_PROP_BIT_EXTENDED_PROPERTIES;
}
}
void
GeneratePathFromGattId(const BluetoothGattId& aId,
nsAString& aPath)

View File

@ -10,6 +10,13 @@
#include "BluetoothCommon.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class GattPermissions;
class GattCharacteristicProperties;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
@ -36,15 +43,6 @@ UuidToString(const BluetoothUuid& aUuid, nsAString& aString);
* string created by gecko back to BluetoothUuid representation.
*/
void
StringToUuid(const char* aString, BluetoothUuid& aUuid);
/**
* Convert xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string to BluetoothUuid object.
*
* This utility function is used by gecko internal only to convert uuid string
* created by gecko back to BluetoothUuid representation.
*/
void
StringToUuid(const nsAString& aString, BluetoothUuid& aUuid);
/**
@ -52,9 +50,51 @@ StringToUuid(const nsAString& aString, BluetoothUuid& aUuid);
*
* @param aUuidString [out] String to store the generated uuid.
*/
void
nsresult
GenerateUuid(nsAString &aUuidString);
/**
* Convert BluetoothGattAttrPerm bit masks to GattPermissions object.
*
* @param aBits [in] BluetoothGattAttrPerm bit masks.
* @param aPermissions [out] GattPermissions object.
*/
void
GattPermissionsToDictionary(BluetoothGattAttrPerm aBits,
GattPermissions& aPermissions);
/**
* Convert GattPermissions object to BluetoothGattAttrPerm bit masks.
*
* @param aPermissions [in] GattPermissions object.
* @param aBits [out] BluetoothGattAttrPerm bit masks.
*/
void
GattPermissionsToBits(const GattPermissions& aPermissions,
BluetoothGattAttrPerm& aBits);
/**
* Convert BluetoothGattCharProp bit masks to GattCharacteristicProperties
* object.
*
* @param aBits [in] BluetoothGattCharProp bit masks.
* @param aProperties [out] GattCharacteristicProperties object.
*/
void
GattPropertiesToDictionary(BluetoothGattCharProp aBits,
GattCharacteristicProperties& aProperties);
/**
* Convert GattCharacteristicProperties object to BluetoothGattCharProp bit
* masks.
*
* @param aProperties [in] GattCharacteristicProperties object.
* @param aBits [out] BluetoothGattCharProp bit masks.
*/
void
GattPropertiesToBits(const GattCharacteristicProperties& aProperties,
BluetoothGattCharProp& aBits);
//
// Generate bluetooth signal path from GattId
//

View File

@ -113,8 +113,8 @@ BluetoothGatt::Connect(ErrorResult& aRv)
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
if (mAppUuid.IsEmpty()) {
GenerateUuid(mAppUuid);
BT_ENSURE_TRUE_REJECT(!mAppUuid.IsEmpty(),
nsresult rv = GenerateUuid(mAppUuid);
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv) && !mAppUuid.IsEmpty(),
promise,
NS_ERROR_DOM_OPERATION_ERR);
RegisterBluetoothSignalHandler(mAppUuid, this);

View File

@ -0,0 +1,181 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "mozilla/dom/bluetooth/BluetoothGattAttributeEvent.h"
#include "js/GCAPI.h"
#include "jsfriendapi.h"
#include "mozilla/dom/BluetoothGattAttributeEventBinding.h"
#include "mozilla/dom/bluetooth/BluetoothGattCharacteristic.h"
#include "mozilla/dom/bluetooth/BluetoothGattDescriptor.h"
#include "mozilla/dom/EventBinding.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/TypedArray.h"
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothGattAttributeEvent)
NS_IMPL_ADDREF_INHERITED(BluetoothGattAttributeEvent, Event)
NS_IMPL_RELEASE_INHERITED(BluetoothGattAttributeEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothGattAttributeEvent,
Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCharacteristic)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDescriptor)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothGattAttributeEvent,
Event)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mValue)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothGattAttributeEvent,
Event)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCharacteristic)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDescriptor)
tmp->mValue = nullptr;
mozilla::DropJSObjects(this);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothGattAttributeEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
BluetoothGattAttributeEvent::BluetoothGattAttributeEvent(EventTarget* aOwner)
: Event(aOwner, nullptr, nullptr)
{
mozilla::HoldJSObjects(this);
}
BluetoothGattAttributeEvent::~BluetoothGattAttributeEvent()
{
mozilla::DropJSObjects(this);
}
JSObject*
BluetoothGattAttributeEvent::WrapObjectInternal(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return BluetoothGattAttributeEventBinding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<BluetoothGattAttributeEvent>
BluetoothGattAttributeEvent::Constructor(
EventTarget* aOwner,
const nsAString& aType,
const nsAString& aAddress,
int32_t aRequestId,
BluetoothGattCharacteristic* aCharacteristic,
BluetoothGattDescriptor* aDescriptor,
const nsTArray<uint8_t>* aValue,
bool aNeedResponse,
bool aBubbles,
bool aCancelable)
{
nsRefPtr<BluetoothGattAttributeEvent> e =
new BluetoothGattAttributeEvent(aOwner);
bool trusted = e->Init(aOwner);
e->InitEvent(aType, aBubbles, aCancelable);
e->mAddress = aAddress;
e->mRequestId = aRequestId;
e->mCharacteristic = aCharacteristic;
e->mDescriptor = aDescriptor;
e->mNeedResponse = aNeedResponse;
if (aValue) {
e->mRawValue = *aValue;
}
e->SetTrusted(trusted);
return e.forget();
}
already_AddRefed<BluetoothGattAttributeEvent>
BluetoothGattAttributeEvent::Constructor(
const GlobalObject& aGlobal,
const nsAString& aType,
const BluetoothGattAttributeEventInit& aEventInitDict,
ErrorResult& aRv)
{
nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
nsRefPtr<BluetoothGattAttributeEvent> e =
Constructor(owner, aType, aEventInitDict.mAddress,
aEventInitDict.mRequestId, aEventInitDict.mCharacteristic,
aEventInitDict.mDescriptor, nullptr,
aEventInitDict.mNeedResponse, aEventInitDict.mBubbles,
aEventInitDict.mCancelable);
if (!aEventInitDict.mValue.IsNull()) {
const auto& value = aEventInitDict.mValue.Value();
value.ComputeLengthAndData();
e->mValue = ArrayBuffer::Create(aGlobal.Context(),
value.Length(),
value.Data());
if (!e->mValue) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
}
return e.forget();
}
void
BluetoothGattAttributeEvent::GetAddress(nsString& aRetVal) const
{
aRetVal = mAddress;
}
int32_t
BluetoothGattAttributeEvent::RequestId() const
{
return mRequestId;
}
BluetoothGattCharacteristic*
BluetoothGattAttributeEvent::GetCharacteristic() const
{
return mCharacteristic;
}
BluetoothGattDescriptor*
BluetoothGattAttributeEvent::GetDescriptor() const
{
return mDescriptor;
}
void
BluetoothGattAttributeEvent::GetValue(
JSContext* cx, JS::MutableHandle<JSObject*> aValue, ErrorResult& aRv)
{
if (!mValue) {
mValue = ArrayBuffer::Create(
cx, this, mRawValue.Length(), mRawValue.Elements());
if (!mValue) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
mRawValue.Clear();
}
JS::ExposeObjectToActiveJS(mValue);
aValue.set(mValue);
return;
}
bool
BluetoothGattAttributeEvent::NeedResponse() const
{
return mNeedResponse;
}

View File

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#ifndef mozilla_dom_bluetooth_BluetoothGattAttributeEvent_h
#define mozilla_dom_bluetooth_BluetoothGattAttributeEvent_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BluetoothGattAttributeEventBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/dom/Event.h"
struct JSContext;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothGattAttributeEvent final : public Event
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
BluetoothGattAttributeEvent, Event)
protected:
virtual ~BluetoothGattAttributeEvent();
explicit BluetoothGattAttributeEvent(EventTarget* aOwner);
nsString mAddress;
int32_t mRequestId;
nsRefPtr<BluetoothGattCharacteristic> mCharacteristic;
nsRefPtr<BluetoothGattDescriptor> mDescriptor;
JS::Heap<JSObject*> mValue;
bool mNeedResponse;
public:
virtual
JSObject* WrapObjectInternal(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<BluetoothGattAttributeEvent>
Constructor(EventTarget* aOwner,
const nsAString& aType,
const nsAString& aAddress,
int32_t aRequestId,
BluetoothGattCharacteristic* aCharacteristic,
BluetoothGattDescriptor* aDescriptor,
const nsTArray<uint8_t>* aValue,
bool aNeedResponse,
bool aBubbles,
bool aCancelable);
static already_AddRefed<BluetoothGattAttributeEvent>
Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const BluetoothGattAttributeEventInit& aEventInitDict,
ErrorResult& aRv);
void GetAddress(nsString& aRetVal) const;
int32_t RequestId() const;
BluetoothGattCharacteristic* GetCharacteristic() const;
BluetoothGattDescriptor* GetDescriptor() const;
void
GetValue(JSContext* cx,
JS::MutableHandle<JSObject*> aValue,
ErrorResult& aRv);
bool NeedResponse() const;
private:
nsTArray<uint8_t> mRawValue;
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_BluetoothGattAttributeEvent_h

View File

@ -10,7 +10,6 @@
#include "mozilla/dom/BluetoothGattCharacteristicBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothGattCharacteristic.h"
#include "mozilla/dom/bluetooth/BluetoothGattDescriptor.h"
#include "mozilla/dom/bluetooth/BluetoothGattService.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/Promise.h"
@ -55,6 +54,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BluetoothGattCharacteristic)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/*
* "A characteristic definition shall contain a characteristic declaration, a
* Characteristic Value declaration and may contain characteristic descriptor
* declarations."
* ...
* "Each declaration above is contained in a separate Attribute. Two required
* declarations are the characteristic declaration and the Characteristic
* Value declaration."
* -- Bluetooth Core Specification version 4.2, Volume 3, Part G, Section 3.3
*/
const uint16_t BluetoothGattCharacteristic::sHandleCount = 2;
// Constructor of BluetoothGattCharacteristic in ATT client role
BluetoothGattCharacteristic::BluetoothGattCharacteristic(
nsPIDOMWindow* aOwner,
BluetoothGattService* aService,
@ -62,8 +74,11 @@ BluetoothGattCharacteristic::BluetoothGattCharacteristic(
: mOwner(aOwner)
, mService(aService)
, mCharId(aChar.mId)
, mPermissions(BLUETOOTH_EMPTY_GATT_ATTR_PERM)
, mProperties(aChar.mProperties)
, mWriteType(aChar.mWriteType)
, mAttRole(ATT_CLIENT_ROLE)
, mActive(true)
{
MOZ_ASSERT(aOwner);
MOZ_ASSERT(mService);
@ -76,6 +91,42 @@ BluetoothGattCharacteristic::BluetoothGattCharacteristic(
RegisterBluetoothSignalHandler(path, this);
}
// Constructor of BluetoothGattCharacteristic in ATT server role
BluetoothGattCharacteristic::BluetoothGattCharacteristic(
nsPIDOMWindow* aOwner,
BluetoothGattService* aService,
const nsAString& aCharacteristicUuid,
const GattPermissions& aPermissions,
const GattCharacteristicProperties& aProperties,
const ArrayBuffer& aValue)
: mOwner(aOwner)
, mService(aService)
, mUuidStr(aCharacteristicUuid)
, mPermissions(BLUETOOTH_EMPTY_GATT_ATTR_PERM)
, mProperties(BLUETOOTH_EMPTY_GATT_CHAR_PROP)
, mWriteType(GATT_WRITE_TYPE_NORMAL)
, mAttRole(ATT_SERVER_ROLE)
, mActive(false)
{
MOZ_ASSERT(aOwner);
MOZ_ASSERT(aService);
// UUID
memset(&mCharId, 0, sizeof(mCharId));
StringToUuid(aCharacteristicUuid, mCharId.mUuid);
// permissions
GattPermissionsToBits(aPermissions, mPermissions);
// properties
GattPropertiesToBits(aProperties, mProperties);
// value
aValue.ComputeLengthAndData();
mValue.AppendElements(aValue.Data(), aValue.Length());
}
BluetoothGattCharacteristic::~BluetoothGattCharacteristic()
{
nsString path;
@ -95,6 +146,10 @@ BluetoothGattCharacteristic::StartNotifications(ErrorResult& aRv)
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(mAttRole == ATT_CLIENT_ROLE,
promise,
NS_ERROR_UNEXPECTED);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(mService, promise, NS_ERROR_NOT_AVAILABLE);
@ -118,6 +173,10 @@ BluetoothGattCharacteristic::StopNotifications(ErrorResult& aRv)
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(mAttRole == ATT_CLIENT_ROLE,
promise,
NS_ERROR_UNEXPECTED);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(mService, promise, NS_ERROR_NOT_AVAILABLE);
@ -151,6 +210,31 @@ BluetoothGattCharacteristic::HandleCharacteristicValueUpdated(
mValue = aValue.get_ArrayOfuint8_t();
}
void
BluetoothGattCharacteristic::AssignCharacteristicHandle(
const BluetoothAttributeHandle& aCharacteristicHandle)
{
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
MOZ_ASSERT(!mActive);
MOZ_ASSERT(!mCharacteristicHandle.mHandle);
mCharacteristicHandle = aCharacteristicHandle;
mActive = true;
}
void
BluetoothGattCharacteristic::AssignDescriptorHandle(
const BluetoothUuid& aDescriptorUuid,
const BluetoothAttributeHandle& aDescriptorHandle)
{
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
MOZ_ASSERT(mActive);
size_t index = mDescriptors.IndexOf(aDescriptorUuid);
NS_ENSURE_TRUE_VOID(index != mDescriptors.NoIndex);
mDescriptors[index]->AssignDescriptorHandle(aDescriptorHandle);
}
void
BluetoothGattCharacteristic::Notify(const BluetoothSignal& aData)
{
@ -166,6 +250,22 @@ BluetoothGattCharacteristic::Notify(const BluetoothSignal& aData)
}
}
void
BluetoothGattCharacteristic::GetUuid(BluetoothUuid& aUuid) const
{
aUuid = mCharId.mUuid;
}
uint16_t
BluetoothGattCharacteristic::GetHandleCount() const
{
uint16_t count = sHandleCount;
for (size_t i = 0; i < mDescriptors.Length(); ++i) {
count += mDescriptors[i]->GetHandleCount();
}
return count;
}
JSObject*
BluetoothGattCharacteristic::WrapObject(JSContext* aContext,
JS::Handle<JSObject*> aGivenProto)
@ -183,19 +283,17 @@ BluetoothGattCharacteristic::GetValue(JSContext* cx,
}
void
BluetoothGattCharacteristic::GetProperties(
mozilla::dom::GattCharacteristicProperties& aProperties) const
BluetoothGattCharacteristic::GetPermissions(
GattPermissions& aPermissions) const
{
aProperties.mBroadcast = mProperties & GATT_CHAR_PROP_BIT_BROADCAST;
aProperties.mRead = mProperties & GATT_CHAR_PROP_BIT_READ;
aProperties.mWriteNoResponse =
mProperties & GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE;
aProperties.mWrite = mProperties & GATT_CHAR_PROP_BIT_WRITE;
aProperties.mNotify = mProperties & GATT_CHAR_PROP_BIT_NOTIFY;
aProperties.mIndicate = mProperties & GATT_CHAR_PROP_BIT_INDICATE;
aProperties.mSignedWrite = mProperties & GATT_CHAR_PROP_BIT_SIGNED_WRITE;
aProperties.mExtendedProps =
mProperties & GATT_CHAR_PROP_BIT_EXTENDED_PROPERTIES;
GattPermissionsToDictionary(mPermissions, aPermissions);
}
void
BluetoothGattCharacteristic::GetProperties(
GattCharacteristicProperties& aProperties) const
{
GattPropertiesToDictionary(mProperties, aProperties);
}
class ReadValueTask final : public BluetoothReplyRunnable
@ -252,6 +350,11 @@ BluetoothGattCharacteristic::ReadValue(ErrorResult& aRv)
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
if (mAttRole == ATT_SERVER_ROLE) {
promise->MaybeResolve(mValue);
return promise.forget();
}
BT_ENSURE_TRUE_REJECT(mProperties & GATT_CHAR_PROP_BIT_READ,
promise,
NS_ERROR_NOT_AVAILABLE);
@ -279,6 +382,16 @@ BluetoothGattCharacteristic::WriteValue(const ArrayBuffer& aValue,
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
aValue.ComputeLengthAndData();
if (mAttRole == ATT_SERVER_ROLE) {
mValue.Clear();
mValue.AppendElements(aValue.Data(), aValue.Length());
promise->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
}
BT_ENSURE_TRUE_REJECT(mProperties &
(GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE |
GATT_CHAR_PROP_BIT_WRITE |
@ -286,8 +399,6 @@ BluetoothGattCharacteristic::WriteValue(const ArrayBuffer& aValue,
promise,
NS_ERROR_NOT_AVAILABLE);
aValue.ComputeLengthAndData();
nsTArray<uint8_t> value;
value.AppendElements(aValue.Data(), aValue.Length());
@ -301,3 +412,39 @@ BluetoothGattCharacteristic::WriteValue(const ArrayBuffer& aValue,
return promise.forget();
}
already_AddRefed<Promise>
BluetoothGattCharacteristic::AddDescriptor(const nsAString& aDescriptorUuid,
const GattPermissions& aPermissions,
const ArrayBuffer& aValue,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<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 characteristic should not be actively acting with the Bluetooth
* backend. Otherwise, descriptors cannot be added into the characteristic. */
BT_ENSURE_TRUE_REJECT(!mActive, promise, NS_ERROR_UNEXPECTED);
nsRefPtr<BluetoothGattDescriptor> descriptor =
new BluetoothGattDescriptor(GetParentObject(),
this,
aDescriptorUuid,
aPermissions,
aValue);
mDescriptors.AppendElement(descriptor);
promise->MaybeResolve(descriptor);
return promise.forget();
}

View File

@ -32,6 +32,7 @@ class BluetoothGattCharacteristic final : public nsISupports
, public nsWrapperCache
, public BluetoothSignalObserver
{
friend class BluetoothGattServer;
friend class BluetoothGattService;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -63,6 +64,8 @@ public:
void GetValue(JSContext* cx, JS::MutableHandle<JSObject*> aValue) const;
void GetPermissions(GattPermissions& aPermissions) const;
void GetProperties(GattCharacteristicProperties& aProperties) const;
/****************************************************************************
@ -71,12 +74,12 @@ public:
already_AddRefed<Promise> ReadValue(ErrorResult& aRv);
already_AddRefed<Promise> WriteValue(const ArrayBuffer& aValue,
ErrorResult& aRv);
/****************************************************************************
* Methods (Web API Implementation)
***************************************************************************/
already_AddRefed<Promise> StartNotifications(ErrorResult& aRv);
already_AddRefed<Promise> StopNotifications(ErrorResult& aRv);
already_AddRefed<Promise> AddDescriptor(const nsAString& aDescriptorUuid,
const GattPermissions& aPermissions,
const ArrayBuffer& aValue,
ErrorResult& aRv);
/****************************************************************************
* Others
@ -88,18 +91,51 @@ public:
void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
const BluetoothAttributeHandle& GetCharacteristicHandle() const
{
return mCharacteristicHandle;
}
void GetUuid(BluetoothUuid& aUuid) const;
nsPIDOMWindow* GetParentObject() const
{
return mOwner;
}
BluetoothGattAttrPerm GetPermissions() const
{
return mPermissions;
}
BluetoothGattCharProp GetProperties() const
{
return mProperties;
}
uint16_t GetHandleCount() const;
const nsTArray<uint8_t>& GetValue() const
{
return mValue;
}
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// Constructor of BluetoothGattCharacteristic in ATT client role
BluetoothGattCharacteristic(nsPIDOMWindow* aOwner,
BluetoothGattService* aService,
const BluetoothGattCharAttribute& aChar);
// Constructor of BluetoothGattCharacteristic in ATT server role
BluetoothGattCharacteristic(nsPIDOMWindow* aOwner,
BluetoothGattService* aService,
const nsAString& aCharacteristicUuid,
const GattPermissions& aPermissions,
const GattCharacteristicProperties& aProperties,
const ArrayBuffer& aValue);
private:
~BluetoothGattCharacteristic();
@ -119,6 +155,43 @@ private:
*/
void HandleCharacteristicValueUpdated(const BluetoothValue& aValue);
/**
* Assign the handle value for this GATT characteristic. This function would
* be called only after a valid handle value is retrieved from the Bluetooth
* backend.
*
* @param aCharacteristicHandle [in] The handle value of this GATT
* characteristic.
*/
void AssignCharacteristicHandle(
const BluetoothAttributeHandle& aCharacteristicHandle);
/**
* Assign the handle value for one of the descriptor within this GATT
* characteristic. This function would be called only after a valid handle
* value is retrieved from the Bluetooth backend.
*
* @param aDescriptorUuid [in] BluetoothUuid of the target GATT descriptor.
* @param aDescriptorHandle [in] The handle value of the target GATT
* descriptor.
*/
void AssignDescriptorHandle(
const BluetoothUuid& aDescriptorUuid,
const BluetoothAttributeHandle& aDescriptorHandle);
/**
* Examine whether this GATT characteristic can react with the Bluetooth
* backend.
*
* @return true if this characteristic can react with the Bluetooth backend;
* false if this characteristic cannot react with the Bluetooth
* backend.
*/
bool IsActivated() const
{
return mActive;
}
/****************************************************************************
* Variables
***************************************************************************/
@ -151,6 +224,11 @@ private:
*/
nsTArray<uint8_t> mValue;
/**
* Permissions of this GATT characteristic.
*/
BluetoothGattAttrPerm mPermissions;
/**
* Properties of this GATT characteristic.
*/
@ -160,6 +238,37 @@ private:
* Write type of this GATT characteristic.
*/
BluetoothGattWriteType mWriteType;
/**
* ATT role of this GATT characteristic.
*/
const BluetoothAttRole mAttRole;
/**
* Activeness of this GATT characteristic.
*
* True means this service does react with the Bluetooth backend. False means
* this characteristic doesn't react with the Bluetooth backend. The value
* should be true if |mAttRole| equals |ATT_CLIENT_ROLE| because the
* characteristic instance could be created only when the Bluetooth backend
* has found one GATT characteristic. The value would be false at the
* beginning if |mAttRole| equals |ATT_SERVER_ROLE|. Then the value would
* become true later if the corresponding GATT service has been added into
* Bluetooth backend.
*/
bool mActive;
/**
* Handle of this GATT characteristic.
*
* The value is only valid if |mAttRole| equals |ATT_SERVER_ROLE|.
*/
BluetoothAttributeHandle mCharacteristicHandle;
/**
* Total count of handles of this GATT characteristic itself.
*/
static const uint16_t sHandleCount;
};
END_BLUETOOTH_NAMESPACE
@ -185,4 +294,49 @@ public:
}
};
/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison between
* 'nsRefPtr<BluetoothGattCharacteristic>' and 'BluetoothUuid' properly,
* including IndexOf() and Contains();
*/
template <>
class nsDefaultComparator <
nsRefPtr<mozilla::dom::bluetooth::BluetoothGattCharacteristic>,
mozilla::dom::bluetooth::BluetoothUuid> {
public:
bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothGattCharacteristic>& aChar,
const mozilla::dom::bluetooth::BluetoothUuid& aUuid) const
{
mozilla::dom::bluetooth::BluetoothUuid uuid;
aChar->GetUuid(uuid);
return uuid == aUuid;
}
};
/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison between
* 'nsRefPtr<BluetoothGattCharacteristic>' and 'BluetoothAttributeHandle'
* properly, including IndexOf() and Contains();
*/
template <>
class nsDefaultComparator <
nsRefPtr<mozilla::dom::bluetooth::BluetoothGattCharacteristic>,
mozilla::dom::bluetooth::BluetoothAttributeHandle> {
public:
bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothGattCharacteristic>& aChar,
const mozilla::dom::bluetooth::BluetoothAttributeHandle& aCharacteristicHandle)
const
{
return aChar->GetCharacteristicHandle() == aCharacteristicHandle;
}
};
#endif // mozilla_dom_bluetooth_BluetoothGattCharacteristic_h

View File

@ -7,6 +7,7 @@
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "mozilla/dom/BluetoothGattCharacteristicBinding.h"
#include "mozilla/dom/BluetoothGattDescriptorBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothGattCharacteristic.h"
@ -52,6 +53,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BluetoothGattDescriptor)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
const uint16_t BluetoothGattDescriptor::sHandleCount = 1;
// Constructor of BluetoothGattDescriptor in ATT client role
BluetoothGattDescriptor::BluetoothGattDescriptor(
nsPIDOMWindow* aOwner,
BluetoothGattCharacteristic* aCharacteristic,
@ -59,6 +63,9 @@ BluetoothGattDescriptor::BluetoothGattDescriptor(
: mOwner(aOwner)
, mCharacteristic(aCharacteristic)
, mDescriptorId(aDescriptorId)
, mPermissions(BLUETOOTH_EMPTY_GATT_ATTR_PERM)
, mAttRole(ATT_CLIENT_ROLE)
, mActive(true)
{
MOZ_ASSERT(aOwner);
MOZ_ASSERT(aCharacteristic);
@ -71,6 +78,35 @@ BluetoothGattDescriptor::BluetoothGattDescriptor(
RegisterBluetoothSignalHandler(path, this);
}
// Constructor of BluetoothGattDescriptor in ATT server role
BluetoothGattDescriptor::BluetoothGattDescriptor(
nsPIDOMWindow* aOwner,
BluetoothGattCharacteristic* aCharacteristic,
const nsAString& aDescriptorUuid,
const GattPermissions& aPermissions,
const ArrayBuffer& aValue)
: mOwner(aOwner)
, mCharacteristic(aCharacteristic)
, mUuidStr(aDescriptorUuid)
, mPermissions(BLUETOOTH_EMPTY_GATT_ATTR_PERM)
, mAttRole(ATT_SERVER_ROLE)
, mActive(false)
{
MOZ_ASSERT(aOwner);
MOZ_ASSERT(aCharacteristic);
// UUID
memset(&mDescriptorId, 0, sizeof(mDescriptorId));
StringToUuid(aDescriptorUuid, mDescriptorId.mUuid);
// permissions
GattPermissionsToBits(aPermissions, mPermissions);
// value
aValue.ComputeLengthAndData();
mValue.AppendElements(aValue.Data(), aValue.Length());
}
BluetoothGattDescriptor::~BluetoothGattDescriptor()
{
nsString path;
@ -87,6 +123,18 @@ BluetoothGattDescriptor::HandleDescriptorValueUpdated(
mValue = aValue.get_ArrayOfuint8_t();
}
void
BluetoothGattDescriptor::AssignDescriptorHandle(
const BluetoothAttributeHandle& aDescriptorHandle)
{
MOZ_ASSERT(mAttRole == ATT_SERVER_ROLE);
MOZ_ASSERT(!mActive);
MOZ_ASSERT(!mDescriptorHandle.mHandle);
mDescriptorHandle = aDescriptorHandle;
mActive = true;
}
void
BluetoothGattDescriptor::Notify(const BluetoothSignal& aData)
{
@ -102,6 +150,12 @@ BluetoothGattDescriptor::Notify(const BluetoothSignal& aData)
}
}
void
BluetoothGattDescriptor::GetUuid(BluetoothUuid& aUuid) const
{
aUuid = mDescriptorId.mUuid;
}
JSObject*
BluetoothGattDescriptor::WrapObject(JSContext* aContext,
JS::Handle<JSObject*> aGivenProto)
@ -118,6 +172,12 @@ BluetoothGattDescriptor::GetValue(JSContext* cx,
: ArrayBuffer::Create(cx, mValue.Length(), mValue.Elements()));
}
void
BluetoothGattDescriptor::GetPermissions(GattPermissions& aPermissions) const
{
GattPermissionsToDictionary(mPermissions, aPermissions);
}
class ReadValueTask final : public BluetoothReplyRunnable
{
public:
@ -172,6 +232,11 @@ BluetoothGattDescriptor::ReadValue(ErrorResult& aRv)
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
if (mAttRole == ATT_SERVER_ROLE) {
promise->MaybeResolve(mValue);
return promise.forget();
}
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
@ -200,6 +265,14 @@ BluetoothGattDescriptor::WriteValue(
aValue.ComputeLengthAndData();
if (mAttRole == ATT_SERVER_ROLE) {
mValue.Clear();
mValue.AppendElements(aValue.Data(), aValue.Length());
promise->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
}
nsTArray<uint8_t> value;
value.AppendElements(aValue.Data(), aValue.Length());

View File

@ -16,15 +16,24 @@
#include "nsWrapperCache.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
struct GattPermissions;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothGattCharacteristic;
class BluetoothSignal;
class BluetoothValue;
class BluetoothGattDescriptor final : public nsISupports
, public nsWrapperCache
, public BluetoothSignalObserver
{
friend class BluetoothGattServer;
friend class BluetoothGattCharacteristic;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattDescriptor)
@ -44,6 +53,8 @@ public:
void GetValue(JSContext* cx, JS::MutableHandle<JSObject*> aValue) const;
void GetPermissions(GattPermissions& aPermissions) const;
/****************************************************************************
* Methods (Web API Implementation)
***************************************************************************/
@ -56,18 +67,48 @@ public:
***************************************************************************/
void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
const BluetoothAttributeHandle& GetDescriptorHandle() const
{
return mDescriptorHandle;
}
nsPIDOMWindow* GetParentObject() const
{
return mOwner;
}
void GetUuid(BluetoothUuid& aUuid) const;
BluetoothGattAttrPerm GetPermissions() const
{
return mPermissions;
}
uint16_t GetHandleCount() const
{
return sHandleCount;
}
const nsTArray<uint8_t>& GetValue() const
{
return mValue;
}
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// Constructor of BluetoothGattDescriptor in ATT client role
BluetoothGattDescriptor(nsPIDOMWindow* aOwner,
BluetoothGattCharacteristic* aCharacteristic,
const BluetoothGattId& aDescriptorId);
// Constructor of BluetoothGattDescriptor in ATT server role
BluetoothGattDescriptor(nsPIDOMWindow* aOwner,
BluetoothGattCharacteristic* aCharacteristic,
const nsAString& aDescriptorUuid,
const GattPermissions& aPermissions,
const ArrayBuffer& aValue);
private:
~BluetoothGattDescriptor();
@ -78,6 +119,33 @@ private:
*/
void HandleDescriptorValueUpdated(const BluetoothValue& aValue);
/**
* Assign AppUuid of this GATT descriptor.
*
* @param aAppUuid The value of AppUuid.
*/
void AssignAppUuid(const nsAString& aAppUuid);
/**
* Assign the handle value for this GATT descriptor. This function would be
* called only after a valid handle value is retrieved from the Bluetooth
* backend.
*
* @param aDescriptorHandle [in] The handle value of this GATT descriptor.
*/
void AssignDescriptorHandle(const BluetoothAttributeHandle& aDescriptorHandle);
/**
* Examine whether this GATT descriptor can react with the Bluetooth backend.
*
* @return true if this descriptor can react with the Bluetooth backend;
* false if this descriptor cannot react with the Bluetooth backend.
*/
bool IsActivated() const
{
return mActive;
}
/****************************************************************************
* Variables
***************************************************************************/
@ -104,8 +172,87 @@ private:
* Value of this GATT descriptor.
*/
nsTArray<uint8_t> mValue;
/**
* Permissions of this GATT descriptor.
*/
BluetoothGattAttrPerm mPermissions;
/**
* ATT role of this GATT descriptor.
*/
const BluetoothAttRole mAttRole;
/**
* Activeness of this GATT descriptor.
*
* True means this service does react with the Bluetooth backend. False means
* this descriptor doesn't react with the Bluetooth backend. The value should
* be true if |mAttRole| equals |ATT_CLIENT_ROLE| because the descriptor
* instance could be created only when the Bluetooth backend has found one
* GATT descriptor. The value would be false at the beginning if |mAttRole|
* equals |ATT_SERVER_ROLE|. Then the value would become true later if the
* corresponding GATT service has been added into Bluetooth backend.
*/
bool mActive;
/**
* Handle of this GATT descriptor.
*
* The value is only valid if |mAttRole| equals |ATT_SERVER_ROLE|.
*/
BluetoothAttributeHandle mDescriptorHandle;
/**
* Total count of handles of this GATT descriptor itself.
*/
static const uint16_t sHandleCount;
};
END_BLUETOOTH_NAMESPACE
/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison between
* 'nsRefPtr<BluetoothGattDescriptor>' and 'BluetoothUuid' properly,
* including IndexOf() and Contains();
*/
template <>
class nsDefaultComparator <
nsRefPtr<mozilla::dom::bluetooth::BluetoothGattDescriptor>,
mozilla::dom::bluetooth::BluetoothUuid> {
public:
bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothGattDescriptor>& aDesc,
const mozilla::dom::bluetooth::BluetoothUuid& aUuid) const
{
mozilla::dom::bluetooth::BluetoothUuid uuid;
aDesc->GetUuid(uuid);
return uuid == aUuid;
}
};
/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison between
* 'nsRefPtr<BluetoothGattDescriptor>' and 'BluetoothAttributeHandle'
* properly, including IndexOf() and Contains();
*/
template <>
class nsDefaultComparator <
nsRefPtr<mozilla::dom::bluetooth::BluetoothGattDescriptor>,
mozilla::dom::bluetooth::BluetoothAttributeHandle> {
public:
bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothGattDescriptor>& aDesc,
const mozilla::dom::bluetooth::BluetoothAttributeHandle& aHandle) const
{
return aDesc->GetDescriptorHandle() == aHandle;
}
};
#endif // mozilla_dom_bluetooth_BluetoothGattDescriptor_h

View File

@ -10,6 +10,9 @@
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "mozilla/dom/BluetoothStatusChangedEvent.h"
#include "mozilla/dom/bluetooth/BluetoothGattAttributeEvent.h"
#include "mozilla/dom/bluetooth/BluetoothGattCharacteristic.h"
#include "mozilla/dom/bluetooth/BluetoothGattService.h"
#include "mozilla/dom/Promise.h"
using namespace mozilla;
@ -22,6 +25,8 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothGattServer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothGattServer,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mServices)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingService)
/**
* Unregister the bluetooth signal handler after unlinked.
@ -36,6 +41,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothGattServer,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServices)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothGattServer)
@ -48,13 +55,193 @@ BluetoothGattServer::BluetoothGattServer(nsPIDOMWindow* aOwner)
: mOwner(aOwner)
, mServerIf(0)
, mValid(true)
{ }
{
if (NS_SUCCEEDED(GenerateUuid(mAppUuid)) && !mAppUuid.IsEmpty()) {
RegisterBluetoothSignalHandler(mAppUuid, this);
}
if (!mSignalRegistered) {
Invalidate();
}
}
BluetoothGattServer::~BluetoothGattServer()
{
Invalidate();
}
void BluetoothGattServer::HandleServerRegistered(const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::Tuint32_t);
mServerIf = aValue.get_uint32_t();
}
void BluetoothGattServer::HandleServerUnregistered(const BluetoothValue& aValue)
{
mServerIf = 0;
}
void BluetoothGattServer::HandleConnectionStateChanged(
const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(arr.Length() == 2 &&
arr[0].value().type() == BluetoothValue::Tbool &&
arr[1].value().type() == BluetoothValue::TnsString);
BluetoothStatusChangedEventInit init;
init.mStatus = arr[0].value().get_bool();
init.mAddress = arr[1].value().get_nsString();
nsRefPtr<BluetoothStatusChangedEvent> event =
BluetoothStatusChangedEvent::Constructor(
this, NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID), init);
DispatchTrustedEvent(event);
}
void
BluetoothGattServer::HandleServiceHandleUpdated(const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(arr.Length() == 2 &&
arr[0].value().type() == BluetoothValue::TBluetoothGattServiceId &&
arr[1].value().type() == BluetoothValue::TBluetoothAttributeHandle);
BluetoothGattServiceId serviceId =
arr[0].value().get_BluetoothGattServiceId();
BluetoothAttributeHandle serviceHandle =
arr[1].value().get_BluetoothAttributeHandle();
NS_ENSURE_TRUE_VOID(mPendingService);
NS_ENSURE_TRUE_VOID(mPendingService->GetServiceId() == serviceId);
mPendingService->AssignServiceHandle(serviceHandle);
}
void
BluetoothGattServer::HandleCharacteristicHandleUpdated(
const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(arr.Length() == 3 &&
arr[0].value().type() == BluetoothValue::TBluetoothUuid &&
arr[1].value().type() == BluetoothValue::TBluetoothAttributeHandle &&
arr[2].value().type() == BluetoothValue::TBluetoothAttributeHandle);
BluetoothUuid characteristicUuid =
arr[0].value().get_BluetoothUuid();
BluetoothAttributeHandle serviceHandle =
arr[1].value().get_BluetoothAttributeHandle();
BluetoothAttributeHandle characteristicHandle =
arr[2].value().get_BluetoothAttributeHandle();
NS_ENSURE_TRUE_VOID(mPendingService);
NS_ENSURE_TRUE_VOID(mPendingService->GetServiceHandle() == serviceHandle);
mPendingService->AssignCharacteristicHandle(characteristicUuid,
characteristicHandle);
}
void
BluetoothGattServer::HandleDescriptorHandleUpdated(
const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(arr.Length() == 4 &&
arr[0].value().type() == BluetoothValue::TBluetoothUuid &&
arr[1].value().type() == BluetoothValue::TBluetoothAttributeHandle &&
arr[2].value().type() == BluetoothValue::TBluetoothAttributeHandle &&
arr[3].value().type() == BluetoothValue::TBluetoothAttributeHandle);
BluetoothUuid descriptorUuid =
arr[0].value().get_BluetoothUuid();
BluetoothAttributeHandle serviceHandle =
arr[1].value().get_BluetoothAttributeHandle();
BluetoothAttributeHandle characteristicHandle =
arr[2].value().get_BluetoothAttributeHandle();
BluetoothAttributeHandle descriptorHandle =
arr[3].value().get_BluetoothAttributeHandle();
NS_ENSURE_TRUE_VOID(mPendingService);
NS_ENSURE_TRUE_VOID(mPendingService->GetServiceHandle() == serviceHandle);
mPendingService->AssignDescriptorHandle(descriptorUuid,
characteristicHandle,
descriptorHandle);
}
void
BluetoothGattServer::HandleReadWriteRequest(const BluetoothValue& aValue,
const nsAString& aEventName)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(arr.Length() == 5 &&
arr[0].value().type() == BluetoothValue::Tint32_t &&
arr[1].value().type() == BluetoothValue::TBluetoothAttributeHandle &&
arr[2].value().type() == BluetoothValue::TnsString &&
arr[3].value().type() == BluetoothValue::Tbool &&
arr[4].value().type() == BluetoothValue::TArrayOfuint8_t);
int32_t requestId = arr[0].value().get_int32_t();
BluetoothAttributeHandle handle =
arr[1].value().get_BluetoothAttributeHandle();
nsString address = arr[2].value().get_nsString();
bool needResponse = arr[3].value().get_bool();
nsTArray<uint8_t> value;
value = arr[4].value().get_ArrayOfuint8_t();
// Find the target characteristic or descriptor from the given handle
nsRefPtr<BluetoothGattCharacteristic> characteristic = nullptr;
nsRefPtr<BluetoothGattDescriptor> descriptor = nullptr;
for (uint32_t i = 0; i < mServices.Length(); i++) {
for (uint32_t j = 0; j < mServices[i]->mCharacteristics.Length(); j++) {
nsRefPtr<BluetoothGattCharacteristic> currentChar =
mServices[i]->mCharacteristics[j];
if (handle == currentChar->GetCharacteristicHandle()) {
characteristic = currentChar;
break;
}
size_t index = currentChar->mDescriptors.IndexOf(handle);
if (index != currentChar->mDescriptors.NoIndex) {
descriptor = currentChar->mDescriptors[index];
break;
}
}
}
if (!(characteristic || descriptor)) {
BT_WARNING("Wrong handle: no matched characteristic or descriptor");
return;
}
// Save the request information for sending the response later
RequestData data(handle,
characteristic,
descriptor);
mRequestMap.Put(requestId, &data);
nsRefPtr<BluetoothGattAttributeEvent> event =
BluetoothGattAttributeEvent::Constructor(
this, aEventName, address, requestId, characteristic, descriptor,
&value, needResponse, false /* Bubble */, false /* Cancelable*/);
DispatchTrustedEvent(event);
}
void
BluetoothGattServer::Notify(const BluetoothSignal& aData)
{
@ -63,28 +250,21 @@ BluetoothGattServer::Notify(const BluetoothSignal& aData)
BluetoothValue v = aData.value();
if (aData.name().EqualsLiteral("ServerRegistered")) {
MOZ_ASSERT(v.type() == BluetoothValue::Tuint32_t);
mServerIf = v.get_uint32_t();
HandleServerRegistered(v);
} else if (aData.name().EqualsLiteral("ServerUnregistered")) {
mServerIf = 0;
HandleServerUnregistered(v);
} else if (aData.name().EqualsLiteral(GATT_CONNECTION_STATE_CHANGED_ID)) {
MOZ_ASSERT(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
v.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(arr.Length() == 2 &&
arr[0].value().type() == BluetoothValue::Tbool &&
arr[1].value().type() == BluetoothValue::TnsString);
BluetoothStatusChangedEventInit init;
init.mStatus = arr[0].value().get_bool();
init.mAddress = arr[1].value().get_nsString();
nsRefPtr<BluetoothStatusChangedEvent> event =
BluetoothStatusChangedEvent::Constructor(
this, NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID), init);
DispatchTrustedEvent(event);
HandleConnectionStateChanged(v);
} else if (aData.name().EqualsLiteral("ServiceHandleUpdated")) {
HandleServiceHandleUpdated(v);
} else if (aData.name().EqualsLiteral("CharacteristicHandleUpdated")) {
HandleCharacteristicHandleUpdated(v);
} else if (aData.name().EqualsLiteral("DescriptorHandleUpdated")) {
HandleDescriptorHandleUpdated(v);
} else if (aData.name().EqualsLiteral("ReadRequested")) {
HandleReadWriteRequest(v, NS_LITERAL_STRING(ATTRIBUTE_READ_REQUEST));
} else if (aData.name().EqualsLiteral("WriteRequested")) {
HandleReadWriteRequest(v, NS_LITERAL_STRING(ATTRIBUTE_WRITE_REQUEST));
} else {
BT_WARNING("Not handling GATT signal: %s",
NS_ConvertUTF16toUTF8(aData.name()).get());
@ -109,15 +289,22 @@ void
BluetoothGattServer::Invalidate()
{
mValid = false;
mPendingService = nullptr;
mServices.Clear();
mRequestMap.Clear();
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
if (mServerIf > 0) {
bs->UnregisterGattServerInternal(mServerIf, nullptr);
bs->UnregisterGattServerInternal(mServerIf,
new BluetoothVoidReplyRunnable(nullptr,
nullptr));
}
UnregisterBluetoothSignalHandler(mAppUuid, this);
if (!mAppUuid.IsEmpty() && mSignalRegistered) {
UnregisterBluetoothSignalHandler(mAppUuid, this);
}
}
already_AddRefed<Promise>
@ -136,14 +323,6 @@ BluetoothGattServer::Connect(const nsAString& aAddress, ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
if (mAppUuid.IsEmpty()) {
GenerateUuid(mAppUuid);
BT_ENSURE_TRUE_REJECT(!mAppUuid.IsEmpty(),
promise,
NS_ERROR_DOM_OPERATION_ERR);
RegisterBluetoothSignalHandler(mAppUuid, this);
}
bs->GattServerConnectPeripheralInternal(
mAppUuid, aAddress, new BluetoothVoidReplyRunnable(nullptr, promise));
@ -171,3 +350,523 @@ BluetoothGattServer::Disconnect(const nsAString& aAddress, ErrorResult& aRv)
return promise.forget();
}
class BluetoothGattServer::AddIncludedServiceTask final
: public BluetoothReplyTaskQueue::SubTask
{
public:
AddIncludedServiceTask(BluetoothReplyTaskQueue* aRootQueue,
BluetoothGattServer* aServer,
BluetoothGattService* aService,
BluetoothGattService* aIncludedService)
: BluetoothReplyTaskQueue::SubTask(aRootQueue, nullptr)
, mServer(aServer)
, mService(aService)
, mIncludedService(aIncludedService)
{ }
bool Execute() override
{
BluetoothService* bs = BluetoothService::Get();
if (NS_WARN_IF(!bs)) {
return false;
}
bs->GattServerAddIncludedServiceInternal(
mServer->mAppUuid,
mService->GetServiceHandle(),
mIncludedService->GetServiceHandle(),
GetReply());
return true;
}
private:
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
nsRefPtr<BluetoothGattService> mIncludedService;
};
class BluetoothGattServer::AddCharacteristicTask final
: public BluetoothReplyTaskQueue::SubTask
{
public:
AddCharacteristicTask(BluetoothReplyTaskQueue* aRootQueue,
BluetoothGattServer* aServer,
BluetoothGattService* aService,
BluetoothGattCharacteristic* aCharacteristic)
: BluetoothReplyTaskQueue::SubTask(aRootQueue, nullptr)
, mServer(aServer)
, mService(aService)
, mCharacteristic(aCharacteristic)
{ }
bool Execute() override
{
BluetoothService* bs = BluetoothService::Get();
if (NS_WARN_IF(!bs)) {
return false;
}
BluetoothUuid uuid;
mCharacteristic->GetUuid(uuid);
bs->GattServerAddCharacteristicInternal(
mServer->mAppUuid,
mService->GetServiceHandle(),
uuid,
mCharacteristic->GetPermissions(),
mCharacteristic->GetProperties(),
GetReply());
return true;
}
private:
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
nsRefPtr<BluetoothGattCharacteristic> mCharacteristic;
};
class BluetoothGattServer::AddDescriptorTask final
: public BluetoothReplyTaskQueue::SubTask
{
public:
AddDescriptorTask(BluetoothReplyTaskQueue* aRootQueue,
BluetoothGattServer* aServer,
BluetoothGattService* aService,
BluetoothGattCharacteristic* aCharacteristic,
BluetoothGattDescriptor* aDescriptor)
: BluetoothReplyTaskQueue::SubTask(aRootQueue, nullptr)
, mServer(aServer)
, mService(aService)
, mCharacteristic(aCharacteristic)
, mDescriptor(aDescriptor)
{ }
bool Execute() override
{
BluetoothService* bs = BluetoothService::Get();
if (NS_WARN_IF(!bs)) {
return false;
}
BluetoothUuid uuid;
mDescriptor->GetUuid(uuid);
bs->GattServerAddDescriptorInternal(
mServer->mAppUuid,
mService->GetServiceHandle(),
mCharacteristic->GetCharacteristicHandle(),
uuid,
mDescriptor->GetPermissions(),
GetReply());
return true;
}
private:
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
nsRefPtr<BluetoothGattCharacteristic> mCharacteristic;
nsRefPtr<BluetoothGattDescriptor> mDescriptor;
};
class BluetoothGattServer::StartServiceTask final
: public BluetoothReplyTaskQueue::SubTask
{
public:
StartServiceTask(BluetoothReplyTaskQueue* aRootQueue,
BluetoothGattServer* aServer,
BluetoothGattService* aService)
: BluetoothReplyTaskQueue::SubTask(aRootQueue, nullptr)
, mServer(aServer)
, mService(aService)
{ }
bool Execute() override
{
BluetoothService* bs = BluetoothService::Get();
if (NS_WARN_IF(!bs)) {
return false;
}
bs->GattServerStartServiceInternal(
mServer->mAppUuid,
mService->GetServiceHandle(),
GetReply());
return true;
}
private:
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
};
/*
* CancelAddServiceTask is used when failing to completely add a service. No
* matter CancelAddServiceTask executes successfully or not, the promose should
* be rejected because we fail to adding the service eventually.
*/
class BluetoothGattServer::CancelAddServiceTask final
: public BluetoothVoidReplyRunnable
{
public:
CancelAddServiceTask(BluetoothGattServer* aServer,
BluetoothGattService* aService,
Promise* aPromise)
: BluetoothVoidReplyRunnable(nullptr, nullptr)
/* aPromise is not managed by BluetoothVoidReplyRunnable. It would be
* rejected after this task has been executed anyway. */
, mServer(aServer)
, mService(aService)
, mPromise(aPromise)
{
MOZ_ASSERT(mPromise);
}
void ReleaseMembers() override
{
BluetoothVoidReplyRunnable::ReleaseMembers();
mServer = nullptr;
mService = nullptr;
mPromise = nullptr;
}
private:
void OnSuccessFired() override
{
mServer->mPendingService = nullptr;
mPromise->MaybeReject(NS_ERROR_FAILURE);
}
void OnErrorFired() override
{
mServer->mPendingService = nullptr;
mPromise->MaybeReject(NS_ERROR_FAILURE);
}
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
nsRefPtr<Promise> mPromise;
};
class BluetoothGattServer::AddServiceTaskQueue final
: public BluetoothReplyTaskQueue
{
public:
AddServiceTaskQueue(BluetoothGattServer* aServer,
BluetoothGattService* aService,
Promise* aPromise)
: BluetoothReplyTaskQueue(nullptr)
, mServer(aServer)
, mService(aService)
, mPromise(aPromise)
{
/* add included services */
nsTArray<nsRefPtr<BluetoothGattService>> includedServices;
mService->GetIncludedServices(includedServices);
for (size_t i = 0; i < includedServices.Length(); ++i) {
nsRefPtr<SubTask> includedServiceTask =
new AddIncludedServiceTask(this, mServer, mService, includedServices[i]);
AppendTask(includedServiceTask.forget());
}
/* add characteristics */
nsTArray<nsRefPtr<BluetoothGattCharacteristic>> characteristics;
mService->GetCharacteristics(characteristics);
for (size_t i = 0; i < characteristics.Length(); ++i) {
nsRefPtr<SubTask> characteristicTask =
new AddCharacteristicTask(this, mServer, mService, characteristics[i]);
AppendTask(characteristicTask.forget());
/* add descriptors */
nsTArray<nsRefPtr<BluetoothGattDescriptor>> descriptors;
characteristics[i]->GetDescriptors(descriptors);
for (size_t j = 0; j < descriptors.Length(); ++j) {
nsRefPtr<SubTask> descriptorTask =
new AddDescriptorTask(this,
mServer,
mService,
characteristics[i],
descriptors[j]);
AppendTask(descriptorTask.forget());
}
}
/* start service */
nsRefPtr<SubTask> startTask = new StartServiceTask(this, mServer, mService);
AppendTask(startTask.forget());
}
protected:
virtual ~AddServiceTaskQueue()
{ }
private:
void OnSuccessFired() override
{
mServer->mPendingService = nullptr;
mServer->mServices.AppendElement(mService);
mPromise->MaybeResolve(JS::UndefinedHandleValue);
}
void OnErrorFired() override
{
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT_VOID(bs, mPromise, NS_ERROR_NOT_AVAILABLE);
bs->GattServerRemoveServiceInternal(
mServer->mAppUuid,
mService->GetServiceHandle(),
new CancelAddServiceTask(mServer, mService, mPromise));
}
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
nsRefPtr<Promise> mPromise;
};
class BluetoothGattServer::AddServiceTask final
: public BluetoothVoidReplyRunnable
{
public:
AddServiceTask(BluetoothGattServer* aServer,
BluetoothGattService* aService,
Promise* aPromise)
: BluetoothVoidReplyRunnable(nullptr, nullptr)
/* aPromise is not managed by BluetoothVoidReplyRunnable. It would be
* passed to other tasks after this task executes successfully. */
, mServer(aServer)
, mService(aService)
, mPromise(aPromise)
{
MOZ_ASSERT(mServer);
MOZ_ASSERT(mService);
MOZ_ASSERT(mPromise);
}
void ReleaseMembers() override
{
BluetoothReplyRunnable::ReleaseMembers();
mServer = nullptr;
mService = nullptr;
mPromise = nullptr;
}
private:
virtual void OnSuccessFired() override
{
mService->AssignAppUuid(mServer->mAppUuid);
nsRefPtr<nsRunnable> runnable = new AddServiceTaskQueue(mServer,
mService,
mPromise);
nsresult rv = NS_DispatchToMainThread(runnable.forget());
if (NS_WARN_IF(NS_FAILED(rv))) {
mServer->mPendingService = nullptr;
mPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
}
}
virtual void OnErrorFired() override
{
mServer->mPendingService = nullptr;
mPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
}
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
nsRefPtr<Promise> mPromise;
};
already_AddRefed<Promise>
BluetoothGattServer::AddService(BluetoothGattService& aService,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(!aService.IsActivated(),
promise,
NS_ERROR_INVALID_ARG);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
mPendingService = &aService;
bs->GattServerAddServiceInternal(mAppUuid,
mPendingService->GetServiceId(),
mPendingService->GetHandleCount(),
new AddServiceTask(this,
mPendingService,
promise));
return promise.forget();
}
class BluetoothGattServer::RemoveServiceTask final
: public BluetoothReplyRunnable
{
public:
RemoveServiceTask(BluetoothGattServer* aServer,
BluetoothGattService* aService,
Promise* aPromise)
: BluetoothReplyRunnable(nullptr, aPromise)
, mServer(aServer)
, mService(aService)
{
MOZ_ASSERT(mServer);
MOZ_ASSERT(mService);
}
void ReleaseMembers() override
{
BluetoothReplyRunnable::ReleaseMembers();
mServer = nullptr;
mService = nullptr;
}
protected:
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) override
{
aValue.setUndefined();
mServer->mServices.RemoveElement(mService);
return true;
}
private:
nsRefPtr<BluetoothGattServer> mServer;
nsRefPtr<BluetoothGattService> mService;
};
already_AddRefed<Promise>
BluetoothGattServer::RemoveService(BluetoothGattService& aService,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(mServices.Contains(&aService),
promise,
NS_ERROR_INVALID_ARG);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
bs->GattServerRemoveServiceInternal(
mAppUuid, aService.GetServiceHandle(), new RemoveServiceTask(this,
&aService,
promise));
return promise.forget();
}
already_AddRefed<Promise>
BluetoothGattServer::NotifyCharacteristicChanged(
const nsAString& aAddress,
BluetoothGattCharacteristic& aCharacteristic,
bool aConfirm,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothGattService> service = aCharacteristic.Service();
BT_ENSURE_TRUE_REJECT(service, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(mServices.Contains(service),
promise,
NS_ERROR_NOT_AVAILABLE);
bs->GattServerSendIndicationInternal(
mAppUuid, aAddress, aCharacteristic.GetCharacteristicHandle(), aConfirm,
aCharacteristic.GetValue(),
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
already_AddRefed<Promise>
BluetoothGattServer::SendResponse(const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);
RequestData* requestData;
mRequestMap.Get(aRequestId, &requestData);
BT_ENSURE_TRUE_REJECT(requestData, promise, NS_ERROR_UNEXPECTED);
BluetoothGattResponse response;
memset(&response, 0, sizeof(response));
response.mHandle = requestData->mHandle;
if (requestData->mCharacteristic) {
const nsTArray<uint8_t>& value = requestData->mCharacteristic->GetValue();
response.mLength = value.Length();
memcpy(&response.mValue, value.Elements(), response.mLength);
} else if (requestData->mDescriptor) {
const nsTArray<uint8_t>& value = requestData->mDescriptor->GetValue();
response.mLength = value.Length();
memcpy(&response.mValue, value.Elements(), response.mLength);
} else {
MOZ_ASSERT_UNREACHABLE(
"There should be at least one characteristic or descriptor in the "
"request data.");
promise->MaybeReject(NS_ERROR_INVALID_ARG);
return promise.forget();
}
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
bs->GattServerSendResponseInternal(
mAppUuid,
aAddress,
aStatus,
aRequestId,
response,
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}

View File

@ -10,6 +10,9 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BluetoothGattServerBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothGattService.h"
#include "mozilla/dom/Promise.h"
#include "nsClassHashtable.h"
#include "nsCOMPtr.h"
#include "nsPIDOMWindow.h"
@ -34,11 +37,18 @@ public:
/****************************************************************************
* Attribute Getters
***************************************************************************/
void GetServices(
nsTArray<nsRefPtr<BluetoothGattService>>& aServices) const
{
aServices = mServices;
}
/****************************************************************************
* Event Handlers
***************************************************************************/
IMPL_EVENT_HANDLER(connectionstatechanged);
IMPL_EVENT_HANDLER(attributereadreq);
IMPL_EVENT_HANDLER(attributewritereq);
/****************************************************************************
* Methods (Web API Implementation)
@ -47,6 +57,20 @@ public:
const nsAString& aAddress, ErrorResult& aRv);
already_AddRefed<Promise> Disconnect(
const nsAString& aAddress, ErrorResult& aRv);
already_AddRefed<Promise> AddService(BluetoothGattService& aService,
ErrorResult& aRv);
already_AddRefed<Promise> RemoveService(BluetoothGattService& aService,
ErrorResult& aRv);
already_AddRefed<Promise> NotifyCharacteristicChanged(
const nsAString& aAddress,
BluetoothGattCharacteristic& aCharacteristic,
bool aConfirm,
ErrorResult& aRv);
already_AddRefed<Promise> SendResponse(const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
ErrorResult& aRv);
/****************************************************************************
* Others
@ -73,6 +97,48 @@ public:
private:
~BluetoothGattServer();
class AddIncludedServiceTask;
class AddCharacteristicTask;
class AddDescriptorTask;
class StartServiceTask;
class CancelAddServiceTask;
class AddServiceTaskQueue;
class AddServiceTask;
class RemoveServiceTask;
friend class AddIncludedServiceTask;
friend class AddCharacteristicTask;
friend class AddDescriptorTask;
friend class StartServiceTask;
friend class CancelAddServiceTask;
friend class AddServiceTaskQueue;
friend class AddServiceTask;
friend class RemoveServiceTask;
struct RequestData
{
RequestData(const BluetoothAttributeHandle& aHandle,
BluetoothGattCharacteristic* aCharacteristic,
BluetoothGattDescriptor* aDescriptor)
: mHandle(aHandle)
, mCharacteristic(aCharacteristic)
, mDescriptor(aDescriptor)
{ }
BluetoothAttributeHandle mHandle;
nsRefPtr<BluetoothGattCharacteristic> mCharacteristic;
nsRefPtr<BluetoothGattDescriptor> mDescriptor;
};
void HandleServerRegistered(const BluetoothValue& aValue);
void HandleServerUnregistered(const BluetoothValue& aValue);
void HandleConnectionStateChanged(const BluetoothValue& aValue);
void HandleServiceHandleUpdated(const BluetoothValue& aValue);
void HandleCharacteristicHandleUpdated(const BluetoothValue& aValue);
void HandleDescriptorHandleUpdated(const BluetoothValue& aValue);
void HandleReadWriteRequest(const BluetoothValue& aValue,
const nsAString& aString);
/****************************************************************************
* Variables
***************************************************************************/
@ -90,6 +156,21 @@ private:
int mServerIf;
bool mValid;
/**
* Array of services for this server.
*/
nsTArray<nsRefPtr<BluetoothGattService>> mServices;
/**
* The service that is being added to this server.
*/
nsRefPtr<BluetoothGattService> mPendingService;
/**
* Map request information from the request ID.
*/
nsClassHashtable<nsUint32HashKey, RequestData> mRequestMap;
};
END_BLUETOOTH_NAMESPACE

View File

@ -29,12 +29,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BluetoothGattService)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
const uint16_t BluetoothGattService::sHandleCount = 1;
// Constructor of BluetoothGattService in ATT client role
BluetoothGattService::BluetoothGattService(
nsPIDOMWindow* 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());
@ -42,6 +47,20 @@ BluetoothGattService::BluetoothGattService(
UuidToString(mServiceId.mId.mUuid, mUuidStr);
}
// Constructor of BluetoothGattService in ATT server role
BluetoothGattService::BluetoothGattService(
nsPIDOMWindow* 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()
{
}
@ -85,9 +104,156 @@ BluetoothGattService::AssignDescriptors(
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<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
if (!window) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<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;
}
nsRefPtr<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);
nsRefPtr<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;
}
nsRefPtr<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->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
}

View File

@ -25,6 +25,7 @@ class BluetoothGattService final : public nsISupports
, public nsWrapperCache
{
friend class BluetoothGatt;
friend class BluetoothGattServer;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattService)
@ -59,6 +60,23 @@ public:
aCharacteristics = mCharacteristics;
}
/****************************************************************************
* Methods (Web API Implementation)
***************************************************************************/
static already_AddRefed<BluetoothGattService> Constructor(
const GlobalObject& aGlobal,
const BluetoothGattServiceInit& aInit,
ErrorResult& aRv);
already_AddRefed<Promise> AddCharacteristic(
const nsAString& aCharacteristicUuid,
const GattPermissions& aPermissions,
const GattCharacteristicProperties& aProperties,
const ArrayBuffer& aValue,
ErrorResult& aRv);
already_AddRefed<Promise> AddIncludedService(
BluetoothGattService& aIncludedService,
ErrorResult& aRv);
/****************************************************************************
* Others
***************************************************************************/
@ -72,17 +90,28 @@ public:
return mServiceId;
}
const BluetoothAttributeHandle& GetServiceHandle() const
{
return mServiceHandle;
}
nsPIDOMWindow* GetParentObject() const
{
return mOwner;
}
uint16_t GetHandleCount() const;
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// Constructor of BluetoothGattService in ATT client role
BluetoothGattService(nsPIDOMWindow* aOwner,
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId);
// Constructor of BluetoothGattService in ATT server role
BluetoothGattService(nsPIDOMWindow* aOwner,
const BluetoothGattServiceInit& aInit);
private:
~BluetoothGattService();
@ -122,6 +151,61 @@ private:
const BluetoothGattId& aCharacteristicId,
const nsTArray<BluetoothGattId>& aDescriptorIds);
/**
* Assign AppUuid of this GATT service.
*
* @param aAppUuid The value of AppUuid.
*/
void AssignAppUuid(const nsAString& aAppUuid);
/**
* Assign the handle value for this GATT service. This function would be
* called only after a valid handle value is retrieved from the Bluetooth
* backend.
*
* @param aServiceHandle [in] The handle value of this GATT service.
*/
void AssignServiceHandle(const BluetoothAttributeHandle& aServiceHandle);
/**
* Assign the handle value for one of the characteristic within this GATT
* service. This function would be called only after a valid handle value is
* retrieved from the Bluetooth backend.
*
* @param aCharacteristicUuid [in] BluetoothUuid of this GATT characteristic.
* @param aCharacteristicHandle [in] The handle value of this GATT
* characteristic.
*/
void AssignCharacteristicHandle(
const BluetoothUuid& aCharacteristicUuid,
const BluetoothAttributeHandle& aCharacteristicHandle);
/**
* Assign the handle value for one of the descriptor within this GATT
* service. This function would be called only after a valid handle value is
* retrieved from the Bluetooth backend.
*
* @param aDescriptorUuid [in] BluetoothUuid of this GATT descriptor.
* @param aCharacteristicHandle [in] The handle value of this GATT
* characteristic.
* @param aDescriptorHandle [in] The handle value of this GATT descriptor.
*/
void AssignDescriptorHandle(
const BluetoothUuid& aDescriptorUuid,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothAttributeHandle& aDescriptorHandle);
/**
* Examine whether this GATT service can react with the Bluetooth backend.
*
* @return true if this service can react with the Bluetooth backend; false
* if this service cannot react with the Bluetooth backend.
*/
bool IsActivated() const
{
return mActive;
}
/****************************************************************************
* Variables
***************************************************************************/
@ -154,6 +238,36 @@ private:
* Array of discovered characteristics for this service.
*/
nsTArray<nsRefPtr<BluetoothGattCharacteristic>> mCharacteristics;
/**
* ATT role of this GATT service.
*/
const BluetoothAttRole mAttRole;
/**
* Activeness of this GATT service.
*
* True means this service does react with the Bluetooth backend. False means
* this service doesn't react with the Bluetooth backend. The value should be
* true if |mAttRole| equals |ATT_CLIENT_ROLE| because the service instance
* could be created only when the Bluetooth backend has found one GATT
* service. The value would be false at the beginning if |mAttRole| equals
* |ATT_SERVER_ROLE|. Then the value would become true later if this GATT
* service has been added into Bluetooth backend.
*/
bool mActive;
/**
* Handle of this GATT service.
*
* The value is only valid if |mAttRole| equals |ATT_SERVER_ROLE|.
*/
BluetoothAttributeHandle mServiceHandle;
/**
* Total count of handles of this GATT service itself.
*/
static const uint16_t sHandleCount;
};
END_BLUETOOTH_NAMESPACE
@ -179,4 +293,26 @@ public:
}
};
/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison between
* 'nsRefPtr<BluetoothGattService>' and 'BluetoothAttributeHandle' properly,
* including IndexOf() and Contains();
*/
template <>
class nsDefaultComparator <
nsRefPtr<mozilla::dom::bluetooth::BluetoothGattService>,
mozilla::dom::bluetooth::BluetoothAttributeHandle> {
public:
bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothGattService>& aService,
const mozilla::dom::bluetooth::BluetoothAttributeHandle& aServiceHandle)
const
{
return aService->GetServiceHandle() == aServiceHandle;
}
};
#endif // mozilla_dom_bluetooth_BluetoothGattService_h

View File

@ -44,6 +44,14 @@ struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattWriteType>
mozilla::dom::bluetooth::GATT_WRITE_TYPE_END_GUARD>
{ };
template <>
struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattAuthReq>
: public ContiguousEnumSerializer<
mozilla::dom::bluetooth::BluetoothGattAuthReq,
mozilla::dom::bluetooth::GATT_AUTH_REQ_NONE,
mozilla::dom::bluetooth::GATT_AUTH_REQ_END_GUARD>
{ };
template <>
struct ParamTraits<mozilla::dom::bluetooth::BluetoothUuid>
{
@ -136,6 +144,60 @@ struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattCharAttribute>
}
};
template <>
struct ParamTraits<mozilla::dom::bluetooth::BluetoothAttributeHandle>
{
typedef mozilla::dom::bluetooth::BluetoothAttributeHandle paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHandle);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mHandle))) {
return false;
}
return true;
}
};
template <>
struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattResponse>
{
typedef mozilla::dom::bluetooth::BluetoothGattResponse paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHandle);
WriteParam(aMsg, aParam.mOffset);
WriteParam(aMsg, aParam.mLength);
WriteParam(aMsg, aParam.mAuthReq);
for (uint16_t i = 0; i < aParam.mLength; i++) {
WriteParam(aMsg, aParam.mValue[i]);
}
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mHandle)) ||
!ReadParam(aMsg, aIter, &(aResult->mOffset)) ||
!ReadParam(aMsg, aIter, &(aResult->mLength)) ||
!ReadParam(aMsg, aIter, &(aResult->mAuthReq))) {
return false;
}
for (uint16_t i = 0; i < aResult->mLength; i++) {
if (!ReadParam(aMsg, aIter, &(aResult->mValue[i]))) {
return false;
}
}
return true;
}
};
} // namespace IPC
#endif // mozilla_dom_bluetooth_ipc_BluetoothMessageUtils_h

View File

@ -300,6 +300,27 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
aRequest.get_GattServerDisconnectPeripheralRequest());
case Request::TUnregisterGattServerRequest:
return actor->DoRequest(aRequest.get_UnregisterGattServerRequest());
case Request::TGattServerAddServiceRequest:
return actor->DoRequest(aRequest.get_GattServerAddServiceRequest());
case Request::TGattServerAddIncludedServiceRequest:
return actor->DoRequest(
aRequest.get_GattServerAddIncludedServiceRequest());
case Request::TGattServerAddCharacteristicRequest:
return actor->DoRequest(
aRequest.get_GattServerAddCharacteristicRequest());
case Request::TGattServerAddDescriptorRequest:
return actor->DoRequest(aRequest.get_GattServerAddDescriptorRequest());
case Request::TGattServerRemoveServiceRequest:
return actor->DoRequest(aRequest.get_GattServerRemoveServiceRequest());
case Request::TGattServerStartServiceRequest:
return actor->DoRequest(aRequest.get_GattServerStartServiceRequest());
case Request::TGattServerStopServiceRequest:
return actor->DoRequest(aRequest.get_GattServerStopServiceRequest());
case Request::TGattServerSendResponseRequest:
return actor->DoRequest(aRequest.get_GattServerSendResponseRequest());
case Request::TGattServerSendIndicationRequest:
return actor->DoRequest(
aRequest.get_GattServerSendIndicationRequest());
default:
MOZ_CRASH("Unknown type!");
}
@ -1023,3 +1044,158 @@ BluetoothRequestParent::DoRequest(const UnregisterGattServerRequest& aRequest)
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerAddServiceRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerAddServiceRequest);
mService->GattServerAddServiceInternal(aRequest.appUuid(),
aRequest.serviceId(),
aRequest.handleCount(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerAddIncludedServiceRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerAddIncludedServiceRequest);
mService->GattServerAddIncludedServiceInternal(
aRequest.appUuid(),
aRequest.serviceHandle(),
aRequest.includedServiceHandle(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerAddCharacteristicRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerAddCharacteristicRequest);
mService->GattServerAddCharacteristicInternal(
aRequest.appUuid(),
aRequest.serviceHandle(),
aRequest.characteristicUuid(),
aRequest.permissions(),
aRequest.properties(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerAddDescriptorRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerAddDescriptorRequest);
mService->GattServerAddDescriptorInternal(
aRequest.appUuid(),
aRequest.serviceHandle(),
aRequest.characteristicHandle(),
aRequest.descriptorUuid(),
aRequest.permissions(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerRemoveServiceRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerRemoveServiceRequest);
mService->GattServerRemoveServiceInternal(
aRequest.appUuid(),
aRequest.serviceHandle(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerStartServiceRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerStartServiceRequest);
mService->GattServerStartServiceInternal(
aRequest.appUuid(),
aRequest.serviceHandle(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerStopServiceRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerStopServiceRequest);
mService->GattServerStopServiceInternal(
aRequest.appUuid(),
aRequest.serviceHandle(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerSendIndicationRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TGattServerSendIndicationRequest);
mService->GattServerSendIndicationInternal(
aRequest.appUuid(),
aRequest.address(),
aRequest.characteristicHandle(),
aRequest.confirm(),
aRequest.value(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattServerSendResponseRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType ==
Request::TGattServerSendResponseRequest);
mService->GattServerSendResponseInternal(
aRequest.appUuid(),
aRequest.address(),
aRequest.status(),
aRequest.requestId(),
aRequest.response(),
mReplyRunnable.get());
return true;
}

View File

@ -279,6 +279,33 @@ protected:
bool
DoRequest(const UnregisterGattServerRequest& aRequest);
bool
DoRequest(const GattServerAddServiceRequest& aRequest);
bool
DoRequest(const GattServerAddIncludedServiceRequest& aRequest);
bool
DoRequest(const GattServerAddCharacteristicRequest& aRequest);
bool
DoRequest(const GattServerAddDescriptorRequest& aRequest);
bool
DoRequest(const GattServerRemoveServiceRequest& aRequest);
bool
DoRequest(const GattServerStartServiceRequest& aRequest);
bool
DoRequest(const GattServerStopServiceRequest& aRequest);
bool
DoRequest(const GattServerSendResponseRequest& aRequest);
bool
DoRequest(const GattServerSendIndicationRequest& aRequest);
};
END_BLUETOOTH_NAMESPACE

View File

@ -627,6 +627,125 @@ BluetoothServiceChildProcess::UnregisterGattServerInternal(
SendRequest(aRunnable, UnregisterGattServerRequest(aServerIf));
}
void
BluetoothServiceChildProcess::GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerAddServiceRequest(nsString(aAppUuid), aServiceId, aHandleCount));
}
void
BluetoothServiceChildProcess::GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerAddIncludedServiceRequest(nsString(aAppUuid),
aServiceHandle,
aIncludedServiceHandle));
}
void
BluetoothServiceChildProcess::GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerAddCharacteristicRequest(nsString(aAppUuid),
aServiceHandle,
aCharacteristicUuid,
aPermissions,
aProperties));
}
void
BluetoothServiceChildProcess::GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerAddDescriptorRequest(nsString(aAppUuid),
aServiceHandle,
aCharacteristicHandle,
aDescriptorUuid,
aPermissions));
}
void
BluetoothServiceChildProcess::GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerRemoveServiceRequest(nsString(aAppUuid), aServiceHandle));
}
void
BluetoothServiceChildProcess::GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerStartServiceRequest(nsString(aAppUuid), aServiceHandle));
}
void
BluetoothServiceChildProcess::GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerStopServiceRequest(nsString(aAppUuid), aServiceHandle));
}
void
BluetoothServiceChildProcess::GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerSendResponseRequest(
nsString(aAppUuid), nsString(aAddress), aStatus, aRequestId, aRsp));
}
void
BluetoothServiceChildProcess::GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattServerSendIndicationRequest(nsString(aAppUuid),
nsString(aAddress),
aCharacteristicHandle,
aConfirm,
aValue));
}
nsresult
BluetoothServiceChildProcess::HandleStartup()
{

View File

@ -287,7 +287,7 @@ public:
const BluetoothGattServiceId& aServiceId,
const BluetoothGattId& aCharacteristicId,
const BluetoothGattId& aDescriptorId,
BluetoothReplyRunnable* aRunnable);
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattClientWriteDescriptorValueInternal(
@ -296,24 +296,92 @@ public:
const BluetoothGattId& aCharacteristicId,
const BluetoothGattId& aDescriptorId,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable);
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerConnectPeripheralInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
BluetoothReplyRunnable* aRunnable);
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerDisconnectPeripheralInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
BluetoothReplyRunnable* aRunnable);
BluetoothReplyRunnable* aRunnable) override;
virtual void
UnregisterGattServerInternal(int aServerIf,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddServiceInternal(
const nsAString& aAppUuid,
const BluetoothGattServiceId& aServiceId,
uint16_t aHandleCount,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddIncludedServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aIncludedServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddCharacteristicInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothUuid& aCharacteristicUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothGattCharProp aProperties,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerAddDescriptorInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
const BluetoothAttributeHandle& aCharacteristicHandle,
const BluetoothUuid& aDescriptorUuid,
BluetoothGattAttrPerm aPermissions,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerRemoveServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerStartServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerStopServiceInternal(
const nsAString& aAppUuid,
const BluetoothAttributeHandle& aServiceHandle,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerSendResponseInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
uint16_t aStatus,
int32_t aRequestId,
const BluetoothGattResponse& aRsp,
BluetoothReplyRunnable* aRunnable) override;
virtual void
GattServerSendIndicationInternal(
const nsAString& aAppUuid,
const nsAString& aAddress,
const BluetoothAttributeHandle& aCharacteristicHandle,
bool aConfirm,
const nsTArray<uint8_t>& aValue,
BluetoothReplyRunnable* aRunnable) override;
protected:
BluetoothServiceChildProcess();
virtual ~BluetoothServiceChildProcess();

View File

@ -4,10 +4,18 @@
* 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/. */
using mozilla::dom::bluetooth::BluetoothAttributeHandle
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattAttrPerm
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattCharAttribute
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattCharProp
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattId
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattResponse
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattServiceId
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattWriteType
@ -16,6 +24,8 @@ using mozilla::dom::bluetooth::BluetoothSspVariant
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothStatus
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothUuid
from "mozilla/dom/bluetooth/BluetoothCommon.h";
namespace mozilla {
namespace dom {
@ -42,6 +52,8 @@ union BluetoothValue
BluetoothGattServiceId;
BluetoothGattServiceId[];
BluetoothGattCharAttribute[];
BluetoothAttributeHandle;
BluetoothUuid;
};
/**

View File

@ -309,6 +309,74 @@ struct UnregisterGattServerRequest
int serverIf;
};
struct GattServerAddServiceRequest
{
nsString appUuid;
BluetoothGattServiceId serviceId;
uint16_t handleCount;
};
struct GattServerAddIncludedServiceRequest
{
nsString appUuid;
BluetoothAttributeHandle serviceHandle;
BluetoothAttributeHandle includedServiceHandle;
};
struct GattServerAddCharacteristicRequest
{
nsString appUuid;
BluetoothAttributeHandle serviceHandle;
BluetoothUuid characteristicUuid;
BluetoothGattAttrPerm permissions;
BluetoothGattCharProp properties;
};
struct GattServerAddDescriptorRequest
{
nsString appUuid;
BluetoothAttributeHandle serviceHandle;
BluetoothAttributeHandle characteristicHandle;
BluetoothUuid descriptorUuid;
BluetoothGattAttrPerm permissions;
};
struct GattServerRemoveServiceRequest
{
nsString appUuid;
BluetoothAttributeHandle serviceHandle;
};
struct GattServerStartServiceRequest
{
nsString appUuid;
BluetoothAttributeHandle serviceHandle;
};
struct GattServerStopServiceRequest
{
nsString appUuid;
BluetoothAttributeHandle serviceHandle;
};
struct GattServerSendResponseRequest
{
nsString appUuid;
nsString address;
uint16_t status;
int32_t requestId;
BluetoothGattResponse response;
};
struct GattServerSendIndicationRequest
{
nsString appUuid;
nsString address;
BluetoothAttributeHandle characteristicHandle;
bool confirm;
uint8_t[] value;
};
union Request
{
GetAdaptersRequest;
@ -362,6 +430,15 @@ union Request
GattServerConnectPeripheralRequest;
GattServerDisconnectPeripheralRequest;
UnregisterGattServerRequest;
GattServerAddServiceRequest;
GattServerAddIncludedServiceRequest;
GattServerAddCharacteristicRequest;
GattServerAddDescriptorRequest;
GattServerRemoveServiceRequest;
GattServerStartServiceRequest;
GattServerStopServiceRequest;
GattServerSendResponseRequest;
GattServerSendIndicationRequest;
};
protocol PBluetooth

View File

@ -29,6 +29,7 @@ if CONFIG['MOZ_B2G_BT']:
'common/webapi/BluetoothDevice.cpp',
'common/webapi/BluetoothDiscoveryHandle.cpp',
'common/webapi/BluetoothGatt.cpp',
'common/webapi/BluetoothGattAttributeEvent.cpp',
'common/webapi/BluetoothGattCharacteristic.cpp',
'common/webapi/BluetoothGattDescriptor.cpp',
'common/webapi/BluetoothGattServer.cpp',
@ -141,6 +142,7 @@ EXPORTS.mozilla.dom.bluetooth += [
'common/webapi/BluetoothDevice.h',
'common/webapi/BluetoothDiscoveryHandle.h',
'common/webapi/BluetoothGatt.h',
'common/webapi/BluetoothGattAttributeEvent.h',
'common/webapi/BluetoothGattCharacteristic.h',
'common/webapi/BluetoothGattDescriptor.h',
'common/webapi/BluetoothGattServer.h',

View File

@ -1261,7 +1261,7 @@ BrowserElementChild.prototype = {
},
_buildMenuObj: function(menu, idPrefix, copyableElements) {
var menuObj = {type: 'menu', items: []};
var menuObj = {type: 'menu', customized: false, items: []};
// Customized context menu
if (menu) {
this._maybeCopyAttribute(menu, menuObj, 'label');
@ -1278,6 +1278,10 @@ BrowserElementChild.prototype = {
menuObj.items.push(menuitem);
}
}
if (menuObj.items.length > 0) {
menuObj.customized = true;
}
}
// Note: Display "Copy Link" first in order to make sure "Copy Image" is
// put together with other image options if elem is an image link.

View File

@ -24,7 +24,12 @@ function checkEmptyContextMenu() {
function checkInnerContextMenu() {
sendContextMenuTo('#inner-link', function onContextMenu(detail) {
is(detail.systemTargets.length, 1, 'Includes anchor data');
is(detail.contextmenu.items.length, 3, 'Inner clicks trigger correct menu');
is(detail.contextmenu.items.length, 3, 'Inner clicks trigger correct customized menu');
is(detail.contextmenu.items[0].label, 'foo', 'Customized menu has a "foo" menu item');
is(detail.contextmenu.items[1].label, 'bar', 'Customized menu has a "bar" menu item');
is(detail.contextmenu.items[2].id, 'copy-link', '#inner-link has a copy-link menu item');
is(detail.contextmenu.customized, true, 'Make sure contextmenu has customized items');
var target = detail.systemTargets[0];
is(target.nodeName, 'A', 'Reports correct nodeName');
is(target.data.uri, 'foo.html', 'Reports correct uri');
@ -47,9 +52,19 @@ function checkNestedContextMenu() {
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === 'menu';
});
is(detail.systemTargets.length, 2, 'Includes anchor and img data');
is(detail.systemTargets.length, 2, 'Includes two systemTargets');
is(detail.systemTargets[0].nodeName, 'IMG', 'Includes "IMG" node');
is(detail.systemTargets[0].data.uri, 'example.png', 'Img data has the correct uri');
is(detail.systemTargets[1].nodeName, 'A', 'Includes "A" node');
is(detail.systemTargets[1].data.uri, 'bar.html', 'Anchor has the correct uri');
ok(innerMenu.length > 0, 'Menu contains a nested menu');
is(detail.contextmenu.items.length, 4, 'We have correct # of menu items')
is(detail.contextmenu.customized, true, 'Make sure contextmenu has customized items');
is(detail.contextmenu.items[0].label, 'outer', 'Customized menu has an "outer" menu item');
is(detail.contextmenu.items[1].label, 'submenu', 'Customized menu has an "submenu" menu item');
is(detail.contextmenu.items[2].id, 'copy-link', 'Has a copy-link menu item');
is(detail.contextmenu.items[3].id, 'copy-image', 'Has a copy-image menu item');
checkPreviousContextMenuHandler();
});
}
@ -131,6 +146,9 @@ function checkImageContextMenu() {
var target = detail.systemTargets[0];
is(target.nodeName, 'IMG', 'Reports correct nodeName');
is(target.data.uri, 'example.png', 'Reports correct uri');
is(detail.contextmenu.items.length, 1, 'Reports correct # of menu items');
is(detail.contextmenu.items[0].id, 'copy-image', 'IMG has a copy-image menu item');
is(detail.contextmenu.customized, false, 'Make sure we do not have customized items');
checkVideoContextMenu();
}, /* ignorePreventDefault */ true);
@ -265,7 +283,7 @@ function createIframe(callback) {
'</menu>' +
'<menu type="context" id="menu2" label="secondmenu">' +
'<menuitem label="outer" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'<menu>' +
'<menu label="submenu">' +
'<menuitem label="inner 1"></menuitem>' +
'<menuitem label="inner 2" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'</menu>' +

View File

@ -87,6 +87,13 @@ public:
uint32_t aFileType,
uint32_t aFileAttributes);
static already_AddRefed<DeviceStorageFile>
CreateUnique(const nsAString& aStorageType,
const nsAString& aStorageName,
nsAString& aFileName,
uint32_t aFileType,
uint32_t aFileAttributes);
NS_DECL_THREADSAFE_ISUPPORTS
bool IsAvailable();

View File

@ -693,8 +693,20 @@ DeviceStorageFile::CreateUnique(nsAString& aFileName,
if (storageName.IsEmpty()) {
nsDOMDeviceStorage::GetDefaultStorageName(storageType, storageName);
}
return CreateUnique(storageType, storageName, storagePath,
aFileType, aFileAttributes);
}
//static
already_AddRefed<DeviceStorageFile>
DeviceStorageFile::CreateUnique(const nsAString& aStorageType,
const nsAString& aStorageName,
nsAString& aFileName,
uint32_t aFileType,
uint32_t aFileAttributes)
{
nsRefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(storageType, storageName, storagePath);
new DeviceStorageFile(aStorageType, aStorageName, aFileName);
if (!dsf->mFile) {
return nullptr;
}
@ -1499,6 +1511,7 @@ DeviceStorageRequest::DeviceStorageRequest()
: mId(DeviceStorageRequestManager::INVALID_ID)
, mAccess(DEVICE_STORAGE_ACCESS_UNDEFINED)
, mSendToParent(true)
, mUseMainThread(false)
, mUseStreamTransport(false)
, mCheckFile(false)
, mCheckBlob(false)
@ -1578,11 +1591,30 @@ DeviceStorageRequest::Cancel()
nsresult
DeviceStorageRequest::Allow()
{
if (mUseMainThread && !NS_IsMainThread()) {
nsRefPtr<DeviceStorageRequest> self = this;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
{
self->Allow();
});
return NS_DispatchToMainThread(r);
}
nsresult rv = AllowInternal();
if (NS_WARN_IF(NS_FAILED(rv))) {
return Reject(rv == NS_ERROR_ILLEGAL_VALUE
? POST_ERROR_EVENT_ILLEGAL_TYPE
: POST_ERROR_EVENT_UNKNOWN);
const char *reason;
switch (rv) {
case NS_ERROR_ILLEGAL_VALUE:
reason = POST_ERROR_EVENT_ILLEGAL_TYPE;
break;
case NS_ERROR_DOM_SECURITY_ERR:
reason = POST_ERROR_EVENT_PERMISSION_DENIED;
break;
default:
reason = POST_ERROR_EVENT_UNKNOWN;
break;
}
return Reject(reason);
}
return rv;
}
@ -1607,9 +1639,10 @@ DeviceStorageRequest::GetManager() const
return mManager;
}
void
nsresult
DeviceStorageRequest::Prepare()
{
return NS_OK;
}
nsresult
@ -1623,7 +1656,11 @@ nsresult
DeviceStorageRequest::AllowInternal()
{
MOZ_ASSERT(mManager->IsOwningThread() || NS_IsMainThread());
Prepare();
nsresult rv = Prepare();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
@ -1869,6 +1906,8 @@ class DeviceStorageCreateRequest final
: public DeviceStorageRequest
{
public:
using DeviceStorageRequest::Initialize;
DeviceStorageCreateRequest()
{
mAccess = DEVICE_STORAGE_ACCESS_CREATE;
@ -1903,7 +1942,62 @@ public:
return Resolve(fullPath);
}
void Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
uint32_t aRequest) override
{
DeviceStorageRequest::Initialize(aManager, aFile, aRequest);
mUseMainThread = aFile->mPath.IsEmpty();
}
protected:
nsresult Prepare() override
{
if (!mFile->mPath.IsEmpty()) {
// Checks have already been performed when request was created
return NS_OK;
}
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
if (!mimeSvc) {
return NS_ERROR_FAILURE;
}
// if mimeType or extension are null, the request will be rejected
// in DeviceStorageRequest::AllowInternal when the type checker
// verifies the file path
nsString mimeType;
mBlob->GetType(mimeType);
nsCString extension;
mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
EmptyCString(), extension);
char buffer[32];
NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
nsAutoString path;
path.AssignLiteral(buffer);
path.Append('.');
path.AppendASCII(extension.get());
nsRefPtr<DeviceStorageFile> file
= DeviceStorageFile::CreateUnique(mFile->mStorageType,
mFile->mStorageName, path,
nsIFile::NORMAL_FILE_TYPE, 00600);
if (!file) {
return NS_ERROR_FAILURE;
}
if (!file->IsSafePath()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
mFile = file.forget();
return NS_OK;
}
nsresult CreateSendParams(DeviceStorageParams& aParams) override
{
BlobChild* actor
@ -1986,6 +2080,7 @@ public:
DeviceStorageOpenRequest()
{
mUseMainThread = true;
mUseStreamTransport = true;
mCheckFile = true;
DS_LOG_INFO("");
@ -2019,10 +2114,11 @@ public:
}
protected:
void Prepare() override
nsresult Prepare() override
{
MOZ_ASSERT(NS_IsMainThread());
mFile->CalculateMimeType();
return NS_OK;
}
nsresult CreateSendParams(DeviceStorageParams& aParams) override
@ -2926,45 +3022,18 @@ nsDOMDeviceStorage::IsAvailable()
already_AddRefed<DOMRequest>
nsDOMDeviceStorage::Add(Blob* aBlob, ErrorResult& aRv)
{
if (!aBlob) {
return nullptr;
}
nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
if (!mimeSvc) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
// if mimeType isn't set, we will not get a correct
// extension, and AddNamed() will fail. This will post an
// onerror to the requestee.
nsString mimeType;
aBlob->GetType(mimeType);
nsCString extension;
mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
EmptyCString(), extension);
// if extension is null here, we will ignore it for now.
// AddNamed() will check the file path and fail. This
// will post an onerror to the requestee.
// possible race here w/ unique filename
char buffer[32];
NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
nsAutoCString path;
path.Assign(nsDependentCString(buffer));
path.Append('.');
path.Append(extension);
return AddNamed(aBlob, NS_ConvertASCIItoUTF16(path), aRv);
nsString path;
return AddOrAppendNamed(aBlob, path, true, aRv);
}
already_AddRefed<DOMRequest>
nsDOMDeviceStorage::AddNamed(Blob* aBlob, const nsAString& aPath,
ErrorResult& aRv)
{
if (aPath.IsEmpty()) {
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
return nullptr;
}
return AddOrAppendNamed(aBlob, aPath, true, aRv);
}
@ -2972,6 +3041,10 @@ already_AddRefed<DOMRequest>
nsDOMDeviceStorage::AppendNamed(Blob* aBlob, const nsAString& aPath,
ErrorResult& aRv)
{
if (aPath.IsEmpty()) {
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
return nullptr;
}
return AddOrAppendNamed(aBlob, aPath, false, aRv);
}
@ -3017,19 +3090,13 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
bool aCreate, ErrorResult& aRv)
{
MOZ_ASSERT(IsOwningThread());
MOZ_ASSERT(aCreate || !aPath.IsEmpty());
// if the blob is null here, bail
if (!aBlob) {
return nullptr;
}
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
if (!typeChecker) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsIRunnable> r;
if (IsFullPath(aPath)) {
@ -3048,25 +3115,25 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
return nullptr;
}
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
mStorageName,
aPath);
if (!dsf->IsSafePath()) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
} else if (!typeChecker->Check(mStorageType, dsf->mFile) ||
!typeChecker->Check(mStorageType, aBlob->Impl())) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_ILLEGAL_TYPE);
nsRefPtr<DeviceStorageFile> dsf;
if (aPath.IsEmpty()) {
dsf = new DeviceStorageFile(mStorageType, mStorageName);
} else {
nsRefPtr<DeviceStorageRequest> request;
if (aCreate) {
request = new DeviceStorageCreateRequest();
} else {
request = new DeviceStorageAppendRequest();
dsf = new DeviceStorageFile(mStorageType, mStorageName, aPath);
if (!dsf->IsSafePath()) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
return domRequest.forget();
}
request->Initialize(mManager, dsf, id, aBlob->Impl());
aRv = CheckPermission(request);
}
nsRefPtr<DeviceStorageRequest> request;
if (aCreate) {
request = new DeviceStorageCreateRequest();
} else {
request = new DeviceStorageAppendRequest();
}
request->Initialize(mManager, dsf, id, aBlob->Impl());
aRv = CheckPermission(request);
return domRequest.forget();
}

View File

@ -378,7 +378,7 @@ protected:
}
virtual ~DeviceStorageRequest();
virtual void Prepare();
virtual nsresult Prepare();
virtual nsresult CreateSendParams(mozilla::dom::DeviceStorageParams& aParams);
nsresult AllowInternal();
nsresult SendToParentProcess();
@ -390,6 +390,7 @@ protected:
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
DeviceStorageAccessType mAccess;
bool mSendToParent;
bool mUseMainThread;
bool mUseStreamTransport;
bool mCheckFile;
bool mCheckBlob;

View File

@ -64,6 +64,10 @@ const kEventConstructors = {
return new BluetoothDeviceEvent(aName, aProps);
},
},
BluetoothGattAttributeEvent: { create: function (aName, aProps) {
return new BluetoothGattAttributeEvent(aName, aProps);
},
},
BluetoothGattCharacteristicEvent: { create: function (aName, aProps) {
return new BluetoothGattCharacteristicEvent(aName, aProps);
},

View File

@ -72,7 +72,8 @@ DataCall.prototype = {
addreses: null,
dnses: null,
gateways: null,
pcscf: null
pcscf: null,
mtu: -1
};
function DataCallInterfaceService() {

View File

@ -961,7 +961,8 @@ function DataCall(aClientId, aApnSetting, aDataCallHandler) {
addresses: [],
dnses: [],
gateways: [],
pcscf: []
pcscf: [],
mtu: null
};
this.state = NETWORK_STATE_UNKNOWN;
this.requestedNetworkIfaces = [];
@ -1027,6 +1028,10 @@ DataCall.prototype = {
}
}
if (aCurrentDataCall.mtu != aUpdatedDataCall.mtu) {
return "changed";
}
return "identical";
},
@ -1093,6 +1098,7 @@ DataCall.prototype = {
this.linkInfo.gateways = aDataCall.gateways ? aDataCall.gateways.split(" ") : [];
this.linkInfo.dnses = aDataCall.dnses ? aDataCall.dnses.split(" ") : [];
this.linkInfo.pcscf = aDataCall.pcscf ? aDataCall.pcscf.split(" ") : [];
this.linkInfo.mtu = aDataCall.mtu > 0 ? aDataCall.mtu : 0;
this.state = this._getGeckoDataCallState(aDataCall);
// Notify DataCallHandler about data call connected.
@ -1146,7 +1152,8 @@ DataCall.prototype = {
addresses: aUpdatedDataCall.addresses ? aUpdatedDataCall.addresses.split(" ") : [],
dnses: aUpdatedDataCall.dnses ? aUpdatedDataCall.dnses.split(" ") : [],
gateways: aUpdatedDataCall.gateways ? aUpdatedDataCall.gateways.split(" ") : [],
pcscf: aUpdatedDataCall.pcscf ? aUpdatedDataCall.pcscf.split(" ") : []
pcscf: aUpdatedDataCall.pcscf ? aUpdatedDataCall.pcscf.split(" ") : [],
mtu: aUpdatedDataCall.mtu > 0 ? aUpdatedDataCall.mtu : 0
};
switch (dataCallState) {
@ -1173,6 +1180,7 @@ DataCall.prototype = {
this.linkInfo.gateways = newLinkInfo.gateways.slice();
this.linkInfo.dnses = newLinkInfo.dnses.slice();
this.linkInfo.pcscf = newLinkInfo.pcscf.slice();
this.linkInfo.mtu = newLinkInfo.mtu;
}
break;
case NETWORK_STATE_DISCONNECTED:
@ -1272,6 +1280,7 @@ DataCall.prototype = {
this.linkInfo.dnses = [];
this.linkInfo.gateways = [];
this.linkInfo.pcscf = [];
this.linkInfo.mtu = null;
},
reset: function() {
@ -1666,6 +1675,11 @@ RILNetworkInterface.prototype = {
return this.apnSetting.port || "";
},
get mtu() {
// Value provided by network has higher priority than apn settings.
return this.dataCall.linkInfo.mtu || this.apnSetting.mtu || -1;
},
// Helpers
debug: function(aMsg) {

View File

@ -99,6 +99,7 @@ function ExtraNetworkInfo(aNetwork) {
this.dnses = aNetwork.info.getDnses();
this.httpProxyHost = aNetwork.httpProxyHost;
this.httpProxyPort = aNetwork.httpProxyPort;
this.mtu = aNetwork.mtu;
}
ExtraNetworkInfo.prototype = {
getAddresses: function(aIps, aPrefixLengths) {
@ -369,6 +370,13 @@ NetworkManager.prototype = {
return this.setSecondaryDefaultRoute(extNetworkInfo);
})
.then(() => this._addSubnetRoutes(extNetworkInfo))
.then(() => {
if (extNetworkInfo.mtu <= 0) {
return;
}
return this._setMtu(extNetworkInfo);
})
.then(() => this.setAndConfigureActive())
.then(() => {
// Update data connection when Wifi connected/disconnected
@ -943,6 +951,18 @@ NetworkManager.prototype = {
});
},
_setMtu: function(aNetworkInfo) {
return new Promise((aResolve, aReject) => {
gNetworkService.setMtu(aNetworkInfo.name, aNetworkInfo.mtu, (aSuccess) => {
if (!aSuccess) {
debug("setMtu failed");
}
// Always resolve.
aResolve();
});
});
},
_createNetwork: function(aInterfaceName) {
return new Promise((aResolve, aReject) => {
gNetworkService.createNetwork(aInterfaceName, (aSuccess) => {

View File

@ -801,6 +801,20 @@ NetworkService.prototype = {
});
});
},
setMtu: function (aInterfaceName, aMtu, aCallback) {
debug("Set MTU on " + aInterfaceName + ": " + aMtu);
let params = {
cmd: "setMtu",
ifname: aInterfaceName,
mtu: aMtu
};
this.controlMessage(params, function(aResult) {
aCallback.nativeCommandResult(!aResult.error);
});
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkService]);

View File

@ -1438,6 +1438,17 @@ void NetworkUtils::disableIpv6(CommandChain* aChain,
setIpv6Enabled(aChain, aCallback, aResult, false);
}
void NetworkUtils::setMtu(CommandChain* aChain,
CommandCallback aCallback,
NetworkResultOptions& aResult)
{
char command[MAX_COMMAND_SIZE];
PR_snprintf(command, MAX_COMMAND_SIZE - 1, "interface setmtu %s %d",
GET_CHAR(mIfname), GET_FIELD(mMtu));
doCommand(command, aChain, aCallback);
}
#undef GET_CHAR
#undef GET_FIELD
@ -1676,6 +1687,7 @@ void NetworkUtils::ExecuteCommand(NetworkParams aOptions)
BUILD_ENTRY(createNetwork),
BUILD_ENTRY(destroyNetwork),
BUILD_ENTRY(getNetId),
BUILD_ENTRY(setMtu),
#undef BUILD_ENTRY
};
@ -2714,6 +2726,23 @@ CommandResult NetworkUtils::getNetId(NetworkParams& aOptions)
return result;
}
CommandResult NetworkUtils::setMtu(NetworkParams& aOptions)
{
// Setting/getting mtu is supported since Kitkat.
if (SDK_VERSION < 19) {
ERROR("setMtu is not supported in current SDK_VERSION.");
return -1;
}
static CommandFunc COMMAND_CHAIN[] = {
setMtu,
defaultAsyncSuccessHandler,
};
runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
return CommandResult::Pending();
}
void NetworkUtils::sendBroadcastMessage(uint32_t code, char* reason)
{
NetworkResultOptions result;

View File

@ -144,6 +144,7 @@ public:
COPY_OPT_FIELD(mGateway_long, 0)
COPY_OPT_FIELD(mDns1_long, 0)
COPY_OPT_FIELD(mDns2_long, 0)
COPY_OPT_FIELD(mMtu, 0)
mLoopIndex = 0;
@ -196,6 +197,7 @@ public:
long mGateway_long;
long mDns1_long;
long mDns2_long;
long mMtu;
// Auxiliary information required to carry accros command chain.
int mNetId; // A locally defined id per interface.
@ -312,6 +314,7 @@ private:
CommandResult createNetwork(NetworkParams& aOptions);
CommandResult destroyNetwork(NetworkParams& aOptions);
CommandResult getNetId(NetworkParams& aOptions);
CommandResult setMtu(NetworkParams& aOptions);
CommandResult addHostRouteLegacy(NetworkParams& aOptions);
CommandResult removeHostRouteLegacy(NetworkParams& aOptions);
@ -402,6 +405,7 @@ private:
static void modifyRouteOnInterface(PARAMS, bool aDoAdd);
static void enableIpv6(PARAMS);
static void disableIpv6(PARAMS);
static void setMtu(PARAMS);
static void setIpv6Enabled(PARAMS, bool aEnabled);
static void addRouteToSecondaryTable(PARAMS);
static void removeRouteFromSecondaryTable(PARAMS);

View File

@ -393,7 +393,8 @@ DataCall.prototype = {
addreses: null,
dnses: null,
gateways: null,
pcscf: null
pcscf: null,
mtu: -1
};
function RadioInterfaceLayer() {

View File

@ -4,7 +4,7 @@
#include "nsISupports.idl"
[scriptable, uuid(88f18811-8f19-4902-a9b8-2a6430c71c94)]
[scriptable, uuid(6b66446a-7000-438f-8e1b-b56b4cbf4fa9)]
interface nsIDataCall : nsISupports
{
/**
@ -61,6 +61,11 @@ interface nsIDataCall : nsISupports
* IMS client.
*/
readonly attribute DOMString pcscf;
/**
* MTU received from network, -1 if not set or invalid.
*/
readonly attribute long mtu;
};
[scriptable, uuid(e119c54b-9354-4ad6-a1ee-18608bde9320)]

View File

@ -80,7 +80,7 @@ interface nsINetworkInfo : nsISupports
[array, size_is(count), retval] out wstring dnses);
};
[scriptable, uuid(9a025351-8684-4ab5-a0c1-f21a9f83d405)]
[scriptable, uuid(8b1345fa-b34c-41b3-8d21-09f961bf8887)]
interface nsINetworkInterface : nsISupports
{
/**
@ -97,4 +97,9 @@ interface nsINetworkInterface : nsISupports
* The port number of the http proxy server.
*/
readonly attribute long httpProxyPort;
/*
* The Maximun Transmit Unit for this network interface, -1 if not set.
*/
readonly attribute long mtu;
};

View File

@ -157,7 +157,7 @@ interface nsIDhcpRequestCallback : nsISupports
/**
* Provide network services.
*/
[scriptable, uuid(fcd0abd4-8525-469f-a166-12edb4081f3e)]
[scriptable, uuid(8f689d9f-30c0-4809-8bf6-87120e71f3ee)]
interface nsINetworkService : nsISupports
{
const long MODIFY_ROUTE_ADD = 0;
@ -482,9 +482,9 @@ interface nsINetworkService : nsISupports
in nsINativeCommandCallback callback);
/**
* Reset all connections
* Reset all connections on a specified network interface.
*
* @param networkInterface
* @param interfaceName
* The network interface name which we want to reset.
*
* @param callback
@ -494,25 +494,25 @@ interface nsINetworkService : nsISupports
in nsINativeCommandCallback callback);
/**
* Create network (required to call prior to any networking operation)
* Create network (required to call prior to any networking operation).
*
* @param networkInterface
* The network interface name which we want to reset.
* @param interfaceName
* The network interface name which we want to create network for.
*
* @param callback
* Callback to notify the result of resetting connections.
* Callback to notify the result of creating network.
*/
void createNetwork(in DOMString interfaceName,
in nsINativeCommandCallback callback);
/**
* Destroy network (required to call prior to any networking operation)
* Destroy network.
*
* @param networkInterface
* The network interface name which we want to reset.
* @param interfaceName
* The network interface name of the network we want to destroy.
*
* @param callback
* Callback to notify the result of resetting connections.
* Callback to notify the result of destroying network.
*/
void destroyNetwork(in DOMString interfaceName,
in nsINativeCommandCallback callback);
@ -529,4 +529,18 @@ interface nsINetworkService : nsISupports
*
*/
jsval getNetId(in DOMString interfaceName);
/**
* Set maximum transmission unit on a network interface.
*
* @param interfaceName
* The name of the network interface that we want to set mtu.
* @param mtu
* Size of maximum tranmission unit.
*
* @param callback
* Callback to notify the result of setting mtu.
*/
void setMtu(in DOMString interfaceName, in long mtu,
in nsINativeCommandCallback callback);
};

View File

@ -4536,6 +4536,11 @@ RilObject.prototype.readDataCall = function(options, version) {
options.pcscf = Buf.readString();
}
if (version >= 11) {
let mtu = Buf.readInt32();
options.mtu = (mtu > 0) ? mtu : -1 ;
}
return options;
};

View File

@ -40,6 +40,35 @@ ok(ril, "ril.constructor is " + ril.constructor);
var radioInterface = ril.getRadioInterface(0);
ok(radioInterface, "radioInterface.constructor is " + radioInterface.constrctor);
let _pendingEmulatorShellCmdCount = 0;
/**
* Send emulator shell command with safe guard.
*
* We should only call |finish()| after all emulator shell command transactions
* end, so here comes with the pending counter. Resolve when the emulator
* shell gives response. Never reject.
*
* Fulfill params:
* result -- an array of emulator shell response lines.
*
* @param aCommands
* A string array commands to be passed to emulator through adb shell.
*
* @return A deferred promise.
*/
function runEmulatorShellCmdSafe(aCommands) {
return new Promise(function(aResolve, aReject) {
++_pendingEmulatorShellCmdCount;
runEmulatorShell(aCommands, function(aResult) {
--_pendingEmulatorShellCmdCount;
log("Emulator shell response: " + JSON.stringify(aResult));
aResolve(aResult);
});
});
}
/**
* Get mozSettings value specified by @aKey.
*
@ -162,7 +191,7 @@ function waitForTargetEvent(aEventTarget, aEventName, aMatchFun) {
* Set the default data connection enabling state, wait for
* "network-connection-state-changed" event and verify state.
*
* Fulfill params: (none)
* Fulfill params: instance of nsIRilNetworkInfo of the network connected.
*
* @param aEnabled
* A boolean state.
@ -181,17 +210,19 @@ function setDataEnabledAndWait(aEnabled) {
aEnabled ? Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED
: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED,
"subject.state should be " + aEnabled ? "CONNECTED" : "DISCONNECTED");
return aSubject;
}));
promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aEnabled));
return Promise.all(promises);
return Promise.all(promises).then(aValues => aValues[0]);
}
/**
* Setup a certain type of data connection, wait for
* "network-connection-state-changed" event and verify state.
*
* Fulfill params: (none)
* Fulfill params: instance of nsIRilNetworkInfo of the network connected.
*
* @param aNetworkType
* The mobile network type to setup.
@ -210,10 +241,12 @@ function setupDataCallAndWait(aNetworkType) {
"subject.type should be " + aNetworkType);
is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED,
"subject.state should be CONNECTED");
return aSubject;
}));
promises.push(radioInterface.setupDataCallByType(aNetworkType));
return Promise.all(promises);
return Promise.all(promises).then(aValues => aValues[0]);
}
/**
@ -245,6 +278,19 @@ function deactivateDataCallAndWait(aNetworkType) {
return Promise.all(promises);
}
/**
* Wait for pending emulator transactions and call |finish()|.
*/
function cleanUp() {
// Use ok here so that we have at least one test run.
ok(true, ":: CLEANING UP ::");
waitFor(finish, function() {
return _pendingEmulatorShellCmdCount === 0;
});
}
/**
* Basic test routine helper.
*
@ -258,6 +304,6 @@ function startTestBase(aTestCaseMain) {
.then(aTestCaseMain)
.then(finish, function(aException) {
ok(false, "promise rejects during test: " + aException);
finish();
cleanUp();
});
}

View File

@ -15,3 +15,5 @@ disabled = Bug 808783
[test_data_connection_proxy.js]
[test_network_interface_list_service.js]
[test_all_network_info.js]
[test_network_interface_mtu.js]
skip-if = android_version < '19'

View File

@ -0,0 +1,104 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
const TEST_MTU1 = "1410";
const TEST_MTU2 = "1440";
function setEmulatorAPN() {
let apn = [
[ { "carrier":"T-Mobile US",
"apn":"epc1.tmobile.com",
"types":["default"],
"mtu": TEST_MTU1 },
{ "carrier":"T-Mobile US",
"apn":"epc2.tmobile.com",
"mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
"types":["supl","mms","ims","dun", "fota"],
"mtu": TEST_MTU2 } ]
];
return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
}
function verifyInitialState() {
// Data should be off before starting any test.
return getSettings(SETTINGS_KEY_DATA_ENABLED)
.then(value => {
is(value, false, "Data must be off");
});
}
function verifyMtu(aInterfaceName, aMtu) {
runEmulatorShellCmdSafe(['ip', 'link', 'show', 'dev', aInterfaceName])
.then(aLines => {
// Sample output:
//
// 4: rmnet0: <BROADCAST,MULTICAST> mtu 1410 qdisc pfifo_fast state DOWN mode DEFAULT qlen 1000
// link/ether 52:54:00:12:34:58 brd ff:ff:ff:ff:ff:ff
//
let mtu;
aLines.some(function (aLine) {
let tokens = aLine.trim().split(/\s+/);
let mtuIndex = tokens.indexOf('mtu');
if (mtuIndex < 0 || mtuIndex + 1 >= tokens.length) {
return false;
}
mtu = tokens[mtuIndex + 1];
return true;
});
is(mtu, aMtu, aInterfaceName + "'s mtu.");
});
}
function testDefaultDataCallMtu() {
log("= testDefaultDataCallMtu =");
return setDataEnabledAndWait(true)
.then(aNetworkInfo => {
verifyMtu(aNetworkInfo.name, TEST_MTU1);
})
.then(() => setDataEnabledAndWait(false));
}
function testNonDefaultDataCallMtu() {
log("= testNonDefaultDataCallMtu =");
function doTestNonDefaultDataCallMtu(aType) {
log("doTestNonDefaultDataCallMtu: " + aType);
return setupDataCallAndWait(aType)
.then(aNetworkInfo => {
verifyMtu(aNetworkInfo.name, TEST_MTU2);
})
.then(() => deactivateDataCallAndWait(aType));
}
return doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_MMS)
.then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_SUPL))
.then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_IMS))
.then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_DUN))
.then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_FOTA));
}
// Start test
startTestBase(function() {
let origApnSettings;
return verifyInitialState()
.then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS))
.then(value => {
origApnSettings = value;
})
.then(() => setEmulatorAPN())
.then(() => testDefaultDataCallMtu())
.then(() => testNonDefaultDataCallMtu())
.then(() => {
if (origApnSettings) {
return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings);
}
});
});

View File

@ -200,6 +200,9 @@ var interfaceNamesInGlobalScope =
{name: "BluetoothDiscoveryHandle", b2g: true, permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothGatt", b2g: true, permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothGattAttributeEvent", b2g: true,
permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothGattCharacteristic", b2g: true,
permission: ["bluetooth"]},

View File

@ -0,0 +1,33 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
[Constructor(DOMString type,
optional BluetoothGattAttributeEventInit eventInitDict),
CheckAnyPermissions="bluetooth"]
interface BluetoothGattAttributeEvent : Event
{
readonly attribute DOMString address;
readonly attribute long requestId;
readonly attribute BluetoothGattCharacteristic? characteristic;
readonly attribute BluetoothGattDescriptor? descriptor;
[Throws]
readonly attribute ArrayBuffer? value;
readonly attribute boolean needResponse;
};
dictionary BluetoothGattAttributeEventInit : EventInit
{
DOMString address = "";
long requestId = 0;
BluetoothGattCharacteristic? characteristic = null;
BluetoothGattDescriptor? descriptor = null;
/**
* Note that the passed-in value will be copied by the event constructor
* here instead of storing the reference.
*/
ArrayBuffer? value = null;
boolean needResponse = true;
};

View File

@ -6,16 +6,33 @@
dictionary GattCharacteristicProperties
{
required boolean broadcast;
required boolean read;
required boolean writeNoResponse;
required boolean write;
required boolean notify;
required boolean indicate;
required boolean signedWrite;
required boolean extendedProps;
boolean broadcast = false;
boolean read = false;
boolean writeNoResponse = false;
boolean write = false;
boolean notify = false;
boolean indicate = false;
boolean signedWrite = false;
boolean extendedProps = false;
};
dictionary GattPermissions
{
boolean read = false;
boolean readEncrypted = false;
boolean readEncryptedMITM = false;
boolean write = false;
boolean writeEncrypted = false;
boolean writeEncryptedMITM = false;
boolean writeSigned = false;
boolean writeSignedMITM = false;
};
/**
* BluetoothGattCharacteristic could be in the server role as a characteristic
* provided by a local GATT server, or in the client role as a characteristic
* provided by a remote GATT server.
*/
[CheckAnyPermissions="bluetooth"]
interface BluetoothGattCharacteristic
{
@ -27,8 +44,17 @@ interface BluetoothGattCharacteristic
readonly attribute unsigned short instanceId;
readonly attribute ArrayBuffer? value;
[Cached, Constant]
readonly attribute GattPermissions permissions;
[Cached, Constant]
readonly attribute GattCharacteristicProperties properties;
/**
* Read or write the value of this characteristic.
*
* If this charactersitic is in the client role, the value will be
* read from or written to the remote GATT server. Otherwise, the local value
* will be read/written.
*/
[NewObject]
Promise<ArrayBuffer> readValue();
[NewObject]
@ -37,9 +63,23 @@ interface BluetoothGattCharacteristic
/**
* Start or stop subscribing notifications of this characteristic from the
* remote GATT server.
*
* This API will be rejected if this characteristic is in the server role.
*/
[NewObject]
Promise<void> startNotifications();
[NewObject]
Promise<void> stopNotifications();
/**
* Add a BLE descriptor to the local GATT characteristic.
*
* The promise will be rejected if this characteristic is in the client role
* since a GATT client is not allowed to manipulate the descriptor list in a
* remote GATT server.
*/
[NewObject]
Promise<BluetoothGattDescriptor> addDescriptor(DOMString uuid,
GattPermissions permissions,
ArrayBuffer value);
};

View File

@ -4,13 +4,27 @@
* 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/. */
/**
* BluetoothGattDescriptor could be in the server role as a descriptor provided
* by a local GATT server, or in the client role as a descriptor provided by a
* remote GATT server.
*/
[CheckAnyPermissions="bluetooth"]
interface BluetoothGattDescriptor
{
readonly attribute BluetoothGattCharacteristic characteristic;
readonly attribute DOMString uuid;
readonly attribute ArrayBuffer? value;
[Cached, Constant]
readonly attribute GattPermissions permissions;
/**
* Read or write the value of this descriptor.
*
* If this descriptor is in the client role, the value will be read from or
* written to the remote GATT server. Otherwise, the local value will be
* read/written.
*/
[NewObject]
Promise<ArrayBuffer> readValue();
[NewObject]

View File

@ -7,9 +7,16 @@
[CheckAnyPermissions="bluetooth"]
interface BluetoothGattServer : EventTarget
{
[Cached, Pure]
readonly attribute sequence<BluetoothGattService> services;
// Fired when a remote device has been connected/disconnected
attribute EventHandler onconnectionstatechanged;
// Fired when a remote BLE client send a read/write request
attribute EventHandler onattributereadreq;
attribute EventHandler onattributewritereq;
/**
* Connect/Disconnect to the remote BLE device with the target address.
*
@ -20,4 +27,39 @@ interface BluetoothGattServer : EventTarget
Promise<void> connect(DOMString address);
[NewObject]
Promise<void> disconnect(DOMString address);
/**
* Add a BLE service to the local GATT server.
*
* This API will be rejected if this service has been added to the GATT
* server.
*/
[NewObject]
Promise<void> addService(BluetoothGattService service);
/**
* Remove a BLE service to the local GATT server.
*
* This API will be rejected if this service does not exist in the GATT
* server.
*/
[NewObject]
Promise<void> removeService(BluetoothGattService service);
/**
* Notify the remote BLE device that the value of a characteristic has been
* changed.
*/
[NewObject]
Promise<void> notifyCharacteristicChanged(
DOMString address,
BluetoothGattCharacteristic characteristic,
boolean confirm);
/**
* Send a read/write response to a remote BLE client
*/
[NewObject]
Promise<void> sendResponse(
DOMString address, unsigned short status, long requestId);
};

View File

@ -4,7 +4,12 @@
* 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/. */
[CheckAnyPermissions="bluetooth"]
/**
* BluetoothGattService could be in the server role as a service provided by a
* local GATT server, or in the client role as a service provided by a remote
* GATT server.
*/
[CheckAnyPermissions="bluetooth", Constructor(BluetoothGattServiceInit init)]
interface BluetoothGattService
{
[Cached, Pure]
@ -15,4 +20,35 @@ interface BluetoothGattService
readonly attribute boolean isPrimary;
readonly attribute DOMString uuid;
readonly attribute unsigned short instanceId;
/**
* Add a BLE characteristic to the local GATT service.
*
* This API will be rejected if this service is in the client role since a
* GATT client is not allowed to manipulate the characteristic list in a
* remote GATT server.
*/
[NewObject]
Promise<BluetoothGattCharacteristic> addCharacteristic(
DOMString uuid,
GattPermissions permissions,
GattCharacteristicProperties properties,
ArrayBuffer value);
/**
* Add a BLE included service to the local GATT service.
*
* This API will be rejected if this service is in the client role since a
* GATT client is not allowed to manipulate the included service list in a
* remote GATT server. The included service to be added should be an existing
* service of the same GATT server. Otherwise this API will be rejected.
*/
[NewObject]
Promise<void> addIncludedService(BluetoothGattService service);
};
dictionary BluetoothGattServiceInit
{
boolean isPrimary = false;
DOMString uuid = "";
};

View File

@ -54,6 +54,8 @@ dictionary NetworkCommandOptions
long gateway_long; // for "ifc_configure".
long dns1_long; // for "ifc_configure".
long dns2_long; // for "ifc_configure".
long mtu; // for "setMtu".
};
/**

View File

@ -684,6 +684,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothDevice.webidl',
'BluetoothDiscoveryHandle.webidl',
'BluetoothGatt.webidl',
'BluetoothGattAttributeEvent.webidl',
'BluetoothGattCharacteristic.webidl',
'BluetoothGattDescriptor.webidl',
'BluetoothGattServer.webidl',

View File

@ -1,148 +0,0 @@
# 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/.
# XXX Bug 1181261 - Please update config in testing/mozharness/config
# instead. This file is still needed for taskcluster emulator tests,
# but should be removed once bug 1188330 is finished.
config = {
"suite_definitions": {
"cppunittest": {
"options": [
"--dm_trans=adb",
"--symbols-path=%(symbols_path)s",
"--xre-path=%(xre_path)s",
"--addEnv",
"LD_LIBRARY_PATH=/vendor/lib:/system/lib:/system/b2g",
"--with-b2g-emulator=%(b2gpath)s",
"."
],
"run_filename": "remotecppunittests.py",
"testsdir": "cppunittest"
},
"crashtest": {
"options": [
"--adbpath=%(adbpath)s",
"--b2gpath=%(b2gpath)s",
"--emulator=%(emulator)s",
"--emulator-res=800x1000",
"--logdir=%(logcat_dir)s",
"--remote-webserver=%(remote_webserver)s",
"--ignore-window-size",
"--xre-path=%(xre_path)s",
"--symbols-path=%(symbols_path)s",
"--busybox=%(busybox)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"tests/testing/crashtest/crashtests.list"
],
"run_filename": "runreftestb2g.py",
"testsdir": "reftest"
},
"jsreftest": {
"options": [
"--adbpath=%(adbpath)s",
"--b2gpath=%(b2gpath)s",
"--emulator=%(emulator)s",
"--emulator-res=800x1000",
"--logdir=%(logcat_dir)s",
"--remote-webserver=%(remote_webserver)s",
"--ignore-window-size",
"--xre-path=%(xre_path)s",
"--symbols-path=%(symbols_path)s",
"--busybox=%(busybox)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"--extra-profile-file=jsreftest/tests/user.js",
"jsreftest/tests/jstests.list"
],
"run_filename": "remotereftest.py",
"testsdir": "reftest"
},
"mochitest": {
"options": [
"--adbpath=%(adbpath)s",
"--b2gpath=%(b2gpath)s",
"--emulator=%(emulator)s",
"--logdir=%(logcat_dir)s",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--symbols-path=%(symbols_path)s",
"--busybox=%(busybox)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"--quiet",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--certificate-path=%(certificate_path)s",
"--screenshot-on-fail",
"%(test_path)s"
],
"run_filename": "runtestsb2g.py",
"testsdir": "mochitest"
},
"mochitest-chrome": {
"options": [
"--adbpath=%(adbpath)s",
"--b2gpath=%(b2gpath)s",
"--emulator=%(emulator)s",
"--logdir=%(logcat_dir)s",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--symbols-path=%(symbols_path)s",
"--busybox=%(busybox)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"--quiet",
"--chrome",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--certificate-path=%(certificate_path)s",
"--screenshot-on-fail",
"%(test_path)s"
],
"run_filename": "runtestsb2g.py",
"testsdir": "mochitest"
},
"reftest": {
"options": [
"--adbpath=%(adbpath)s",
"--b2gpath=%(b2gpath)s",
"--emulator=%(emulator)s",
"--emulator-res=800x1000",
"--logdir=%(logcat_dir)s",
"--remote-webserver=%(remote_webserver)s",
"--ignore-window-size",
"--xre-path=%(xre_path)s",
"--symbols-path=%(symbols_path)s",
"--busybox=%(busybox)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"--enable-oop",
"tests/layout/reftests/reftest.list"
],
"run_filename": "runreftestsb2g.py",
"testsdir": "reftest"
},
"xpcshell": {
"options": [
"--adbpath=%(adbpath)s",
"--b2gpath=%(b2gpath)s",
"--emulator=%(emulator)s",
"--logdir=%(logcat_dir)s",
"--manifest=tests/xpcshell.ini",
"--use-device-libs",
"--testing-modules-dir=%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--busybox=%(busybox)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
],
"run_filename": "runtestsb2g.py",
"testsdir": "xpcshell"
}
}
}

View File

@ -1,120 +0,0 @@
# 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/.
# XXX Bug 1181261 - Please update config in testing/mozharness/config
# instead. This file is still needed for mulet mochitests, but should
# be removed once bug 1188330 is finished.
config = {
"suite_definitions": {
"cppunittest": {
"options": [
"--symbols-path=%(symbols_path)s",
"--xre-path=%(abs_app_dir)s"
],
"run_filename": "runcppunittests.py",
"testsdir": "cppunittest"
},
"jittest": {
"options": [
"tests/bin/js",
"--no-slow",
"--no-progress",
"--format=automation",
"--jitflags=all"
],
"run_filename": "jit_test.py",
"testsdir": "jit-test/jit-test"
},
"luciddream-emulator": {
"options": [
"--startup-timeout=300",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--browser-path=%(browser_path)s",
"--b2gpath=%(emulator_path)s",
"%(test_manifest)s"
],
},
"luciddream-b2gdt": {
"options": [
"--startup-timeout=300",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--browser-path=%(browser_path)s",
"--b2g-desktop-path=%(fxos_desktop_path)s",
"--gaia-profile=%(gaia_profile)s",
"%(test_manifest)s"
],
},
"mochitest": {
"options": [
"--appname=%(binary_path)s",
"--utility-path=tests/bin",
"--extra-profile-file=tests/bin/plugins",
"--symbols-path=%(symbols_path)s",
"--certificate-path=tests/certs",
"--setpref=webgl.force-enabled=true",
"--quiet",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--use-test-media-devices",
"--screenshot-on-fail",
],
"run_filename": "runtests.py",
"testsdir": "mochitest"
},
"mozbase": {
"options": [
"-b",
"%(binary_path)s"
],
"run_filename": "test.py",
"testsdir": "mozbase"
},
"mozmill": {
"options": [
"--binary=%(binary_path)s",
"--symbols-path=%(symbols_path)s"
],
"run_filename": "runtestlist.py",
"testsdir": "mozmill"
},
"reftest": {
"options": [
"--appname=%(binary_path)s",
"--utility-path=tests/bin",
"--extra-profile-file=tests/bin/plugins",
"--symbols-path=%(symbols_path)s"
],
"run_filename": "runreftest.py",
"testsdir": "reftest"
},
"webapprt": {
"options": [
"--app=%(app_path)s",
"--utility-path=tests/bin",
"--extra-profile-file=tests/bin/plugins",
"--symbols-path=%(symbols_path)s",
"--certificate-path=tests/certs",
"--console-level=INFO",
"--testing-modules-dir=tests/modules",
"--quiet"
],
"run_filename": "runtests.py",
"testsdir": "mochitest"
},
"xpcshell": {
"options": [
"--symbols-path=%(symbols_path)s",
"--test-plugin-path=%(test_plugin_path)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--utility-path=tests/bin",
],
"run_filename": "runxpcshelltests.py",
"testsdir": "xpcshell"
}
}
}

View File

@ -1,22 +0,0 @@
# This is used by mozharness' mulet_unittest.py
# XXX Bug 1181261 - Please update config in testing/mozharness/config
# instead. This file is still needed for mulet reftests, but should
# be removed once bug 1188330 is finished.
config = {
# testsuite options
"reftest_options": [
"--mulet",
"--profile=%(gaia_profile)s",
"--appname=%(application)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s",
"--symbols-path=%(symbols_path)s",
"--enable-oop",
"%(test_manifest)s"
],
"run_file_names": {
"reftest": "runreftestb2g.py",
},
}

View File

@ -1,95 +0,0 @@
# 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/.
# XXX Bug 1181261 - Please update config in testing/mozharness/config
# instead. This file is still needed for taskcluster emulator tests,
# but should be removed once bug 1188330 is finished.
config = {
"suite_definitions": {
"gaiatest_desktop": {
"options": [
"--restart",
"--timeout=%(timeout)s",
"--type=%(type)s",
"--testvars=%(testvars)s",
"--profile=%(profile)s",
"--symbols-path=%(symbols_path)s",
"--gecko-log=%(gecko_log)s",
"--xml-output=%(xml_output)s",
"--html-output=%(html_output)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--binary=%(binary)s",
"--address=%(address)s",
"--total-chunks=%(total_chunks)s",
"--this-chunk=%(this_chunk)s"
],
"run_filename": "",
"testsdir": ""
},
"gaiatest_emulator": {
"options": [
"--restart",
"--timeout=%(timeout)s",
"--type=%(type)s",
"--testvars=%(testvars)s",
"--profile=%(profile)s",
"--symbols-path=%(symbols_path)s",
"--xml-output=%(xml_output)s",
"--html-output=%(html_output)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--logcat-dir=%(logcat_dir)s",
"--emulator=%(emulator)s",
"--homedir=%(homedir)s"
],
"run_filename": "",
"testsdir": ""
},
"marionette_desktop": {
"options": [
"--type=%(type)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--binary=%(binary)s",
"--address=%(address)s",
"--symbols-path=%(symbols_path)s"
],
"run_filename": "",
"testsdir": ""
},
"marionette_emulator": {
"options": [
"--type=%(type)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--logcat-dir=%(logcat_dir)s",
"--emulator=%(emulator)s",
"--homedir=%(homedir)s",
"--symbols-path=%(symbols_path)s"
],
"run_filename": "",
"testsdir": ""
},
"webapi_desktop": {
"options": [],
"run_filename": "",
"testsdir": ""
},
"webapi_emulator": {
"options": [
"--type=%(type)s",
"--log-raw=%(raw_log_file)s",
"--log-errorsummary=%(error_summary_file)s",
"--symbols-path=%(symbols_path)s",
"--logcat-dir=%(logcat_dir)s",
"--emulator=%(emulator)s",
"--homedir=%(homedir)s"
],
"run_filename": "",
"testsdir": ""
}
}
}

View File

@ -740,14 +740,9 @@ class B2GBuild(LocalesMixin, PurgeMixin,
if base_pattern in public_upload_patterns:
public_files.append(f)
device_name = self.config['target'].split('-')[0]
blobfree_zip = os.path.join(
dirs['work_dir'],
'out',
'target',
'product',
device_name,
device_name + '.blobfree-dist.zip')
device_name = os.path.basename(output_dir)
blobfree_dist = device_name + '.blobfree-dist.zip'
blobfree_zip = os.path.join(output_dir, blobfree_dist)
if os.path.exists(blobfree_zip):
public_files.append(blobfree_zip)

View File

@ -21,8 +21,8 @@ if [ -f $WORKSPACE/B2G/upload/b2g-*.crashreporter-symbols.zip ]; then
mv $WORKSPACE/B2G/upload/b2g-*.crashreporter-symbols.zip $HOME/artifacts/b2g-crashreporter-symbols.zip
fi
if [ -f $WORKSPACE/B2G/upload-public/${DEVICE}.blobfree-dist.zip ]; then
mv $WORKSPACE/B2G/upload-public/${DEVICE}.blobfree-dist.zip $HOME/artifacts-public
if [ -f $WORKSPACE/B2G/upload-public/*.blobfree-dist.zip ]; then
mv $WORKSPACE/B2G/upload-public/*.blobfree-dist.zip $HOME/artifacts-public/
fi
if [ -f $WORKSPACE/B2G/upload-public/$mar_file ]; then