Merge m-c to inbound, a=merge

This commit is contained in:
Wes Kocher 2015-05-19 16:44:10 -07:00
commit 9cd4ebfb26
44 changed files with 1646 additions and 1148 deletions

View File

@ -15,15 +15,15 @@
<project name="platform_build" path="build" remote="b2g" revision="a8ace1361d702eef293e48f2ea525dac686daa86">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -15,15 +15,15 @@
<project name="platform_build" path="build" remote="b2g" revision="a8ace1361d702eef293e48f2ea525dac686daa86">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -19,8 +19,8 @@
<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="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8c2d32bccc7061e9ca0165135457c3fd53e7107e"/>

View File

@ -17,10 +17,10 @@
</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="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,15 +15,15 @@
<project name="platform_build" path="build" remote="b2g" revision="a8ace1361d702eef293e48f2ea525dac686daa86">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -15,15 +15,15 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

View File

@ -19,8 +19,8 @@
<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="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8c2d32bccc7061e9ca0165135457c3fd53e7107e"/>

View File

@ -15,15 +15,15 @@
<project name="platform_build" path="build" remote="b2g" revision="a8ace1361d702eef293e48f2ea525dac686daa86">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "97dc139f1a690224e98533a86526c4165eed1db5",
"git_revision": "600fd8249960b8256af9de67d9171025bb9a3ff3",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "8fa0242e0aa7c8e126dec5fb6811f6137616c87e",
"revision": "c2b9d5ec23830d9e360ca665ffe4d60195f60c91",
"repo_path": "integration/gaia-central"
}

View File

@ -17,10 +17,10 @@
</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="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,15 +15,15 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="97dc139f1a690224e98533a86526c4165eed1db5"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="600fd8249960b8256af9de67d9171025bb9a3ff3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4ba12ace183b9664b4dc4f146a796564514d9605"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

View File

@ -270,7 +270,6 @@ BroadcastSystemMessage(const nsAString& aType,
return true;
}
#ifdef MOZ_B2G_BT_API_V2
void
DispatchReplySuccess(BluetoothReplyRunnable* aRunnable)
{
@ -297,8 +296,14 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
MOZ_ASSERT(aRunnable);
MOZ_ASSERT(!aErrorStr.IsEmpty());
// Reply will be deleted by the runnable after running on main thread
#if MOZ_B2G_BT_API_V2
BluetoothReply* reply =
new BluetoothReply(BluetoothReplyError(STATUS_FAIL, nsString(aErrorStr)));
#else
BluetoothReply* reply =
new BluetoothReply(BluetoothReplyError(nsString(aErrorStr)));
#endif
aRunnable->SetReply(reply); // runnable will delete reply after Run()
NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(aRunnable)));
@ -311,8 +316,15 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
MOZ_ASSERT(aRunnable);
MOZ_ASSERT(aStatus != STATUS_SUCCESS);
// Reply will be deleted by the runnable after running on main thread
#if MOZ_B2G_BT_API_V2
BluetoothReply* reply =
new BluetoothReply(BluetoothReplyError(aStatus, EmptyString()));
#else
BluetoothReply* reply =
new BluetoothReply(
BluetoothReplyError(NS_LITERAL_STRING("Internal error")));
#endif
aRunnable->SetReply(reply); // runnable will delete reply after Run()
NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(aRunnable)));
@ -331,50 +343,14 @@ DispatchStatusChangedEvent(const nsAString& aType,
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
#ifdef MOZ_B2G_BT_API_V2
bs->DistributeSignal(aType, NS_LITERAL_STRING(KEY_ADAPTER), data);
}
#else
// TODO: remove with bluetooth1
void
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
const BluetoothValue& aValue,
const nsAString& aErrorStr)
{
// Reply will be deleted by the runnable after running on main thread
BluetoothReply* reply;
if (!aErrorStr.IsEmpty()) {
nsString err(aErrorStr);
reply = new BluetoothReply(BluetoothReplyError(err));
} else {
MOZ_ASSERT(aValue.type() != BluetoothValue::T__None);
reply = new BluetoothReply(BluetoothReplySuccess(aValue));
}
aRunnable->SetReply(reply);
if (NS_FAILED(NS_DispatchToMainThread(aRunnable))) {
BT_WARNING("Failed to dispatch to main thread!");
}
}
// TODO: remove with bluetooth1
void
DispatchStatusChangedEvent(const nsAString& aType,
const nsAString& aAddress,
bool aStatus)
{
MOZ_ASSERT(NS_IsMainThread());
InfallibleTArray<BluetoothNamedValue> data;
BT_APPEND_NAMED_VALUE(data, "address", nsString(aAddress));
BT_APPEND_NAMED_VALUE(data, "status", aStatus);
BluetoothSignal signal(nsString(aType), NS_LITERAL_STRING(KEY_ADAPTER), data);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
bs->DistributeSignal(signal);
}
#endif
}
bool
IsMainProcess()

View File

