diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml
index f4725639949..528e121b45e 100644
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 218c4d5fd5f..c6b682a2e91 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 0a0a3c36ea8..734631a7c94 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,8 +19,8 @@
-
-
+
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 508f0bb9107..2070ced2909 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,10 +17,10 @@
-
-
+
+
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 39f45586c70..73c497efdba 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml
index 2bd4ee19062..b7ad9ace7bb 100644
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 0a0a3c36ea8..734631a7c94 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,8 +19,8 @@
-
-
+
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index f3cd317a8d4..1b9e7974971 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 871f6ede654..79c7e328a48 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -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"
}
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 096d920cf79..c4c1cbe75ce 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,10 +17,10 @@
-
-
+
+
-
+
diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml
index 048db8d119e..8dbab3baccf 100644
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/dom/bluetooth/BluetoothUtils.cpp b/dom/bluetooth/BluetoothUtils.cpp
index b52356e5ec5..a3f1a834e23 100644
--- a/dom/bluetooth/BluetoothUtils.cpp
+++ b/dom/bluetooth/BluetoothUtils.cpp
@@ -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 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()
diff --git a/dom/bluetooth/BluetoothUtils.h b/dom/bluetooth/BluetoothUtils.h
index 1b231376d49..666a94094c3 100644
--- a/dom/bluetooth/BluetoothUtils.h
+++ b/dom/bluetooth/BluetoothUtils.h
@@ -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,
diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
new file mode 100644
index 00000000000..a526fca396e
--- /dev/null
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
@@ -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
+#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(&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(&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
diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonConnector.h b/dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
new file mode 100644
index 00000000000..c3f014294f4
--- /dev/null
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
@@ -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
diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
index 91046bd744c..5b20efd8117 100644
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -10,13 +10,13 @@
#include
#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;
diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
index c3f2eb41e3c..cd1f74b2ba9 100644
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -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 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 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 emptyArr;
- DispatchBluetoothReply(aRunnable, BluetoothValue(emptyArr), EmptyString());
+ DispatchReplySuccess(aRunnable, InfallibleTArray());
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;
diff --git a/dom/bluetooth/bluetooth1/BluetoothProfileController.cpp b/dom/bluetooth/bluetooth1/BluetoothProfileController.cpp
index b63b2ccd53c..bdf017a5b72 100644
--- a/dom/bluetooth/bluetooth1/BluetoothProfileController.cpp
+++ b/dom/bluetooth/bluetooth1/BluetoothProfileController.cpp
@@ -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();
diff --git a/dom/bluetooth/bluez/BluetoothDBusService.cpp b/dom/bluetooth/bluez/BluetoothDBusService.cpp
index a43887267f4..7136d9f461b 100644
--- a/dom/bluetooth/bluez/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp
@@ -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& aServiceUuids,
- BluetoothReplyRunnable* aRunnable);
+ BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::StopLeScanInternal(
const nsAString& aAppUuid,
- BluetoothReplyRunnable* aRunnable);
+ BluetoothReplyRunnable* aRunnable)
{
}
diff --git a/dom/bluetooth/bluez/BluetoothHfpManager.cpp b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
index b6982807f7d..283a864ca99 100644
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -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;
}
diff --git a/dom/bluetooth/bluez/BluetoothSocket.cpp b/dom/bluetooth/bluez/BluetoothSocket.cpp
index 27b5d50d32f..02f573de6d9 100644
--- a/dom/bluetooth/bluez/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluez/BluetoothSocket.cpp
@@ -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(&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(&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(&mAddr), mAddrSize);
+ rv = UnixSocketWatcher::Listen(
+ reinterpret_cast(&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(&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(&mAddr), mAddrSize);
+ reinterpret_cast(&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(&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(&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 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 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;
}
diff --git a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
index bb980dec314..f9fbfbdf8de 100644
--- a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
+++ b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
@@ -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
-#include
-#include
-#include
-
-#include
-#ifdef MOZ_B2G_BT_BLUEZ
+#include "BluetoothUnixSocketConnector.h"
#include
#include
#include
#include
-#endif
-#include "BluetoothUnixSocketConnector.h"
-#include "nsThreadUtils.h"
+#include
+#include
+#include
+#include
+#include
+#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(&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(&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(&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(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(&aAddress);
+ b = rc->rc_bdaddr.b;
+ }
+ break;
+ case BluetoothSocketType::SCO: {
+ const struct sockaddr_sco* sco =
+ reinterpret_cast(&aAddress);
+ b = sco->sco_bdaddr.b;
+ }
+ break;
+ case BluetoothSocketType::L2CAP:
+ case BluetoothSocketType::EL2CAP: {
+ const struct sockaddr_l2* l2 =
+ reinterpret_cast(&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
diff --git a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h
index d793f470651..852a5e69389 100644
--- a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h
+++ b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h
@@ -8,29 +8,48 @@
#define mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
#include "BluetoothCommon.h"
-#include
-#include
+#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;
diff --git a/dom/bluetooth/moz.build b/dom/bluetooth/moz.build
index 78a84e766aa..538077133f0 100644
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -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',
diff --git a/dom/nfc/gonk/NfcService.cpp b/dom/nfc/gonk/NfcService.cpp
index f0923b5331d..de1d6951181 100644
--- a/dom/nfc/gonk/NfcService.cpp
+++ b/dom/nfc/gonk/NfcService.cpp
@@ -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;
diff --git a/dom/system/gonk/tests/marionette/test_ril_code_quality.py b/dom/system/gonk/tests/marionette/test_ril_code_quality.py
index 1002b99486f..a7705e4c5e9 100644
--- a/dom/system/gonk/tests/marionette/test_ril_code_quality.py
+++ b/dom/system/gonk/tests/marionette/test_ril_code_quality.py
@@ -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
diff --git a/ipc/keystore/KeyStore.cpp b/ipc/keystore/KeyStore.cpp
index 1bf568b8521..0a878e221d2 100644
--- a/ipc/keystore/KeyStore.cpp
+++ b/ipc/keystore/KeyStore.cpp
@@ -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& 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);
diff --git a/ipc/keystore/KeyStore.h b/ipc/keystore/KeyStore.h
index 797cd536937..18dcf3b56ea 100644
--- a/ipc/keystore/KeyStore.h
+++ b/ipc/keystore/KeyStore.h
@@ -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:
diff --git a/ipc/keystore/KeyStoreConnector.cpp b/ipc/keystore/KeyStoreConnector.cpp
new file mode 100644
index 00000000000..a40fef8665b
--- /dev/null
+++ b/ipc/keystore/KeyStoreConnector.cpp
@@ -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
+#include
+#include
+#include
+#include "nsThreadUtils.h" // For NS_IsMainThread.
+
+#ifdef MOZ_WIDGET_GONK
+#include
+#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(&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(&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;
+}
+
+}
+}
diff --git a/ipc/keystore/KeyStoreConnector.h b/ipc/keystore/KeyStoreConnector.h
new file mode 100644
index 00000000000..5387b5290ff
--- /dev/null
+++ b/ipc/keystore/KeyStoreConnector.h
@@ -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
diff --git a/ipc/keystore/moz.build b/ipc/keystore/moz.build
index 78af00cb211..62005f33aa8 100644
--- a/ipc/keystore/moz.build
+++ b/ipc/keystore/moz.build
@@ -9,7 +9,8 @@ EXPORTS.mozilla.ipc += [
]
SOURCES += [
- 'KeyStore.cpp'
+ 'KeyStore.cpp',
+ 'KeyStoreConnector.cpp'
]
FAIL_ON_WARNINGS = True
diff --git a/ipc/nfc/Nfc.cpp b/ipc/nfc/Nfc.cpp
index 9ff5e49d600..15162149242 100644
--- a/ipc/nfc/Nfc.cpp
+++ b/ipc/nfc/Nfc.cpp
@@ -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
diff --git a/ipc/nfc/Nfc.h b/ipc/nfc/Nfc.h
index 583c4174df5..198f7d666fe 100644
--- a/ipc/nfc/Nfc.h
+++ b/ipc/nfc/Nfc.h
@@ -11,7 +11,6 @@
#include
#include
-#include
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:
diff --git a/ipc/nfc/NfcConnector.cpp b/ipc/nfc/NfcConnector.cpp
new file mode 100644
index 00000000000..5c36d7450aa
--- /dev/null
+++ b/ipc/nfc/NfcConnector.cpp
@@ -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
+#include
+#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(&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(&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;
+}
+
+}
+}
diff --git a/ipc/nfc/NfcConnector.h b/ipc/nfc/NfcConnector.h
new file mode 100644
index 00000000000..b4ef85ef60f
--- /dev/null
+++ b/ipc/nfc/NfcConnector.h
@@ -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
diff --git a/ipc/nfc/moz.build b/ipc/nfc/moz.build
index 8443be5bedb..b824ae1c8ed 100644
--- a/ipc/nfc/moz.build
+++ b/ipc/nfc/moz.build
@@ -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')
diff --git a/ipc/ril/Ril.cpp b/ipc/ril/Ril.cpp
index c7848bb9519..48264e1a91d 100644
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -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 > 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
diff --git a/ipc/ril/RilConnector.cpp b/ipc/ril/RilConnector.cpp
new file mode 100644
index 00000000000..35bcd48b68d
--- /dev/null
+++ b/ipc/ril/RilConnector.cpp
@@ -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
+#include
+#include "nsThreadUtils.h" // For NS_IsMainThread.
+
+#ifdef AF_INET
+#include
+#include
+#endif
+#ifdef AF_UNIX
+#include
+#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(&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(&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(&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(&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;
+}
+
+}
+}
diff --git a/ipc/ril/RilConnector.h b/ipc/ril/RilConnector.h
new file mode 100644
index 00000000000..49c1cf051cb
--- /dev/null
+++ b/ipc/ril/RilConnector.h
@@ -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
diff --git a/ipc/ril/moz.build b/ipc/ril/moz.build
index 2ab5da59e8d..4e7018bcb6a 100644
--- a/ipc/ril/moz.build
+++ b/ipc/ril/moz.build
@@ -10,6 +10,7 @@ EXPORTS.mozilla.ipc += [
SOURCES += [
'Ril.cpp',
+ 'RilConnector.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')
diff --git a/ipc/unixsocket/ListenSocket.cpp b/ipc/unixsocket/ListenSocket.cpp
index fca2f896b2d..62cb76fba54 100644
--- a/ipc/unixsocket/ListenSocket.cpp
+++ b/ipc/unixsocket/ListenSocket.cpp
@@ -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(&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(&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(&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(&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(&storage), &addressLength,
+ fd);
+ if (NS_FAILED(rv)) {
+ FireSocketError();
return;
}
- RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
-
mCOSocketIO->Accept(fd,
- reinterpret_cast(&addr),
- addrLen);
+ reinterpret_cast(&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);
diff --git a/ipc/unixsocket/StreamSocket.cpp b/ipc/unixsocket/StreamSocket.cpp
index d6e423ba593..79b8471efc6 100644
--- a/ipc/unixsocket/StreamSocket.cpp
+++ b/ipc/unixsocket/StreamSocket.cpp
@@ -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(&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(&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(&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;
}
diff --git a/ipc/unixsocket/UnixSocketConnector.cpp b/ipc/unixsocket/UnixSocketConnector.cpp
index ef958f062f8..37ddd0fb1b0 100644
--- a/ipc/unixsocket/UnixSocketConnector.cpp
+++ b/ipc/unixsocket/UnixSocketConnector.cpp
@@ -9,6 +9,9 @@
namespace mozilla {
namespace ipc {
+UnixSocketConnector::UnixSocketConnector()
+{ }
+
UnixSocketConnector::~UnixSocketConnector()
{ }
diff --git a/ipc/unixsocket/UnixSocketConnector.h b/ipc/unixsocket/UnixSocketConnector.h
index dcfb1b83149..39f76501c70 100644
--- a/ipc/unixsocket/UnixSocketConnector.h
+++ b/ipc/unixsocket/UnixSocketConnector.h
@@ -7,6 +7,7 @@
#ifndef mozilla_ipc_unixsocketconnector_h
#define mozilla_ipc_unixsocketconnector_h
+#include
#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();
};
}