@ -127,7 +127,6 @@ BroadcastSystemMessage(const nsAString& aType,
// Dispatch bluetooth reply to main thread
//
#ifdef MOZ_B2G_BT_API_V2
/**
* Dispatch successful bluetooth reply with NO value to reply request.
*
@ -177,19 +176,6 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
void
DispatchReplyError(BluetoothReplyRunnable* aRunnable,
const enum BluetoothStatus aStatus);
#else
// TODO: remove with bluetooth1
void
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
const BluetoothValue& aValue,
const nsAString& aErrorStr);
// TODO: remove with bluetooth1
void
DispatchStatusChangedEvent(const nsAString& aType,
const nsAString& aDeviceAddress,
bool aStatus);
#endif
void
DispatchStatusChangedEvent(const nsAString& aType,

View File

@ -0,0 +1,174 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothDaemonConnector.h"
#include <fcntl.h>
#include "nsThreadUtils.h"
BEGIN_BLUETOOTH_NAMESPACE
BluetoothDaemonConnector::BluetoothDaemonConnector(
const nsACString& aSocketName)
: mSocketName(aSocketName)
{ }
BluetoothDaemonConnector::~BluetoothDaemonConnector()
{ }
nsresult
BluetoothDaemonConnector::CreateSocket(int& aFd) const
{
aFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (aFd < 0) {
BT_WARNING("Could not open Bluetooth daemon socket!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
BluetoothDaemonConnector::SetSocketFlags(int aFd) const
{
static const int sReuseAddress = 1;
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= FD_CLOEXEC;
int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= O_NONBLOCK;
res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set socket addr to be reused even if kernel is still waiting to close.
res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
sizeof(sReuseAddress));
if (res < 0) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
BluetoothDaemonConnector::CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const
{
static const size_t sNameOffset = 1;
struct sockaddr_un* address =
reinterpret_cast<struct sockaddr_un*>(&aAddress);
size_t namesiz = mSocketName.Length() + 1; // include trailing '\0'
if (NS_WARN_IF((sNameOffset + namesiz) > sizeof(address->sun_path))) {
return NS_ERROR_FAILURE;
}
address->sun_family = AF_UNIX;
memset(address->sun_path, '\0', sNameOffset); // abstract socket
memcpy(address->sun_path + sNameOffset, mSocketName.get(), namesiz);
aAddressLength =
offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
return NS_OK;
}
// |UnixSocketConnector|
nsresult
BluetoothDaemonConnector::ConvertAddressToString(
const struct sockaddr& aAddress, socklen_t aAddressLength,
nsACString& aAddressString)
{
MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
const struct sockaddr_un* un =
reinterpret_cast<const struct sockaddr_un*>(&aAddress);
size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
aAddressString.Assign(un->sun_path, len);
return NS_OK;
}
nsresult
BluetoothDaemonConnector::CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd)
{
ScopedClose fd;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
aListenFd = fd.forget();
return NS_OK;
}
nsresult
BluetoothDaemonConnector::AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
ScopedClose fd(
TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
if (fd < 0) {
NS_WARNING("Cannot accept file descriptor!");
return NS_ERROR_FAILURE;
}
nsresult rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
aStreamFd = fd.forget();
return NS_OK;
}
nsresult
BluetoothDaemonConnector::CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
MOZ_CRASH("|BluetoothDaemonConnector| does not support "
"creating stream sockets.");
return NS_ERROR_ABORT;
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,54 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothdaemonconnector_h
#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemonconnector_h
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/ipc/UnixSocketConnector.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothDaemonConnector final
: public mozilla::ipc::UnixSocketConnector
{
public:
BluetoothDaemonConnector(const nsACString& aSocketName);
~BluetoothDaemonConnector();
// Methods for |UnixSocketConnector|
//
nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) override;
nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) override;
nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLen,
int& aStreamFd) override;
nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
private:
nsresult CreateSocket(int& aFd) const;
nsresult SetSocketFlags(int aFd) const;
nsresult CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const;
nsCString mSocketName;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -10,13 +10,13 @@
#include <stdlib.h>
#include "BluetoothDaemonA2dpInterface.h"
#include "BluetoothDaemonAvrcpInterface.h"
#include "BluetoothDaemonConnector.h"
#include "BluetoothDaemonHandsfreeInterface.h"
#include "BluetoothDaemonHelpers.h"
#include "BluetoothDaemonSetupInterface.h"
#include "BluetoothDaemonSocketInterface.h"
#include "BluetoothInterfaceHelpers.h"
#include "mozilla/ipc/ListenSocket.h"
#include "mozilla/ipc/UnixSocketConnector.h"
#include "mozilla/unused.h"
#include "prrng.h"
@ -2018,78 +2018,6 @@ BluetoothDaemonInterface::OnDisconnect(enum Channel aChannel)
}
}
class BluetoothDaemonSocketConnector final
: public mozilla::ipc::UnixSocketConnector
{
public:
BluetoothDaemonSocketConnector(const nsACString& aSocketName)
: mSocketName(aSocketName)
{ }
int
Create() override
{
MOZ_ASSERT(!NS_IsMainThread());
int fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (fd < 0) {
BT_WARNING("Could not open socket!");
return -1;
}
return fd;
}
bool
CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress) override
{
static const size_t sNameOffset = 1;
size_t namesiz = mSocketName.Length() + 1; /* include trailing '\0' */
if ((sNameOffset + namesiz) > sizeof(aAddr.un.sun_path)) {
BT_WARNING("Address too long for socket struct!");
return false;
}
memset(aAddr.un.sun_path, '\0', sNameOffset); // abstract socket
memcpy(aAddr.un.sun_path + sNameOffset, mSocketName.get(), namesiz);
aAddr.un.sun_family = AF_UNIX;
aAddrSize = offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
return true;
}
bool
SetUp(int aFd) override
{
if (TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, O_NONBLOCK)) < 0) {
BT_WARNING("Failed to set non-blocking I/O.");
return false;
}
return true;
}
bool
SetUpListenSocket(int aFd) override
{
return true;
}
void
GetSocketAddr(const sockaddr_any& aAddr, nsAString& aAddrStr) override
{
// Unused.
MOZ_CRASH("This should never be called!");
}
private:
nsCString mSocketName;
};
nsresult
BluetoothDaemonInterface::CreateRandomAddressString(
const nsACString& aPrefix, unsigned long aPostfixLength,
@ -2209,7 +2137,7 @@ BluetoothDaemonInterface::Init(
}
bool success = mListenSocket->Listen(
new BluetoothDaemonSocketConnector(mListenSocketName), mCmdChannel);
new BluetoothDaemonConnector(mListenSocketName), mCmdChannel);
if (!success) {
OnConnectError(CMD_CHANNEL);
return;

View File

@ -45,8 +45,6 @@
#include "nsDataHashtable.h"
#endif
#ifdef MOZ_B2G_BT_API_V2
#define ENSURE_BLUETOOTH_IS_READY(runnable, result) \
do { \
if (!sBtInterface || !IsEnabled()) { \
@ -65,6 +63,8 @@
} \
} while(0)
#ifdef MOZ_B2G_BT_API_V2
#define ENSURE_GATT_MGR_IS_READY_VOID(gatt, runnable) \
do { \
if (!gatt) { \
@ -594,24 +594,6 @@ BluetoothServiceBluedroid::GattClientWriteDescriptorValueInternal(
}
#else
#define ENSURE_BLUETOOTH_IS_READY(runnable, result) \
do { \
if (!sBtInterface || !IsEnabled()) { \
NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth is not ready"); \
DispatchBluetoothReply(runnable, BluetoothValue(), errorStr); \
return result; \
} \
} while(0)
#define ENSURE_BLUETOOTH_IS_READY_VOID(runnable) \
do { \
if (!sBtInterface || !IsEnabled()) { \
NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth is not ready"); \
DispatchBluetoothReply(runnable, BluetoothValue(), errorStr); \
return; \
} \
} while(0)
// Audio: Major service class = 0x100 (Bit 21 is set)
#define SET_AUDIO_BIT(cod) (cod |= 0x200000)
// Rendering: Major service class = 0x20 (Bit 18 is set)
@ -936,8 +918,7 @@ ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
replyError.AppendLiteral(":BT_STATUS_FAIL");
}
DispatchBluetoothReply(aBluetoothReplyRunnable, BluetoothValue(true),
replyError);
DispatchReplyError(aBluetoothReplyRunnable, replyError);
}
/**
@ -1057,7 +1038,7 @@ BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
BT_APPEND_NAMED_VALUE(v.get_ArrayOfBluetoothNamedValue(),
"Devices", sAdapterBondedAddressArray);
DispatchBluetoothReply(aRunnable, v, EmptyString());
DispatchReplySuccess(aRunnable, v);
return NS_OK;
}
@ -1098,8 +1079,7 @@ public:
/* dispatch result after final pending operation */
if (--sRequestedDeviceCountArray[0] == 0) {
if (!sGetDeviceRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sGetDeviceRunnableArray[0],
sRemoteDevicesPack, EmptyString());
DispatchReplySuccess(sGetDeviceRunnableArray[0], sRemoteDevicesPack);
sGetDeviceRunnableArray.RemoveElementAt(0);
}
@ -1147,8 +1127,7 @@ BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
BluetoothUuidHelper::GetBluetoothProfileManager(aServiceUuid);
if (!profile) {
InfallibleTArray<BluetoothNamedValue> emptyArr;
DispatchBluetoothReply(aRunnable, emptyArr,
NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
DispatchReplyError(aRunnable, NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
return NS_OK;
}
@ -1162,7 +1141,7 @@ BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
int requestedDeviceCount = deviceAddresses.Length();
if (requestedDeviceCount == 0) {
InfallibleTArray<BluetoothNamedValue> emptyArr;
DispatchBluetoothReply(aRunnable, emptyArr, EmptyString());
DispatchReplySuccess(aRunnable, emptyArr);
return NS_OK;
}
#endif
@ -1196,8 +1175,7 @@ BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal(
#else
int requestedDeviceCount = aDeviceAddress.Length();
if (requestedDeviceCount == 0) {
InfallibleTArray<BluetoothNamedValue> emptyArr;
DispatchBluetoothReply(aRunnable, BluetoothValue(emptyArr), EmptyString());
DispatchReplySuccess(aRunnable, InfallibleTArray<BluetoothNamedValue>());
return NS_OK;
}
@ -1233,7 +1211,7 @@ public:
void StartDiscovery() override
{
MOZ_ASSERT(NS_IsMainThread());
DispatchBluetoothReply(mRunnable, true, EmptyString());
DispatchReplySuccess(mRunnable);
}
void OnError(BluetoothStatus aStatus) override
@ -1282,7 +1260,7 @@ public:
void CancelDiscovery() override
{
MOZ_ASSERT(NS_IsMainThread());
DispatchBluetoothReply(mRunnable, true, EmptyString());
DispatchReplySuccess(mRunnable);
}
void OnError(BluetoothStatus aStatus) override
@ -1552,7 +1530,7 @@ public:
void PinReply() override
{
DispatchBluetoothReply(mRunnable, BluetoothValue(true), EmptyString());
DispatchReplySuccess(mRunnable);
}
void OnError(BluetoothStatus aStatus) override
@ -1652,7 +1630,7 @@ public:
void SspReply() override
{
DispatchBluetoothReply(mRunnable, BluetoothValue(true), EmptyString());
DispatchReplySuccess(mRunnable);
}
void OnError(BluetoothStatus aStatus) override
@ -1785,10 +1763,10 @@ BluetoothServiceBluedroid::IsConnected(const uint16_t aServiceUuid,
BluetoothProfileManagerBase* profile =
BluetoothUuidHelper::GetBluetoothProfileManager(aServiceUuid);
if (profile) {
DispatchBluetoothReply(aRunnable, profile->IsConnected(), EmptyString());
DispatchReplySuccess(aRunnable, profile->IsConnected());
} else {
BT_WARNING("Can't find profile manager with uuid: %x", aServiceUuid);
DispatchBluetoothReply(aRunnable, false, EmptyString());
DispatchReplySuccess(aRunnable, false);
}
}
#endif
@ -1806,7 +1784,6 @@ BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
// has been determined when calling 'Connect()'. Nevertheless, keep
// it for future use.
#ifdef MOZ_B2G_BT_API_V2
BluetoothOppManager* opp = BluetoothOppManager::Get();
if (!opp || !opp->SendFile(aDeviceAddress, aBlobParent)) {
DispatchReplyError(aRunnable, NS_LITERAL_STRING("SendFile failed"));
@ -1814,15 +1791,6 @@ BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
}
DispatchReplySuccess(aRunnable);
#else
BluetoothOppManager* opp = BluetoothOppManager::Get();
nsAutoString errorStr;
if (!opp || !opp->SendFile(aDeviceAddress, aBlobParent)) {
errorStr.AssignLiteral("Calling SendFile() failed");
}
DispatchBluetoothReply(aRunnable, BluetoothValue(true), errorStr);
#endif
}
void
@ -1837,7 +1805,6 @@ BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
// has been determined when calling 'Connect()'. Nevertheless, keep
// it for future use.
#ifdef MOZ_B2G_BT_API_V2
BluetoothOppManager* opp = BluetoothOppManager::Get();
if (!opp || !opp->SendFile(aDeviceAddress, aBlob)) {
DispatchReplyError(aRunnable, NS_LITERAL_STRING("SendFile failed"));
@ -1845,15 +1812,6 @@ BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
}
DispatchReplySuccess(aRunnable);
#else
BluetoothOppManager* opp = BluetoothOppManager::Get();
nsAutoString errorStr;
if (!opp || !opp->SendFile(aDeviceAddress, aBlob)) {
errorStr.AssignLiteral("Calling SendFile() failed");
}
DispatchBluetoothReply(aRunnable, BluetoothValue(true), errorStr);
#endif
}
void
@ -1867,7 +1825,6 @@ BluetoothServiceBluedroid::StopSendingFile(const nsAString& aDeviceAddress,
// has been determined when calling 'Connect()'. Nevertheless, keep
// it for future use.
#ifdef MOZ_B2G_BT_API_V2
BluetoothOppManager* opp = BluetoothOppManager::Get();
nsAutoString errorStr;
if (!opp || !opp->StopSendingFile()) {
@ -1876,15 +1833,6 @@ BluetoothServiceBluedroid::StopSendingFile(const nsAString& aDeviceAddress,
}
DispatchReplySuccess(aRunnable);
#else
BluetoothOppManager* opp = BluetoothOppManager::Get();
nsAutoString errorStr;
if (!opp || !opp->StopSendingFile()) {
errorStr.AssignLiteral("Calling StopSendingFile() failed");
}
DispatchBluetoothReply(aRunnable, BluetoothValue(true), errorStr);
#endif
}
void
@ -1899,7 +1847,6 @@ BluetoothServiceBluedroid::ConfirmReceivingFile(
// has been determined when calling 'Connect()'. Nevertheless, keep
// it for future use.
#ifdef MOZ_B2G_BT_API_V2
BluetoothOppManager* opp = BluetoothOppManager::Get();
nsAutoString errorStr;
if (!opp || !opp->ConfirmReceivingFile(aConfirm)) {
@ -1909,15 +1856,6 @@ BluetoothServiceBluedroid::ConfirmReceivingFile(
}
DispatchReplySuccess(aRunnable);
#else
BluetoothOppManager* opp = BluetoothOppManager::Get();
nsAutoString errorStr;
if (!opp || !opp->ConfirmReceivingFile(aConfirm)) {
errorStr.AssignLiteral("Calling ConfirmReceivingFile() failed");
}
DispatchBluetoothReply(aRunnable, BluetoothValue(true), errorStr);
#endif
}
void
@ -1925,7 +1863,6 @@ BluetoothServiceBluedroid::ConnectSco(BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
#ifdef MOZ_B2G_BT_API_V2
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
if (!hfp || !hfp->ConnectSco()) {
DispatchReplyError(aRunnable, NS_LITERAL_STRING("ConnectSco failed"));
@ -1933,16 +1870,6 @@ BluetoothServiceBluedroid::ConnectSco(BluetoothReplyRunnable* aRunnable)
}
DispatchReplySuccess(aRunnable);
#else
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
if (!hfp || !hfp->ConnectSco()) {
NS_NAMED_LITERAL_STRING(replyError, "Calling ConnectSco() failed");
DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
return;
}
DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
#endif
}
void
@ -1950,7 +1877,6 @@ BluetoothServiceBluedroid::DisconnectSco(BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
#ifdef MOZ_B2G_BT_API_V2
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
if (!hfp || !hfp->DisconnectSco()) {
DispatchReplyError(aRunnable, NS_LITERAL_STRING("DisconnectSco failed"));
@ -1958,16 +1884,6 @@ BluetoothServiceBluedroid::DisconnectSco(BluetoothReplyRunnable* aRunnable)
}
DispatchReplySuccess(aRunnable);
#else
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
if (!hfp || !hfp->DisconnectSco()) {
NS_NAMED_LITERAL_STRING(replyError, "Calling DisconnectSco() failed");
DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
return;
}
DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
#endif
}
void
@ -1975,7 +1891,6 @@ BluetoothServiceBluedroid::IsScoConnected(BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
#ifdef MOZ_B2G_BT_API_V2
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
if (!hfp) {
DispatchReplyError(aRunnable, NS_LITERAL_STRING("IsScoConnected failed"));
@ -1983,16 +1898,6 @@ BluetoothServiceBluedroid::IsScoConnected(BluetoothReplyRunnable* aRunnable)
}
DispatchReplySuccess(aRunnable, BluetoothValue(hfp->IsScoConnected()));
#else
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
if (!hfp) {
NS_NAMED_LITERAL_STRING(replyError, "Fail to get BluetoothHfpManager");
DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
return;
}
DispatchBluetoothReply(aRunnable, hfp->IsScoConnected(), EmptyString());
#endif
}
void
@ -2009,11 +1914,7 @@ BluetoothServiceBluedroid::SendMetaData(const nsAString& aTitle,
a2dp->UpdateMetaData(aTitle, aArtist, aAlbum, aMediaNumber,
aTotalMediaCount, aDuration);
}
#ifdef MOZ_B2G_BT_API_V2
DispatchReplySuccess(aRunnable);
#else
DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
#endif
}
void
@ -2028,11 +1929,7 @@ BluetoothServiceBluedroid::SendPlayStatus(
PlayStatusStringToControlPlayStatus(aPlayStatus);
a2dp->UpdatePlayStatus(aDuration, aPosition, playStatus);
}
#ifdef MOZ_B2G_BT_API_V2
DispatchReplySuccess(aRunnable);
#else
DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
#endif
}
void
@ -2491,8 +2388,7 @@ BluetoothServiceBluedroid::AdapterPropertiesNotification(
// Send reply for SetProperty
if (!sSetPropertyRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sSetPropertyRunnableArray[0],
BluetoothValue(true), EmptyString());
DispatchReplySuccess(sSetPropertyRunnableArray[0]);
sSetPropertyRunnableArray.RemoveElementAt(0);
}
#endif
@ -2699,8 +2595,7 @@ BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
if (--sRequestedDeviceCountArray[0] == 0) {
if (!sGetDeviceRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sGetDeviceRunnableArray[0],
sRemoteDevicesPack, EmptyString());
DispatchReplySuccess(sGetDeviceRunnableArray[0], sRemoteDevicesPack);
sGetDeviceRunnableArray.RemoveElementAt(0);
}
@ -3066,13 +2961,11 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
BluetoothValue(propertiesChangeArray)));
if (bonded && !sBondingRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sBondingRunnableArray[0],
BluetoothValue(true), EmptyString());
DispatchReplySuccess(sBondingRunnableArray[0]);
sBondingRunnableArray.RemoveElementAt(0);
} else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sUnbondingRunnableArray[0],
BluetoothValue(true), EmptyString());
DispatchReplySuccess(sUnbondingRunnableArray[0]);
sUnbondingRunnableArray.RemoveElementAt(0);
}
@ -3098,9 +2991,8 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
BluetoothValue(propertiesArray)));
if (!sBondingRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sBondingRunnableArray[0],
BluetoothValue(true),
NS_LITERAL_STRING("Authentication failure"));
DispatchReplyError(sBondingRunnableArray[0],
NS_LITERAL_STRING("Authentication failure"));
sBondingRunnableArray.RemoveElementAt(0);
}
break;
@ -3109,9 +3001,8 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
BT_WARNING("Got an unhandled status of BondStateChangedCallback!");
// Dispatch a reply to unblock the waiting status of pairing.
if (!sBondingRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sBondingRunnableArray[0],
BluetoothValue(true),
NS_LITERAL_STRING("Internal failure"));
DispatchReplyError(sBondingRunnableArray[0],
NS_LITERAL_STRING("Internal failure"));
sBondingRunnableArray.RemoveElementAt(0);
}
break;

View File

@ -116,8 +116,7 @@ BluetoothProfileController::AddProfileWithServiceClass(
profile = BluetoothHidManager::Get();
break;
default:
DispatchBluetoothReply(mRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
mCallback();
return;
}
@ -130,8 +129,8 @@ BluetoothProfileController::AddProfile(BluetoothProfileManagerBase* aProfile,
bool aCheckConnected)
{
if (!aProfile) {
DispatchBluetoothReply(mRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
DispatchReplyError(mRunnable,
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
mCallback();
return;
}
@ -266,13 +265,11 @@ BluetoothProfileController::EndSession()
// The action has completed, so the DOM request should be replied then invoke
// the callback.
if (mSuccess) {
DispatchBluetoothReply(mRunnable, BluetoothValue(true), EmptyString());
DispatchReplySuccess(mRunnable);
} else if (mConnect) {
DispatchBluetoothReply(mRunnable, BluetoothValue(true),
NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
} else {
DispatchBluetoothReply(mRunnable, BluetoothValue(true),
NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
}
mCallback();

View File

@ -420,7 +420,6 @@ DispatchToBtThread(nsIRunnable* aRunnable)
return sBluetoothThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
}
#ifdef MOZ_B2G_BT_API_V2
static void
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
const BluetoothValue& aValue,
@ -432,9 +431,6 @@ DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
DispatchReplySuccess(aRunnable, aValue);
}
}
#else
// Missing in bluetooth1
#endif
BluetoothDBusService::BluetoothDBusService()
{
@ -4698,14 +4694,14 @@ BluetoothDBusService::UpdateNotification(ControlEventId aEventId,
void
BluetoothDBusService::StartLeScanInternal(
const nsTArray<nsString>& aServiceUuids,
BluetoothReplyRunnable* aRunnable);
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::StopLeScanInternal(
const nsAString& aAppUuid,
BluetoothReplyRunnable* aRunnable);
BluetoothReplyRunnable* aRunnable)
{
}

View File

@ -1916,12 +1916,7 @@ BluetoothHfpManager::OnScoConnectSuccess()
{
// For active connection request, we need to reply the DOMRequest
if (mScoRunnable) {
#ifdef MOZ_B2G_BT_API_V2
DispatchReplySuccess(mScoRunnable);
#else
DispatchBluetoothReply(mScoRunnable,
BluetoothValue(true), EmptyString());
#endif
mScoRunnable = nullptr;
}
@ -1935,13 +1930,8 @@ void
BluetoothHfpManager::OnScoConnectError()
{
if (mScoRunnable) {
#ifdef MOZ_B2G_BT_API_V2
DispatchReplyError(mScoRunnable,
NS_LITERAL_STRING("Failed to create SCO socket!"));
#else
NS_NAMED_LITERAL_STRING(replyError, "Failed to create SCO socket!");
DispatchBluetoothReply(mScoRunnable, BluetoothValue(), replyError);
#endif
mScoRunnable = nullptr;
}

View File

@ -30,11 +30,10 @@ class BluetoothSocket::BluetoothSocketIO final
public:
BluetoothSocketIO(MessageLoop* mIOLoop,
BluetoothSocket* aConsumer,
UnixSocketConnector* aConnector,
const nsACString& aAddress);
UnixSocketConnector* aConnector);
~BluetoothSocketIO();
void GetSocketAddr(nsAString& aAddrStr) const;
void GetSocketAddr(nsAString& aAddrStr) const;
BluetoothSocket* GetBluetoothSocket();
DataSocket* GetDataSocket();
@ -94,9 +93,6 @@ private:
void FireSocketError();
// Set up flags on file descriptor.
static bool SetSocketFlags(int aFd);
/**
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
* directly from main thread. All non-main-thread accesses should happen with
@ -115,19 +111,14 @@ private:
bool mShuttingDownOnIOThread;
/**
* Address we are connecting to, assuming we are creating a client connection.
* Number of valid bytes in |mAddress|
*/
nsCString mAddress;
socklen_t mAddressLength;
/**
* Size of the socket address struct
* Address structure of the socket currently in use
*/
socklen_t mAddrSize;
/**
* Address struct of the socket currently in use
*/
sockaddr_any mAddr;
struct sockaddr_storage mAddress;
/**
* Task member for delayed connect task. Should only be access on main thread.
@ -143,13 +134,12 @@ private:
BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
MessageLoop* mIOLoop,
BluetoothSocket* aConsumer,
UnixSocketConnector* aConnector,
const nsACString& aAddress)
UnixSocketConnector* aConnector)
: UnixSocketWatcher(mIOLoop)
, mConsumer(aConsumer)
, mConnector(aConnector)
, mShuttingDownOnIOThread(false)
, mAddress(aAddress)
, mAddressLength(0)
, mDelayedConnectTask(nullptr)
{
MOZ_ASSERT(mConsumer);
@ -170,7 +160,17 @@ BluetoothSocket::BluetoothSocketIO::GetSocketAddr(nsAString& aAddrStr) const
aAddrStr.Truncate();
return;
}
mConnector->GetSocketAddr(mAddr, aAddrStr);
nsCString addressString;
nsresult rv = mConnector->ConvertAddressToString(
*reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
addressString);
if (NS_FAILED(rv)) {
aAddrStr.Truncate();
return;
}
aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
}
BluetoothSocket*
@ -221,34 +221,20 @@ BluetoothSocket::BluetoothSocketIO::Listen()
MOZ_ASSERT(mConnector);
if (!IsOpen()) {
int fd = mConnector->Create();
if (fd < 0) {
NS_WARNING("Cannot create socket fd!");
FireSocketError();
return;
}
if (!SetSocketFlags(fd)) {
NS_WARNING("Cannot set socket flags!");
FireSocketError();
return;
}
if (!mConnector->SetUpListenSocket(fd)) {
NS_WARNING("Could not set up listen socket!");
FireSocketError();
return;
}
// This will set things we don't particularly care about, but it will hand
// back the correct structure size which is what we do care about.
if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) {
NS_WARNING("Cannot create socket address!");
mAddressLength = sizeof(mAddress);
int fd;
nsresult rv = mConnector->CreateListenSocket(
reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
if (NS_WARN_IF(NS_FAILED(rv))) {
FireSocketError();
return;
}
SetFd(fd);
// calls OnListening on success, or OnError otherwise
nsresult rv = UnixSocketWatcher::Listen(
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
rv = UnixSocketWatcher::Listen(
reinterpret_cast<struct sockaddr*>(&mAddress), mAddressLength);
NS_WARN_IF(NS_FAILED(rv));
}
}
@ -260,24 +246,12 @@ BluetoothSocket::BluetoothSocketIO::Connect()
MOZ_ASSERT(mConnector);
if (!IsOpen()) {
int fd = mConnector->Create();
if (fd < 0) {
NS_WARNING("Cannot create socket fd!");
FireSocketError();
return;
}
if (!SetSocketFlags(fd)) {
NS_WARNING("Cannot set socket flags!");
FireSocketError();
return;
}
if (!mConnector->SetUp(fd)) {
NS_WARNING("Could not set up socket!");
FireSocketError();
return;
}
if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
NS_WARNING("Cannot create socket address!");
mAddressLength = sizeof(mAddress);
int fd;
nsresult rv = mConnector->CreateStreamSocket(
reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
if (NS_WARN_IF(NS_FAILED(rv))) {
FireSocketError();
return;
}
@ -286,7 +260,7 @@ BluetoothSocket::BluetoothSocketIO::Connect()
// calls OnConnected() on success, or OnError() otherwise
nsresult rv = UnixSocketWatcher::Connect(
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
reinterpret_cast<struct sockaddr*>(&mAddress), mAddressLength);
NS_WARN_IF(NS_FAILED(rv));
}
@ -338,18 +312,14 @@ BluetoothSocket::BluetoothSocketIO::OnSocketCanAcceptWithoutBlocking()
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
socklen_t mAddrSize = sizeof(mAddr);
int fd = TEMP_FAILURE_RETRY(accept(GetFd(),
reinterpret_cast<struct sockaddr*>(&mAddr), &mAddrSize));
if (fd < 0) {
OnError("accept", errno);
return;
}
if (!SetSocketFlags(fd)) {
return;
}
if (!mConnector->SetUp(fd)) {
NS_WARNING("Could not set up socket!");
mAddressLength = sizeof(mAddress);
int fd;
nsresult rv = mConnector->AcceptStreamSocket(
GetFd(),
reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
if (NS_WARN_IF(NS_FAILED(rv))) {
FireSocketError();
return;
}
@ -411,38 +381,6 @@ BluetoothSocket::BluetoothSocketIO::FireSocketError()
}
bool
BluetoothSocket::BluetoothSocketIO::SetSocketFlags(int aFd)
{
// Set socket addr to be reused even if kernel is still waiting to close
int n = 1;
if (setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) {
return false;
}
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (-1 == flags) {
return false;
}
flags |= FD_CLOEXEC;
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
return false;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (-1 == flags) {
return false;
}
flags |= O_NONBLOCK;
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
return false;
}
return true;
}
// |DataSocketIO|
nsresult
@ -646,7 +584,8 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress,
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
nsAutoPtr<BluetoothUnixSocketConnector> c(
new BluetoothUnixSocketConnector(mType, aChannel, mAuth, mEncrypt));
new BluetoothUnixSocketConnector(NS_ConvertUTF16toUTF8(aDeviceAddress),
mType, aChannel, mAuth, mEncrypt));
if (!ConnectSocket(c.forget(),
NS_ConvertUTF16toUTF8(aDeviceAddress).BeginReading())) {
@ -668,7 +607,8 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
MOZ_ASSERT(NS_IsMainThread());
nsAutoPtr<BluetoothUnixSocketConnector> c(
new BluetoothUnixSocketConnector(mType, aChannel, mAuth, mEncrypt));
new BluetoothUnixSocketConnector(NS_LITERAL_CSTRING(BLUETOOTH_ADDRESS_NONE),
mType, aChannel, mAuth, mEncrypt));
if (!ListenSocket(c.forget())) {
nsAutoString addr;
@ -728,9 +668,8 @@ BluetoothSocket::ConnectSocket(BluetoothUnixSocketConnector* aConnector,
return false;
}
nsCString addr(aAddress);
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
mIO = new BluetoothSocketIO(ioLoop, this, connector.forget(), addr);
mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
@ -755,10 +694,12 @@ BluetoothSocket::ListenSocket(BluetoothUnixSocketConnector* aConnector)
return false;
}
mIO = new BluetoothSocketIO(
XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
SetConnectionStatus(SOCKET_LISTENING);
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO));
ioLoop->PostTask(FROM_HERE, new ListenTask(mIO));
return true;
}

View File

@ -1,5 +1,6 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*
* Copyright 2009, The Android Open Source Project
*
@ -15,123 +16,175 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* NOTE: Due to being based on the dbus compatibility layer for
* android's bluetooth implementation, this file is licensed under the
* apache license instead of MPL.
*
* NOTE: Due to being based on the D-Bus compatibility layer for
* Android's Bluetooth implementation, this file is licensed under the
* Apache License instead of MPL.
*/
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#ifdef MOZ_B2G_BT_BLUEZ
#include "BluetoothUnixSocketConnector.h"
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sco.h>
#endif
#include "BluetoothUnixSocketConnector.h"
#include "nsThreadUtils.h"
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include "nsThreadUtils.h" // For NS_IsMainThread.
using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE
BEGIN_BLUETOOTH_NAMESPACE
static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
static const int L2CAP_SO_SNDBUF = 400 * 1024; // 400 KB send buffer
static const int L2CAP_SO_RCVBUF = 400 * 1024; // 400 KB receive buffer
static const int L2CAP_MAX_MTU = 65000;
#ifdef MOZ_B2G_BT_BLUEZ
static
int get_bdaddr(const char *str, bdaddr_t *ba)
{
char *d = ((char*)ba) + 5, *endp;
for (int i = 0; i < 6; i++) {
*d-- = strtol(str, &endp, 16);
MOZ_ASSERT(!(*endp != ':' && i != 5));
str = endp + 1;
}
return 0;
}
static
void get_bdaddr_as_string(const bdaddr_t *ba, char *str) {
const uint8_t *b = (const uint8_t *)ba;
sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
b[5], b[4], b[3], b[2], b[1], b[0]);
}
#endif
BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
const nsACString& aAddressString,
BluetoothSocketType aType,
int aChannel,
bool aAuth,
bool aEncrypt) : mType(aType)
, mChannel(aChannel)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
bool aEncrypt)
: mAddressString(aAddressString)
, mType(aType)
, mChannel(aChannel)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
{ }
BluetoothUnixSocketConnector::~BluetoothUnixSocketConnector()
{ }
nsresult
BluetoothUnixSocketConnector::CreateSocket(int& aFd) const
{
static const int sType[] = {
[0] = 0,
[BluetoothSocketType::RFCOMM] = SOCK_STREAM,
[BluetoothSocketType::SCO] = SOCK_SEQPACKET,
[BluetoothSocketType::L2CAP] = SOCK_SEQPACKET,
[BluetoothSocketType::EL2CAP] = SOCK_STREAM
};
static const int sProtocol[] = {
[0] = 0,
[BluetoothSocketType::RFCOMM] = BTPROTO_RFCOMM,
[BluetoothSocketType::SCO] = BTPROTO_SCO,
[BluetoothSocketType::L2CAP] = BTPROTO_L2CAP,
[BluetoothSocketType::EL2CAP] = BTPROTO_L2CAP
};
MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sType));
MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sProtocol));
aFd = socket(AF_BLUETOOTH, sType[mType], sProtocol[mType]);
if (aFd < 0) {
BT_LOGR("Could not open Bluetooth socket!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
bool
BluetoothUnixSocketConnector::SetUp(int aFd)
nsresult
BluetoothUnixSocketConnector::SetSocketFlags(int aFd) const
{
#ifdef MOZ_B2G_BT_BLUEZ
int lm = 0;
int sndbuf, rcvbuf;
static const int sReuseAddress = 1;
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= FD_CLOEXEC;
int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= O_NONBLOCK;
res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set socket addr to be reused even if kernel is still waiting to close.
res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
sizeof(sReuseAddress));
if (res < 0) {
return NS_ERROR_FAILURE;
}
int lm;
/* kernel does not yet support LM for SCO */
switch (mType) {
case BluetoothSocketType::RFCOMM:
lm |= mAuth ? RFCOMM_LM_AUTH : 0;
lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0;
break;
case BluetoothSocketType::L2CAP:
case BluetoothSocketType::EL2CAP:
lm |= mAuth ? L2CAP_LM_AUTH : 0;
lm |= mEncrypt ? L2CAP_LM_ENCRYPT : 0;
break;
case BluetoothSocketType::SCO:
break;
default:
MOZ_CRASH("Unknown socket type!");
case BluetoothSocketType::RFCOMM:
lm |= mAuth ? RFCOMM_LM_AUTH : 0;
lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0;
break;
case BluetoothSocketType::L2CAP:
case BluetoothSocketType::EL2CAP:
lm |= mAuth ? L2CAP_LM_AUTH : 0;
lm |= mEncrypt ? L2CAP_LM_ENCRYPT : 0;
break;
default:
// kernel does not yet support LM for SCO
lm = 0;
break;
}
if (lm) {
if (mType == BluetoothSocketType::RFCOMM) {
if (setsockopt(aFd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
BT_WARNING("setsockopt(RFCOMM_LM) failed, throwing");
return false;
}
} else if (mType == BluetoothSocketType::L2CAP ||
mType == BluetoothSocketType::EL2CAP) {
if (setsockopt(aFd, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm))) {
BT_WARNING("setsockopt(L2CAP_LM) failed, throwing");
return false;
}
static const int sLevel[] = {
[0] = 0,
[BluetoothSocketType::RFCOMM] = SOL_RFCOMM,
[BluetoothSocketType::SCO] = 0,
[BluetoothSocketType::L2CAP] = SOL_L2CAP,
[BluetoothSocketType::EL2CAP] = SOL_L2CAP
};
static const int sOptname[] = {
[0] = 0,
[BluetoothSocketType::RFCOMM] = RFCOMM_LM,
[BluetoothSocketType::SCO] = 0,
[BluetoothSocketType::L2CAP] = L2CAP_LM,
[BluetoothSocketType::EL2CAP] = L2CAP_LM
};
MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sLevel));
MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sOptname));
if (setsockopt(aFd, sLevel[mType], sOptname[mType], &lm, sizeof(lm)) < 0) {
BT_LOGR("setsockopt(RFCOMM_LM) failed, throwing");
return NS_ERROR_FAILURE;
}
}
if (mType == BluetoothSocketType::RFCOMM) {
sndbuf = RFCOMM_SO_SNDBUF;
/* Setting RFCOMM socket options */
int sndbuf = RFCOMM_SO_SNDBUF;
if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
BT_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
return false;
return NS_ERROR_FAILURE;
}
}
/* Setting L2CAP socket options */
if (mType == BluetoothSocketType::L2CAP ||
mType == BluetoothSocketType::EL2CAP) {
/* Setting L2CAP/EL2CAP socket options */
struct l2cap_options opts;
socklen_t optlen = sizeof(opts);
int err;
err = getsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen);
if (!err) {
int res = getsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen);
if (!res) {
/* setting MTU for [E]L2CAP */
opts.omtu = opts.imtu = L2CAP_MAX_MTU;
@ -144,142 +197,215 @@ BluetoothUnixSocketConnector::SetUp(int aFd)
opts.max_tx = 10;
}
err = setsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen);
setsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen);
}
/* Set larger SNDBUF & RCVBUF for EL2CAP connections */
if (mType == BluetoothSocketType::EL2CAP) {
sndbuf = L2CAP_SO_SNDBUF;
if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
BT_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
return false;
/* Set larger SNDBUF and RCVBUF for EL2CAP connections */
int sndbuf = L2CAP_SO_SNDBUF;
if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
BT_LOGR("setsockopt(SO_SNDBUF) failed, throwing");
return NS_ERROR_FAILURE;
}
rcvbuf = L2CAP_SO_RCVBUF;
if (setsockopt(aFd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf))) {
BT_WARNING("setsockopt(SO_RCVBUF) failed, throwing");
return false;
int rcvbuf = L2CAP_SO_RCVBUF;
if (setsockopt(aFd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) {
BT_LOGR("setsockopt(SO_RCVBUF) failed, throwing");
return NS_ERROR_FAILURE;
}
}
}
#endif
return true;
return NS_OK;
}
bool
BluetoothUnixSocketConnector::SetUpListenSocket(int aFd)
nsresult
BluetoothUnixSocketConnector::CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const
{
// Nothing to do here.
return true;
}
int
BluetoothUnixSocketConnector::Create()
{
MOZ_ASSERT(!NS_IsMainThread());
int fd = -1;
#ifdef MOZ_B2G_BT_BLUEZ
switch (mType) {
case BluetoothSocketType::RFCOMM:
fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
break;
case BluetoothSocketType::SCO:
fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
break;
case BluetoothSocketType::L2CAP:
fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
break;
case BluetoothSocketType::EL2CAP:
fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP);
break;
default:
MOZ_CRASH();
case BluetoothSocketType::RFCOMM: {
struct sockaddr_rc* rc =
reinterpret_cast<struct sockaddr_rc*>(&aAddress);
rc->rc_family = AF_BLUETOOTH;
nsresult rv = ConvertAddressString(mAddressString.get(),
rc->rc_bdaddr);
if (NS_FAILED(rv)) {
return rv;
}
rc->rc_channel = mChannel;
aAddressLength = sizeof(*rc);
}
break;
case BluetoothSocketType::L2CAP:
case BluetoothSocketType::EL2CAP: {
struct sockaddr_l2* l2 =
reinterpret_cast<struct sockaddr_l2*>(&aAddress);
l2->l2_family = AF_BLUETOOTH;
l2->l2_psm = mChannel;
nsresult rv = ConvertAddressString(mAddressString.get(),
l2->l2_bdaddr);
if (NS_FAILED(rv)) {
return rv;
}
l2->l2_cid = 0;
aAddressLength = sizeof(*l2);
}
break;
case BluetoothSocketType::SCO: {
struct sockaddr_sco* sco =
reinterpret_cast<struct sockaddr_sco*>(&aAddress);
sco->sco_family = AF_BLUETOOTH;
nsresult rv = ConvertAddressString(mAddressString.get(),
sco->sco_bdaddr);
if (NS_FAILED(rv)) {
return rv;
}
sco->sco_pkt_type = 0;
aAddressLength = sizeof(*sco);
}
break;
default:
MOZ_CRASH("Socket type unknown!");
return NS_ERROR_ABORT;
}
return NS_OK;
}
nsresult
BluetoothUnixSocketConnector::ConvertAddressString(const char* aAddressString,
bdaddr_t& aAddress)
{
char* d = reinterpret_cast<char*>(aAddress.b) + 5;
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aAddress.b); ++i) {
char* endp;
*d-- = strtoul(aAddressString, &endp, 16);
MOZ_ASSERT(!(*endp != ':' && i != 5));
aAddressString = endp + 1;
}
return NS_OK;
}
// |UnixSocketConnector|
nsresult
BluetoothUnixSocketConnector::ConvertAddressToString(
const struct sockaddr& aAddress, socklen_t aAddressLength,
nsACString& aAddressString)
{
MOZ_ASSERT(aAddress.sa_family == AF_BLUETOOTH);
const uint8_t* b;
switch (mType) {
case BluetoothSocketType::RFCOMM: {
const struct sockaddr_rc* rc =
reinterpret_cast<const struct sockaddr_rc*>(&aAddress);
b = rc->rc_bdaddr.b;
}
break;
case BluetoothSocketType::SCO: {
const struct sockaddr_sco* sco =
reinterpret_cast<const struct sockaddr_sco*>(&aAddress);
b = sco->sco_bdaddr.b;
}
break;
case BluetoothSocketType::L2CAP:
case BluetoothSocketType::EL2CAP: {
const struct sockaddr_l2* l2 =
reinterpret_cast<const struct sockaddr_l2*>(&aAddress);
b = l2->l2_bdaddr.b;
}
break;
}
char str[32];
snprintf(str, sizeof(str), "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
b[5], b[4], b[3], b[2], b[1], b[0]);
aAddressString.Assign(str);
return NS_OK;
}
nsresult
BluetoothUnixSocketConnector::CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd)
{
ScopedClose fd;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
aListenFd = fd.forget();
return NS_OK;
}
nsresult
BluetoothUnixSocketConnector::AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
ScopedClose fd(
TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
if (fd < 0) {
BT_WARNING("Could not open bluetooth socket!");
return -1;
NS_WARNING("Cannot accept file descriptor!");
return NS_ERROR_FAILURE;
}
nsresult rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (!SetUp(fd)) {
BT_WARNING("Could not set up socket!");
return -1;
}
#endif
return fd;
aStreamFd = fd.forget();
return NS_OK;
}
bool
BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress)
nsresult
BluetoothUnixSocketConnector::CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
#ifdef MOZ_B2G_BT_BLUEZ
// Set to BDADDR_ANY, if it's not a server, we'll reset.
bdaddr_t bd_address_obj = {{0, 0, 0, 0, 0, 0}};
ScopedClose fd;
if (!aIsServer && aAddress && strlen(aAddress) > 0) {
if (get_bdaddr(aAddress, &bd_address_obj)) {
BT_WARNING("Can't get bluetooth address!");
return false;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
// Initialize
memset(&aAddr, 0, sizeof(aAddr));
aStreamFd = fd.forget();
switch (mType) {
case BluetoothSocketType::RFCOMM:
struct sockaddr_rc addr_rc;
aAddrSize = sizeof(addr_rc);
aAddr.rc.rc_family = AF_BLUETOOTH;
aAddr.rc.rc_channel = mChannel;
memcpy(&aAddr.rc.rc_bdaddr, &bd_address_obj, sizeof(bd_address_obj));
break;
case BluetoothSocketType::L2CAP:
case BluetoothSocketType::EL2CAP:
struct sockaddr_l2 addr_l2;
aAddrSize = sizeof(addr_l2);
aAddr.l2.l2_family = AF_BLUETOOTH;
aAddr.l2.l2_psm = mChannel;
memcpy(&aAddr.l2.l2_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
break;
case BluetoothSocketType::SCO:
struct sockaddr_sco addr_sco;
aAddrSize = sizeof(addr_sco);
aAddr.sco.sco_family = AF_BLUETOOTH;
memcpy(&aAddr.sco.sco_bdaddr, &bd_address_obj, sizeof(bd_address_obj));
break;
default:
BT_WARNING("Socket type unknown!");
return false;
}
#endif
return true;
return NS_OK;
}
void
BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr)
{
#ifdef MOZ_B2G_BT_BLUEZ
char addr[18];
switch (mType) {
case BluetoothSocketType::RFCOMM:
get_bdaddr_as_string((bdaddr_t*)(&aAddr.rc.rc_bdaddr), addr);
break;
case BluetoothSocketType::SCO:
get_bdaddr_as_string((bdaddr_t*)(&aAddr.sco.sco_bdaddr), addr);
break;
case BluetoothSocketType::L2CAP:
case BluetoothSocketType::EL2CAP:
get_bdaddr_as_string((bdaddr_t*)(&aAddr.l2.l2_bdaddr), addr);
break;
default:
MOZ_CRASH("Socket should be either RFCOMM or SCO!");
}
aAddrStr.AssignASCII(addr);
#endif
}
END_BLUETOOTH_NAMESPACE

View File

@ -8,29 +8,48 @@
#define mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
#include "BluetoothCommon.h"
#include <sys/socket.h>
#include <mozilla/ipc/UnixSocketConnector.h>
#include "mozilla/ipc/UnixSocketConnector.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothUnixSocketConnector : public mozilla::ipc::UnixSocketConnector
class BluetoothUnixSocketConnector final
: public mozilla::ipc::UnixSocketConnector
{
public:
BluetoothUnixSocketConnector(BluetoothSocketType aType, int aChannel,
bool aAuth, bool aEncrypt);
virtual ~BluetoothUnixSocketConnector()
{}
virtual int Create() override;
virtual bool CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
mozilla::ipc::sockaddr_any& aAddr,
const char* aAddress) override;
virtual bool SetUp(int aFd) override;
virtual bool SetUpListenSocket(int aFd) override;
virtual void GetSocketAddr(const mozilla::ipc::sockaddr_any& aAddr,
nsAString& aAddrStr) override;
BluetoothUnixSocketConnector(const nsACString& aAddressString,
BluetoothSocketType aType,
int aChannel, bool aAuth, bool aEncrypt);
~BluetoothUnixSocketConnector();
// Methods for |UnixSocketConnector|
//
nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) override;
nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) override;
nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLen,
int& aStreamFd) override;
nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
private:
nsresult CreateSocket(int& aFd) const;
nsresult SetSocketFlags(int aFd) const;
nsresult CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const;
static nsresult ConvertAddressString(const char* aAddressString,
bdaddr_t& aAddress);
nsCString mAddressString;
BluetoothSocketType mType;
int mChannel;
bool mAuth;

View File

@ -94,6 +94,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluedroid/BluetoothAvrcpHALInterface.cpp',
'bluedroid/BluetoothDaemonA2dpInterface.cpp',
'bluedroid/BluetoothDaemonAvrcpInterface.cpp',
'bluedroid/BluetoothDaemonConnector.cpp',
'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
'bluedroid/BluetoothDaemonHelpers.cpp',
'bluedroid/BluetoothDaemonInterface.cpp',

View File

@ -12,6 +12,7 @@
#include "mozilla/dom/NfcOptionsBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/RootedDictionary.h"
#include "mozilla/ipc/NfcConnector.h"
#include "mozilla/unused.h"
#include "nsAutoPtr.h"
#include "nsString.h"
@ -312,7 +313,8 @@ NfcService::Start(nsINfcGonkEventListener* aListener)
mListenSocket = new NfcListenSocket(this);
bool success = mListenSocket->Listen(new NfcConnector(), mConsumer);
bool success = mListenSocket->Listen(new NfcConnector(mListenSocketName),
mConsumer);
if (!success) {
mConsumer = nullptr;
return NS_ERROR_FAILURE;

View File

@ -31,7 +31,7 @@ The above merge way ensures the correct scope of 'strict mode.'
"""
from marionette_test import MarionetteTestCase
from marionette.marionette_test import MarionetteTestCase
import bisect
import inspect
import os

View File

@ -19,6 +19,7 @@
#include "KeyStore.h"
#include "jsfriendapi.h"
#include "KeyStoreConnector.h"
#include "MainThreadUtils.h" // For NS_IsMainThread.
#include "nsICryptoHash.h"
@ -304,7 +305,6 @@ static const char *CA_BEGIN = "-----BEGIN ",
namespace mozilla {
namespace ipc {
static const char* KEYSTORE_SOCKET_PATH = "/dev/socket/keystore";
static const char* KEYSTORE_ALLOWED_USERS[] = {
"root",
"wifi",
@ -672,76 +672,6 @@ checkPermission(uid_t uid)
return false;
}
int
KeyStoreConnector::Create()
{
MOZ_ASSERT(!NS_IsMainThread());
int fd;
unlink(KEYSTORE_SOCKET_PATH);
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (fd < 0) {
NS_WARNING("Could not open keystore socket!");
return -1;
}
return fd;
}
bool
KeyStoreConnector::CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress)
{
// Keystore socket must be server
MOZ_ASSERT(aIsServer);
aAddr.un.sun_family = AF_LOCAL;
if(strlen(KEYSTORE_SOCKET_PATH) > sizeof(aAddr.un.sun_path)) {
NS_WARNING("Address too long for socket struct!");
return false;
}
strcpy((char*)&aAddr.un.sun_path, KEYSTORE_SOCKET_PATH);
aAddrSize = strlen(KEYSTORE_SOCKET_PATH) + offsetof(struct sockaddr_un, sun_path) + 1;
return true;
}
bool
KeyStoreConnector::SetUp(int aFd)
{
// Socket permission check.
struct ucred userCred;
socklen_t len = sizeof(struct ucred);
if (getsockopt(aFd, SOL_SOCKET, SO_PEERCRED, &userCred, &len)) {
return false;
}
return ::checkPermission(userCred.uid);
}
bool
KeyStoreConnector::SetUpListenSocket(int aFd)
{
// Allow access of wpa_supplicant(different user, differnt group)
chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
return true;
}
void
KeyStoreConnector::GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr)
{
// Unused.
MOZ_CRASH("This should never be called!");
}
//
// KeyStore::ListenSocket
//
@ -818,7 +748,7 @@ KeyStore::StreamSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
ConnectionOrientedSocketIO*
KeyStore::StreamSocket::GetIO()
{
return PrepareAccept(new KeyStoreConnector());
return PrepareAccept(new KeyStoreConnector(KEYSTORE_ALLOWED_USERS));
}
//
@ -877,7 +807,8 @@ KeyStore::Listen()
if (!mListenSocket) {
// We only ever allocate one |ListenSocket|...
mListenSocket = new ListenSocket(this);
mListenSocket->Listen(new KeyStoreConnector(), mStreamSocket);
mListenSocket->Listen(new KeyStoreConnector(KEYSTORE_ALLOWED_USERS),
mStreamSocket);
} else {
// ... but keep it open.
mListenSocket->Listen(mStreamSocket);

View File

@ -12,7 +12,6 @@
#include "cert.h"
#include "mozilla/ipc/ListenSocket.h"
#include "mozilla/ipc/StreamSocket.h"
#include "mozilla/ipc/UnixSocketConnector.h"
#include "nsNSSShutDown.h"
namespace mozilla {
@ -79,26 +78,6 @@ typedef enum {
STATE_PROCESSING
} ProtocolHandlerState;
class KeyStoreConnector : public mozilla::ipc::UnixSocketConnector
{
public:
KeyStoreConnector()
{}
virtual ~KeyStoreConnector()
{}
virtual int Create();
virtual bool CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress);
virtual bool SetUp(int aFd);
virtual bool SetUpListenSocket(int aFd);
virtual void GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr);
};
class KeyStore final : public nsNSSShutDownObject
{
public:

View File

@ -0,0 +1,226 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et ft=cpp: tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "KeyStoreConnector.h"
#include <fcntl.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/un.h>
#include "nsThreadUtils.h" // For NS_IsMainThread.
#ifdef MOZ_WIDGET_GONK
#include <android/log.h>
#define KEYSTORE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
#else
#define KEYSTORE_LOG(args...) printf(args);
#endif
namespace mozilla {
namespace ipc {
static const char KEYSTORE_SOCKET_PATH[] = "/dev/socket/keystore";
KeyStoreConnector::KeyStoreConnector(const char** const aAllowedUsers)
: mAllowedUsers(aAllowedUsers)
{ }
KeyStoreConnector::~KeyStoreConnector()
{ }
nsresult
KeyStoreConnector::CreateSocket(int& aFd) const
{
unlink(KEYSTORE_SOCKET_PATH);
aFd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (aFd < 0) {
KEYSTORE_LOG("Could not open KeyStore socket!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
KeyStoreConnector::SetSocketFlags(int aFd) const
{
static const int sReuseAddress = 1;
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= FD_CLOEXEC;
int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= O_NONBLOCK;
res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set socket addr to be reused even if kernel is still waiting to close.
res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
sizeof(sReuseAddress));
if (res < 0) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
KeyStoreConnector::CheckPermission(int aFd) const
{
struct ucred userCred;
socklen_t len = sizeof(userCred);
if (getsockopt(aFd, SOL_SOCKET, SO_PEERCRED, &userCred, &len)) {
return NS_ERROR_FAILURE;
}
const struct passwd* userInfo = getpwuid(userCred.uid);
if (!userInfo) {
return NS_ERROR_FAILURE;
}
if (!mAllowedUsers) {
return NS_ERROR_FAILURE;
}
for (const char** user = mAllowedUsers; *user; ++user) {
if (!strcmp(*user, userInfo->pw_name)) {
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
nsresult
KeyStoreConnector::CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const
{
struct sockaddr_un* address =
reinterpret_cast<struct sockaddr_un*>(&aAddress);
size_t namesiz = strlen(KEYSTORE_SOCKET_PATH) + 1; // include trailing '\0'
if (namesiz > sizeof(address->sun_path)) {
KEYSTORE_LOG("Address too long for socket struct!");
return NS_ERROR_FAILURE;
}
address->sun_family = AF_UNIX;
memcpy(address->sun_path, KEYSTORE_SOCKET_PATH, namesiz);
aAddressLength = offsetof(struct sockaddr_un, sun_path) + namesiz;
return NS_OK;
}
// |UnixSocketConnector|
nsresult
KeyStoreConnector::ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString)
{
MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
const struct sockaddr_un* un =
reinterpret_cast<const struct sockaddr_un*>(&aAddress);
size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
aAddressString.Assign(un->sun_path, len);
return NS_OK;
}
nsresult
KeyStoreConnector::CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd)
{
ScopedClose fd;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
// Allow access for wpa_supplicant (different user, different group)
//
// TODO: Improve this by setting specific user/group for
// wpa_supplicant by calling |fchmod| and |fchown|.
//
chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR|
S_IRGRP|S_IWGRP|
S_IROTH|S_IWOTH);
aListenFd = fd.forget();
return NS_OK;
}
nsresult
KeyStoreConnector::AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
ScopedClose fd(
TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
if (fd < 0) {
NS_WARNING("Cannot accept file descriptor!");
return NS_ERROR_FAILURE;
}
nsresult rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
rv = CheckPermission(fd);
if (NS_FAILED(rv)) {
return rv;
}
aStreamFd = fd.forget();
return NS_OK;
}
nsresult
KeyStoreConnector::CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
MOZ_CRASH("|KeyStoreConnector| does not support creating stream sockets.");
return NS_ERROR_FAILURE;
}
}
}

View File

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et ft=cpp: tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_KeyStoreConnector_h
#define mozilla_ipc_KeyStoreConnector_h
#include "mozilla/ipc/UnixSocketConnector.h"
namespace mozilla {
namespace ipc {
class KeyStoreConnector final : public UnixSocketConnector
{
public:
KeyStoreConnector(const char** const aAllowedUsers);
~KeyStoreConnector();
// Methods for |UnixSocketConnector|
//
nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) override;
nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) override;
nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
private:
nsresult CreateSocket(int& aFd) const;
nsresult SetSocketFlags(int aFd) const;
nsresult CheckPermission(int aFd) const;
nsresult CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const;
const char** const mAllowedUsers;
};
}
}
#endif

View File

@ -9,7 +9,8 @@ EXPORTS.mozilla.ipc += [
]
SOURCES += [
'KeyStore.cpp'
'KeyStore.cpp',
'KeyStoreConnector.cpp'
]
FAIL_ON_WARNINGS = True

View File

@ -22,6 +22,7 @@
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/ipc/NfcConnector.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
using namespace mozilla::ipc;
@ -60,74 +61,6 @@ private:
namespace mozilla {
namespace ipc {
//
// NfcConnector
//
int
NfcConnector::Create()
{
MOZ_ASSERT(!NS_IsMainThread());
int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (fd < 0) {
NS_WARNING("Could not open nfc socket!");
return -1;
}
if (!SetUp(fd)) {
NS_WARNING("Could not set up socket!");
}
return fd;
}
bool
NfcConnector::CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress)
{
static const size_t sNameOffset = 1;
nsDependentCString socketName("nfcd");
size_t namesiz = socketName.Length() + 1; /* include trailing '\0' */
if ((sNameOffset + namesiz) > sizeof(aAddr.un.sun_path)) {
NS_WARNING("Address too long for socket struct!");
return false;
}
memset(aAddr.un.sun_path, '\0', sNameOffset); // abstract socket
memcpy(aAddr.un.sun_path + sNameOffset, socketName.get(), namesiz);
aAddr.un.sun_family = AF_UNIX;
aAddrSize = offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
return true;
}
bool
NfcConnector::SetUp(int aFd)
{
// Nothing to do here.
return true;
}
bool
NfcConnector::SetUpListenSocket(int aFd)
{
// Nothing to do here.
return true;
}
void
NfcConnector::GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr)
{
MOZ_CRASH("This should never be called!");
}
//
// NfcListenSocket
//
@ -231,7 +164,7 @@ NfcConsumer::OnDisconnect()
ConnectionOrientedSocketIO*
NfcConsumer::GetIO()
{
return PrepareAccept(new NfcConnector());
return PrepareAccept(new NfcConnector(NS_LITERAL_CSTRING("nfcd")));
}
} // namespace ipc

View File

@ -11,7 +11,6 @@
#include <mozilla/ipc/ListenSocket.h>
#include <mozilla/ipc/StreamSocket.h>
#include <mozilla/ipc/UnixSocketConnector.h>
namespace mozilla {
namespace ipc {
@ -44,23 +43,6 @@ private:
NfcSocketListener* mListener;
};
class NfcConnector final : public mozilla::ipc::UnixSocketConnector
{
public:
NfcConnector()
{ }
int Create() override;
bool CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress) override;
bool SetUp(int aFd) override;
bool SetUpListenSocket(int aFd) override;
void GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr) override;
};
class NfcConsumer final : public mozilla::ipc::StreamSocket
{
public:

194
ipc/nfc/NfcConnector.cpp Normal file
View File

@ -0,0 +1,194 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=2 ts=8 et ft=cpp: */
/* 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 "NfcConnector.h"
#include <fcntl.h>
#include <sys/un.h>
#include "nsThreadUtils.h" // For NS_IsMainThread.
namespace mozilla {
namespace ipc {
NfcConnector::NfcConnector(const nsACString& aAddressString)
: mAddressString(aAddressString)
{ }
NfcConnector::~NfcConnector()
{ }
nsresult
NfcConnector::CreateSocket(int& aFd) const
{
aFd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (aFd < 0) {
NS_WARNING("Could not open NFC socket!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
NfcConnector::SetSocketFlags(int aFd) const
{
static const int sReuseAddress = 1;
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= FD_CLOEXEC;
int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= O_NONBLOCK;
res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set socket addr to be reused even if kernel is still waiting to close.
res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
sizeof(sReuseAddress));
if (res < 0) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
NfcConnector::CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const
{
static const size_t sNameOffset = 1;
struct sockaddr_un* address =
reinterpret_cast<struct sockaddr_un*>(&aAddress);
size_t namesiz = mAddressString.Length() + 1; // include trailing '\0'
if (NS_WARN_IF((sNameOffset + namesiz) > sizeof(address->sun_path))) {
return NS_ERROR_FAILURE;
}
address->sun_family = AF_UNIX;
memset(address->sun_path, '\0', sNameOffset); // abstract socket
memcpy(address->sun_path + sNameOffset, mAddressString.get(), namesiz);
aAddressLength =
offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
return NS_OK;
}
// |UnixSocketConnector|
//
nsresult
NfcConnector::ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString)
{
MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
const struct sockaddr_un* un =
reinterpret_cast<const struct sockaddr_un*>(&aAddress);
size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
aAddressString.Assign(un->sun_path, len);
return NS_OK;
}
nsresult
NfcConnector::CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd)
{
ScopedClose fd;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
aListenFd = fd.forget();
return NS_OK;
}
nsresult
NfcConnector::AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
ScopedClose fd(
TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
if (fd < 0) {
NS_WARNING("Cannot accept file descriptor!");
return NS_ERROR_FAILURE;
}
nsresult rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
aStreamFd = fd.forget();
return NS_OK;
}
nsresult
NfcConnector::CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
ScopedClose fd;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
aStreamFd = fd.forget();
return NS_OK;
}
}
}

58
ipc/nfc/NfcConnector.h Normal file
View File

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=2 ts=8 et ft=cpp: */
/* 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_ipc_NfcConnector_h
#define mozilla_ipc_NfcConnector_h
#include "mozilla/ipc/UnixSocketConnector.h"
namespace mozilla {
namespace ipc {
/**
* |NfcConnector| creates sockets for communicating with
* the NFC daemon.
*/
class NfcConnector final : public UnixSocketConnector
{
public:
NfcConnector(const nsACString& aAddressString);
~NfcConnector();
// Methods for |UnixSocketConnector|
//
nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) override;
nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) override;
nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLen,
int& aStreamFd) override;
nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
private:
nsresult CreateSocket(int& aFd) const;
nsresult SetSocketFlags(int aFd) const;
nsresult CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const;
nsCString mAddressString;
};
}
}
#endif

View File

@ -6,9 +6,11 @@
if CONFIG['MOZ_NFC']:
EXPORTS.mozilla.ipc += [
'Nfc.h',
'NfcConnector.h',
]
SOURCES += [
'Nfc.cpp',
'NfcConnector.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -21,9 +21,9 @@
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/ipc/UnixSocketConnector.h"
#include "nsTArray.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
#include "RilConnector.h"
USING_WORKERS_NAMESPACE
using namespace mozilla::ipc;
@ -32,10 +32,6 @@ namespace {
static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy";
// Network port to connect to for adb forwarded sockets when doing
// desktop development.
static const uint32_t RIL_TEST_PORT = 6200;
static nsTArray<nsRefPtr<mozilla::ipc::RilConsumer> > sRilConsumers;
class ConnectWorkerToRIL final : public WorkerTask
@ -199,109 +195,6 @@ DispatchRILEvent::RunTask(JSContext* aCx)
return JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
}
class RilConnector final : public mozilla::ipc::UnixSocketConnector
{
public:
RilConnector(unsigned long aClientId)
: mClientId(aClientId)
{ }
int Create() override;
bool CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress) override;
bool SetUp(int aFd) override;
bool SetUpListenSocket(int aFd) override;
void GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr) override;
private:
unsigned long mClientId;
};
int
RilConnector::Create()
{
MOZ_ASSERT(!NS_IsMainThread());
int fd = -1;
#if defined(MOZ_WIDGET_GONK)
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
#else
// If we can't hit a local loopback, fail later in connect.
fd = socket(AF_INET, SOCK_STREAM, 0);
#endif
if (fd < 0) {
NS_WARNING("Could not open ril socket!");
return -1;
}
if (!SetUp(fd)) {
NS_WARNING("Could not set up socket!");
}
return fd;
}
bool
RilConnector::CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress)
{
// We never open ril socket as server.
MOZ_ASSERT(!aIsServer);
uint32_t af;
#if defined(MOZ_WIDGET_GONK)
af = AF_LOCAL;
#else
af = AF_INET;
#endif
switch (af) {
case AF_LOCAL:
aAddr.un.sun_family = af;
if(strlen(aAddress) > sizeof(aAddr.un.sun_path)) {
NS_WARNING("Address too long for socket struct!");
return false;
}
strcpy((char*)&aAddr.un.sun_path, aAddress);
aAddrSize = strlen(aAddress) + offsetof(struct sockaddr_un, sun_path) + 1;
break;
case AF_INET:
aAddr.in.sin_family = af;
aAddr.in.sin_port = htons(RIL_TEST_PORT + mClientId);
aAddr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
aAddrSize = sizeof(sockaddr_in);
break;
default:
NS_WARNING("Socket type not handled by connector!");
return false;
}
return true;
}
bool
RilConnector::SetUp(int aFd)
{
// Nothing to do here.
return true;
}
bool
RilConnector::SetUpListenSocket(int aFd)
{
// Nothing to do here.
return true;
}
void
RilConnector::GetSocketAddr(const sockaddr_any& aAddr, nsAString& aAddrStr)
{
MOZ_CRASH("This should never be called!");
}
} // anonymous namespace
namespace mozilla {
@ -324,7 +217,7 @@ RilConsumer::RilConsumer(unsigned long aClientId,
mAddress = addr_un.sun_path;
}
Connect(new RilConnector(mClientId), mAddress.get());
Connect(new RilConnector(mAddress, mClientId), mAddress.get());
}
nsresult
@ -396,7 +289,7 @@ RilConsumer::OnDisconnect()
{
CHROMIUM_LOG("RIL[%lu]: %s\n", mClientId, __FUNCTION__);
if (!mShutdown) {
Connect(new RilConnector(mClientId), mAddress.get(),
Connect(new RilConnector(mAddress, mClientId), mAddress.get(),
GetSuggestedConnectDelayMs());
}
}
@ -404,7 +297,7 @@ RilConsumer::OnDisconnect()
ConnectionOrientedSocketIO*
RilConsumer::GetIO()
{
return PrepareAccept(new RilConnector(mClientId));
return PrepareAccept(new RilConnector(mAddress, mClientId));
}
} // namespace ipc

208
ipc/ril/RilConnector.cpp Normal file
View File

@ -0,0 +1,208 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RilConnector.h"
#include <fcntl.h>
#include <sys/socket.h>
#include "nsThreadUtils.h" // For NS_IsMainThread.
#ifdef AF_INET
#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#ifdef AF_UNIX
#include <sys/un.h>
#endif
namespace mozilla {
namespace ipc {
static const uint16_t RIL_TEST_PORT = 6200;
RilConnector::RilConnector(const nsACString& aAddressString,
unsigned long aClientId)
: mAddressString(aAddressString)
, mClientId(aClientId)
{ }
RilConnector::~RilConnector()
{ }
nsresult
RilConnector::CreateSocket(int aDomain, int& aFd) const
{
aFd = socket(aDomain, SOCK_STREAM, 0);
if (aFd < 0) {
NS_WARNING("Could not open RIL socket!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
RilConnector::SetSocketFlags(int aFd) const
{
static const int sReuseAddress = 1;
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= FD_CLOEXEC;
int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= O_NONBLOCK;
res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set socket addr to be reused even if kernel is still waiting to close.
res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
sizeof(sReuseAddress));
if (res < 0) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
RilConnector::CreateAddress(int aDomain,
struct sockaddr& aAddress,
socklen_t& aAddressLength) const
{
switch (aDomain) {
#ifdef AF_UNIX
case AF_UNIX: {
struct sockaddr_un* address =
reinterpret_cast<struct sockaddr_un*>(&aAddress);
address->sun_family = aDomain;
size_t siz = mAddressString.Length() + 1;
if (siz > sizeof(address->sun_path)) {
NS_WARNING("Address too long for socket struct!");
return NS_ERROR_FAILURE;
}
memcpy(address->sun_path, mAddressString.get(), siz);
aAddressLength = offsetof(struct sockaddr_un, sun_path) + siz;
}
break;
#endif
#ifdef AF_INET
case AF_INET: {
struct sockaddr_in* address =
reinterpret_cast<struct sockaddr_in*>(&aAddress);
address->sin_family = aDomain;
address->sin_port = htons(RIL_TEST_PORT + mClientId);
address->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
aAddressLength = sizeof(*address);
}
break;
#endif
default:
NS_WARNING("Address family not handled by connector!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
// |UnixSocketConnector|
nsresult
RilConnector::ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString)
{
#ifdef AF_UNIX
if (aAddress.sa_family == AF_UNIX) {
const struct sockaddr_un* un =
reinterpret_cast<const struct sockaddr_un*>(&aAddress);
size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
aAddressString.Assign(un->sun_path, len);
} else
#endif
#ifdef AF_INET
if (aAddress.sa_family == AF_INET) {
const struct sockaddr_in* in =
reinterpret_cast<const struct sockaddr_in*>(&aAddress);
aAddressString.Assign(nsDependentCString(inet_ntoa(in->sin_addr)));
} else
#endif
{
NS_WARNING("Address family not handled by connector!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
RilConnector::CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd)
{
MOZ_CRASH("|RilConnector| does not support listening sockets.");
}
nsresult
RilConnector::AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLen,
int& aStreamFd)
{
MOZ_CRASH("|RilConnector| does not support accepting sockets.");
}
nsresult
RilConnector::CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
#ifdef MOZ_WIDGET_GONK
static const int sDomain = AF_UNIX;
#else
static const int sDomain = AF_INET;
#endif
ScopedClose fd;
nsresult rv = CreateSocket(sDomain, fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(sDomain, *aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
aStreamFd = fd.forget();
return NS_OK;
}
}
}

60
ipc/ril/RilConnector.h Normal file
View File

@ -0,0 +1,60 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_RilConnector_h
#define mozilla_ipc_RilConnector_h
#include "mozilla/ipc/UnixSocketConnector.h"
namespace mozilla {
namespace ipc {
/**
* |RilConnector| creates sockets for connecting to rild.
*/
class RilConnector final : public UnixSocketConnector
{
public:
RilConnector(const nsACString& aAddressString,
unsigned long aClientId);
~RilConnector();
// Methods for |UnixSocketConnector|
//
nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) override;
nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) override;
nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLen,
int& aStreamFd) override;
nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
private:
nsresult CreateSocket(int aDomain, int& aFd) const;
nsresult SetSocketFlags(int aFd) const;
nsresult CreateAddress(int aDomain,
struct sockaddr& aAddress,
socklen_t& aAddressLength) const;
nsCString mAddressString;
unsigned long mClientId;
};
}
}
#endif

View File

@ -10,6 +10,7 @@ EXPORTS.mozilla.ipc += [
SOURCES += [
'Ril.cpp',
'RilConnector.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -28,8 +28,7 @@ public:
ListenSocketIO(MessageLoop* mIOLoop,
ListenSocket* aListenSocket,
UnixSocketConnector* aConnector,
const nsACString& aAddress);
UnixSocketConnector* aConnector);
~ListenSocketIO();
void GetSocketAddr(nsAString& aAddrStr) const;
@ -64,9 +63,6 @@ public:
private:
void FireSocketError();
// Set up flags on file descriptor.
static bool SetSocketFlags(int aFd);
/**
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
* directly from main thread. All non-main-thread accesses should happen with
@ -85,33 +81,27 @@ private:
bool mShuttingDownOnIOThread;
/**
* Address we are connecting to, assuming we are creating a client connection.
* Number of valid bytes in |mAddress|
*/
nsCString mAddress;
socklen_t mAddressLength;
/**
* Size of the socket address struct
* Address structure of the socket currently in use
*/
socklen_t mAddrSize;
/**
* Address struct of the socket currently in use
*/
sockaddr_any mAddr;
struct sockaddr_storage mAddress;
ConnectionOrientedSocketIO* mCOSocketIO;
};
ListenSocketIO::ListenSocketIO(MessageLoop* mIOLoop,
ListenSocket* aListenSocket,
UnixSocketConnector* aConnector,
const nsACString& aAddress)
UnixSocketConnector* aConnector)
: UnixSocketWatcher(mIOLoop)
, SocketIOBase()
, mListenSocket(aListenSocket)
, mConnector(aConnector)
, mShuttingDownOnIOThread(false)
, mAddress(aAddress)
, mAddressLength(0)
, mCOSocketIO(nullptr)
{
MOZ_ASSERT(mListenSocket);
@ -132,7 +122,16 @@ ListenSocketIO::GetSocketAddr(nsAString& aAddrStr) const
aAddrStr.Truncate();
return;
}
mConnector->GetSocketAddr(mAddr, aAddrStr);
nsCString addressString;
nsresult rv = mConnector->ConvertAddressToString(
*reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
addressString);
if (NS_FAILED(rv)) {
return;
}
aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
}
void
@ -142,28 +141,14 @@ ListenSocketIO::Listen(ConnectionOrientedSocketIO* aCOSocketIO)
MOZ_ASSERT(mConnector);
MOZ_ASSERT(aCOSocketIO);
struct sockaddr* address = reinterpret_cast<struct sockaddr*>(&mAddress);
mAddressLength = sizeof(mAddress);
if (!IsOpen()) {
int fd = mConnector->Create();
if (fd < 0) {
NS_WARNING("Cannot create socket fd!");
FireSocketError();
return;
}
if (!SetSocketFlags(fd)) {
NS_WARNING("Cannot set socket flags!");
FireSocketError();
return;
}
if (!mConnector->SetUpListenSocket(GetFd())) {
NS_WARNING("Could not set up listen socket!");
FireSocketError();
return;
}
// This will set things we don't particularly care about, but
// it will hand back the correct structure size which is what
// we do care about.
if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) {
NS_WARNING("Cannot create socket address!");
int fd;
nsresult rv = mConnector->CreateListenSocket(address, &mAddressLength,
fd);
if (NS_FAILED(rv)) {
FireSocketError();
return;
}
@ -173,8 +158,7 @@ ListenSocketIO::Listen(ConnectionOrientedSocketIO* aCOSocketIO)
mCOSocketIO = aCOSocketIO;
// calls OnListening on success, or OnError otherwise
nsresult rv = UnixSocketWatcher::Listen(
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
nsresult rv = UnixSocketWatcher::Listen(address, mAddressLength);
NS_WARN_IF(NS_FAILED(rv));
}
@ -221,41 +205,6 @@ ListenSocketIO::FireSocketError()
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
}
bool
ListenSocketIO::SetSocketFlags(int aFd)
{
static const int reuseaddr = 1;
// Set socket addr to be reused even if kernel is still waiting to close
int res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR,
&reuseaddr, sizeof(reuseaddr));
if (res < 0) {
return false;
}
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (-1 == flags) {
return false;
}
flags |= FD_CLOEXEC;
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
return false;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (-1 == flags) {
return false;
}
flags |= O_NONBLOCK;
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
return false;
}
return true;
}
void
ListenSocketIO::OnSocketCanAcceptWithoutBlocking()
{
@ -263,20 +212,24 @@ ListenSocketIO::OnSocketCanAcceptWithoutBlocking()
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
MOZ_ASSERT(mCOSocketIO);
struct sockaddr_storage addr;
socklen_t addrLen = sizeof(addr);
int fd = TEMP_FAILURE_RETRY(accept(GetFd(),
reinterpret_cast<struct sockaddr*>(&addr), &addrLen));
if (fd < 0) {
OnError("accept", errno);
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
struct sockaddr_storage storage;
socklen_t addressLength = sizeof(storage);
int fd;
nsresult rv = mConnector->AcceptStreamSocket(
GetFd(),
reinterpret_cast<struct sockaddr*>(&storage), &addressLength,
fd);
if (NS_FAILED(rv)) {
FireSocketError();
return;
}
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
mCOSocketIO->Accept(fd,
reinterpret_cast<union sockaddr_any*>(&addr),
addrLen);
reinterpret_cast<union sockaddr_any*>(&storage),
addressLength);
}
// |SocketIOBase|
@ -397,8 +350,7 @@ ListenSocket::Listen(UnixSocketConnector* aConnector,
return false;
}
mIO = new ListenSocketIO(
XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
mIO = new ListenSocketIO(XRE_GetIOMessageLoop(), this, connector.forget());
// Prepared I/O object, now start listening.
return Listen(aCOSocket);

View File

@ -30,13 +30,11 @@ public:
StreamSocketIO(MessageLoop* mIOLoop,
StreamSocket* aStreamSocket,
UnixSocketConnector* aConnector,
const nsACString& aAddress);
UnixSocketConnector* aConnector);
StreamSocketIO(MessageLoop* mIOLoop, int aFd,
ConnectionStatus aConnectionStatus,
StreamSocket* aStreamSocket,
UnixSocketConnector* aConnector,
const nsACString& aAddress);
UnixSocketConnector* aConnector);
~StreamSocketIO();
void GetSocketAddr(nsAString& aAddrStr) const;
@ -98,9 +96,6 @@ public:
private:
void FireSocketError();
// Set up flags on file descriptor.
static bool SetSocketFlags(int aFd);
/**
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
* directly from main thread. All non-main-thread accesses should happen with
@ -119,19 +114,14 @@ private:
bool mShuttingDownOnIOThread;
/**
* Address we are connecting to, assuming we are creating a client connection.
* Number of valid bytes in |mAddress|
*/
nsCString mAddress;
socklen_t mAddressLength;
/**
* Size of the socket address struct
* Address structure of the socket currently in use
*/
socklen_t mAddrSize;
/**
* Address struct of the socket currently in use
*/
sockaddr_any mAddr;
struct sockaddr_storage mAddress;
/**
* Task member for delayed connect task. Should only be access on main thread.
@ -146,13 +136,12 @@ private:
StreamSocketIO::StreamSocketIO(MessageLoop* mIOLoop,
StreamSocket* aStreamSocket,
UnixSocketConnector* aConnector,
const nsACString& aAddress)
UnixSocketConnector* aConnector)
: UnixSocketWatcher(mIOLoop)
, mStreamSocket(aStreamSocket)
, mConnector(aConnector)
, mShuttingDownOnIOThread(false)
, mAddress(aAddress)
, mAddressLength(0)
, mDelayedConnectTask(nullptr)
{
MOZ_ASSERT(mStreamSocket);
@ -162,13 +151,12 @@ StreamSocketIO::StreamSocketIO(MessageLoop* mIOLoop,
StreamSocketIO::StreamSocketIO(MessageLoop* mIOLoop, int aFd,
ConnectionStatus aConnectionStatus,
StreamSocket* aStreamSocket,
UnixSocketConnector* aConnector,
const nsACString& aAddress)
UnixSocketConnector* aConnector)
: UnixSocketWatcher(mIOLoop, aFd, aConnectionStatus)
, mStreamSocket(aStreamSocket)
, mConnector(aConnector)
, mShuttingDownOnIOThread(false)
, mAddress(aAddress)
, mAddressLength(0)
, mDelayedConnectTask(nullptr)
{
MOZ_ASSERT(mStreamSocket);
@ -189,7 +177,16 @@ StreamSocketIO::GetSocketAddr(nsAString& aAddrStr) const
aAddrStr.Truncate();
return;
}
mConnector->GetSocketAddr(mAddr, aAddrStr);
nsCString addressString;
nsresult rv = mConnector->ConvertAddressToString(
*reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
addressString);
if (NS_FAILED(rv)) {
return;
}
aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
}
StreamSocket*
@ -239,34 +236,21 @@ StreamSocketIO::Connect()
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
MOZ_ASSERT(mConnector);
if (!IsOpen()) {
int fd = mConnector->Create();
if (fd < 0) {
NS_WARNING("Cannot create socket fd!");
FireSocketError();
return;
}
if (!SetSocketFlags(fd)) {
NS_WARNING("Cannot set socket flags!");
FireSocketError();
return;
}
if (!mConnector->SetUp(GetFd())) {
NS_WARNING("Could not set up socket!");
FireSocketError();
return;
}
if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
NS_WARNING("Cannot create socket address!");
FireSocketError();
return;
}
SetFd(fd);
MOZ_ASSERT(!IsOpen());
struct sockaddr* address = reinterpret_cast<struct sockaddr*>(&mAddress);
mAddressLength = sizeof(mAddress);
int fd;
nsresult rv = mConnector->CreateStreamSocket(address, &mAddressLength, fd);
if (NS_FAILED(rv)) {
FireSocketError();
return;
}
SetFd(fd);
// calls OnConnected() on success, or OnError() otherwise
nsresult rv = UnixSocketWatcher::Connect(
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
rv = UnixSocketWatcher::Connect(address, mAddressLength);
NS_WARN_IF(NS_FAILED(rv));
}
@ -354,41 +338,6 @@ StreamSocketIO::FireSocketError()
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
}
bool
StreamSocketIO::SetSocketFlags(int aFd)
{
static const int reuseaddr = 1;
// Set socket addr to be reused even if kernel is still waiting to close
int res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR,
&reuseaddr, sizeof(reuseaddr));
if (res < 0) {
return false;
}
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (-1 == flags) {
return false;
}
flags |= FD_CLOEXEC;
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
return false;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (-1 == flags) {
return false;
}
flags |= O_NONBLOCK;
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
return false;
}
return true;
}
// |ConnectionOrientedSocketIO|
nsresult
@ -398,21 +347,11 @@ StreamSocketIO::Accept(int aFd,
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTING);
// File-descriptor setup
if (!SetSocketFlags(aFd)) {
return NS_ERROR_FAILURE;
}
if (!mConnector->SetUp(aFd)) {
NS_WARNING("Could not set up socket!");
return NS_ERROR_FAILURE;
}
SetSocket(aFd, SOCKET_IS_CONNECTED);
// Address setup
memcpy(&mAddr, aAddr, aAddrLen);
mAddrSize = aAddrLen;
mAddressLength = aAddrLen;
memcpy(&mAddress, aAddr, mAddressLength);
// Signal success
NS_DispatchToMainThread(
@ -652,9 +591,8 @@ StreamSocket::Connect(UnixSocketConnector* aConnector,
return false;
}
nsCString addr(aAddress);
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
mIO = new StreamSocketIO(ioLoop, this, connector.forget(), addr);
mIO = new StreamSocketIO(ioLoop, this, connector.forget());
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
StreamSocketIO::DelayedConnectTask* connectTask =
@ -681,7 +619,7 @@ StreamSocket::PrepareAccept(UnixSocketConnector* aConnector)
mIO = new StreamSocketIO(XRE_GetIOMessageLoop(),
-1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
this, connector.forget(), EmptyCString());
this, connector.forget());
return mIO;
}

View File

@ -9,6 +9,9 @@
namespace mozilla {
namespace ipc {
UnixSocketConnector::UnixSocketConnector()
{ }
UnixSocketConnector::~UnixSocketConnector()
{ }

View File

@ -7,6 +7,7 @@
#ifndef mozilla_ipc_unixsocketconnector_h
#define mozilla_ipc_unixsocketconnector_h
#include <sys/socket.h>
#include "mozilla/ipc/UnixSocketWatcher.h"
#include "nsString.h"
@ -16,7 +17,7 @@ namespace ipc {
/**
* |UnixSocketConnector| defines the socket creation and connection/listening
* functions for |UnixSocketConsumer|, et al. Due to the fact that socket setup
* can vary between protocols (unix sockets, tcp sockets, bluetooth sockets, etc),
* can vary between protocols (Unix sockets, TCP sockets, Bluetooth sockets, etc),
* this allows the user to create whatever connection mechanism they need while
* still depending on libevent for non-blocking communication handling.
*/
@ -26,57 +27,57 @@ public:
virtual ~UnixSocketConnector();
/**
* Establishs a file descriptor for a socket.
* Converts an address to a human-readable string.
*
* @return File descriptor for socket
* @param aAddress A socket address
* @param aAddressLength The number of valid bytes in |aAddress|
* @param[out] aAddressString The resulting string
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
virtual int Create() = 0;
virtual nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) = 0;
/**
* Since most socket specifics are related to address formation into a
* sockaddr struct, this function is defined by subclasses and fills in the
* structure as needed for whatever connection it is trying to build
* Creates a listening socket. I/O thread only.
*
* @param aIsServer True is we are acting as a server socket
* @param aAddrSize Size of the struct
* @param aAddr Struct to fill
* @param aAddress If aIsServer is false, Address to connect to. nullptr otherwise.
*
* @return True if address is filled correctly, false otherwise
* @param[out] aAddress The listening socket's address
* @param[out] aAddressLength The number of valid bytes in |aAddress|
* @param[out] aListenFd The socket's file descriptor
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
virtual bool CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress) = 0;
virtual nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) = 0;
/**
* Does any socket type specific setup that may be needed, only for socket
* created by ConnectSocket()
* Accepts a stream socket from a listening socket. I/O thread only.
*
* @param aFd File descriptor for opened socket
*
* @return true is successful, false otherwise
* @param aListenFd The listening socket
* @param[out] aAddress Returns the stream socket's address
* @param[out] aAddressLength Returns the number of valid bytes in |aAddress|
* @param[out] aStreamFd The stream socket's file descriptor
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
virtual bool SetUp(int aFd) = 0;
virtual nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLen,
int& aStreamFd) = 0;
/**
* Perform socket setup for socket created by ListenSocket(), after listen().
* Creates a stream socket. I/O thread only.
*
* @param aFd File descriptor for opened socket
*
* @return true is successful, false otherwise
* @param[in|out] aAddress The stream socket's address
* @param[in|out] aAddressLength The number of valid bytes in |aAddress|
* @param[out] aStreamFd The socket's file descriptor
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
virtual bool SetUpListenSocket(int aFd) = 0;
virtual nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) = 0;
/**
* Get address of socket we're currently connected to. Return null string if
* not connected.
*
* @param aAddr Address struct
* @param aAddrStr String to store address to
*/
virtual void GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr) = 0;
protected:
UnixSocketConnector();
};
}