Bug 1171017: Move classes from ipc/bluetooth to ipc/hal, r=shuang
The class |DaemonSocket| and its helpers implement a service-
neutral connection to a HAL daemon. This patch moves the code
to an appropriate directory and breaks up the code into smaller
pieces.
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
@@ -5,17 +5,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothdaemonhelpers_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemonhelpers_h__
#include "BluetoothCommon.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
-#include "mozilla/ipc/BluetoothDaemonConnection.h"
+#include "mozilla/ipc/DaemonSocketPDU.h"
#include "nsThreadUtils.h"
using namespace mozilla::ipc;
BEGIN_BLUETOOTH_NAMESPACE
//
// Helper structures
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -12,16 +12,17 @@
#include "BluetoothDaemonAvrcpInterface.h"
#include "BluetoothDaemonConnector.h"
#include "BluetoothDaemonGattInterface.h"
#include "BluetoothDaemonHandsfreeInterface.h"
#include "BluetoothDaemonHelpers.h"
#include "BluetoothDaemonSetupInterface.h"
#include "BluetoothDaemonSocketInterface.h"
#include "BluetoothInterfaceHelpers.h"
+#include "mozilla/ipc/DaemonSocket.h"
#include "mozilla/ipc/ListenSocket.h"
#include "mozilla/unused.h"
#include "prrng.h"
using namespace mozilla::ipc;
BEGIN_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
@@ -3,17 +3,17 @@
/* 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_bluetoothdaemoninterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemoninterface_h__
#include "BluetoothInterface.h"
-#include "mozilla/ipc/BluetoothDaemonConnectionConsumer.h"
+#include "mozilla/ipc/DaemonSocketConsumer.h"
#include "mozilla/ipc/ListenSocketConsumer.h"
namespace mozilla {
namespace ipc {
class DaemonSocket;
class ListenSocket;
rename from ipc/bluetooth/BluetoothDaemonConnection.cpp
rename to ipc/hal/DaemonSocket.cpp
--- a/ipc/bluetooth/BluetoothDaemonConnection.cpp
+++ b/ipc/hal/DaemonSocket.cpp
@@ -1,24 +1,17 @@
/* -*- 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 "BluetoothDaemonConnection.h"
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include "mozilla/ipc/BluetoothDaemonConnectionConsumer.h"
-#include "mozilla/ipc/DataSocket.h"
-#include "nsTArray.h"
-#include "nsXULAppAPI.h"
+#include "DaemonSocket.h"
+#include "mozilla/ipc/DaemonSocketConsumer.h"
+#include "mozilla/ipc/DaemonSocketPDU.h"
#ifdef CHROMIUM_LOG
#undef CHROMIUM_LOG
#endif
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args);
@@ -26,192 +19,16 @@
#include <stdio.h>
#define IODEBUG true
#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
#endif
namespace mozilla {
namespace ipc {
-// The connection to the Bluetooth daemon is established
-// using an abstract socket name. The \0 prefix will be added
-// by the |Connect| method.
-static const char sBluetoothdSocketName[] = "bluez_hal_socket";
-
-//
-// DaemonSocketPDU
-//
-
-DaemonSocketPDU::DaemonSocketPDU(uint8_t aService, uint8_t aOpcode,
- uint16_t aPayloadSize)
- : mConsumer(nullptr)
- , mUserData(nullptr)
-{
- // Allocate memory
- size_t availableSpace = HEADER_SIZE + aPayloadSize;
- ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
-
- // Reserve PDU header
- uint8_t* data = Append(HEADER_SIZE);
- MOZ_ASSERT(data);
-
- // Setup PDU header
- data[OFF_SERVICE] = aService;
- data[OFF_OPCODE] = aOpcode;
- memcpy(data + OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize));
-}
-
-DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize)
- : mConsumer(nullptr)
- , mUserData(nullptr)
-{
- size_t availableSpace = HEADER_SIZE + aPayloadSize;
- ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
-}
-
-DaemonSocketPDU::~DaemonSocketPDU()
-{
- nsAutoArrayPtr<uint8_t> data(GetBuffer());
- ResetBuffer(nullptr, 0, 0, 0);
-}
-
-void
-DaemonSocketPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode,
- uint16_t& aPayloadSize)
-{
- memcpy(&aService, GetData(OFF_SERVICE), sizeof(aService));
- memcpy(&aOpcode, GetData(OFF_OPCODE), sizeof(aOpcode));
- memcpy(&aPayloadSize, GetData(OFF_LENGTH), sizeof(aPayloadSize));
-}
-
-ssize_t
-DaemonSocketPDU::Send(int aFd)
-{
- struct iovec iv;
- memset(&iv, 0, sizeof(iv));
- iv.iov_base = GetData(GetLeadingSpace());
- iv.iov_len = GetSize();
-
- struct msghdr msg;
- memset(&msg, 0, sizeof(msg));
- msg.msg_iov = &iv;
- msg.msg_iovlen = 1;
- msg.msg_control = nullptr;
- msg.msg_controllen = 0;
-
- ssize_t res = TEMP_FAILURE_RETRY(sendmsg(aFd, &msg, 0));
- if (res < 0) {
- MOZ_ASSERT(errno != EBADF); /* internal error */
- OnError("sendmsg", errno);
- return -1;
- }
-
- Consume(res);
-
- if (mConsumer) {
- // We successfully sent a PDU, now store the
- // result runnable in the consumer.
- mConsumer->StoreUserData(*this);
- }
-
- return res;
-}
-
-#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
- ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
- ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
-
-ssize_t
-DaemonSocketPDU::Receive(int aFd)
-{
- struct iovec iv;
- memset(&iv, 0, sizeof(iv));
- iv.iov_base = GetData(0);
- iv.iov_len = GetAvailableSpace();
-
- uint8_t cmsgbuf[CMSG_SPACE(sizeof(int))];
-
- struct msghdr msg;
- memset(&msg, 0, sizeof(msg));
- msg.msg_iov = &iv;
- msg.msg_iovlen = 1;
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
-
- ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL));
- if (res < 0) {
- MOZ_ASSERT(errno != EBADF); /* internal error */
- OnError("recvmsg", errno);
- return -1;
- }
- if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
- return -1;
- }
-
- SetRange(0, res);
-
- struct cmsghdr *chdr = CMSG_FIRSTHDR(&msg);
-
- for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) {
- if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) {
- continue;
- }
- // Retrieve sent file descriptor. If multiple file descriptors
- // have been sent, we close all but the final one.
- mReceivedFd = *(static_cast<int*>(CMSG_DATA(chdr)));
- }
-
- return res;
-}
-
-int
-DaemonSocketPDU::AcquireFd()
-{
- return mReceivedFd.forget();
-}
-
-nsresult
-DaemonSocketPDU::UpdateHeader()
-{
- size_t len = GetPayloadSize();
- if (len >= MAX_PAYLOAD_LENGTH) {
- return NS_ERROR_ILLEGAL_VALUE;
- }
- uint16_t len16 = static_cast<uint16_t>(len);
-
- memcpy(GetData(OFF_LENGTH), &len16, sizeof(len16));
-
- return NS_OK;
-}
-
-size_t
-DaemonSocketPDU::GetPayloadSize() const
-{
- MOZ_ASSERT(GetSize() >= HEADER_SIZE);
-
- return GetSize() - HEADER_SIZE;
-}
-
-void
-DaemonSocketPDU::OnError(const char* aFunction, int aErrno)
-{
- CHROMIUM_LOG("%s failed with error %d (%s)",
- aFunction, aErrno, strerror(aErrno));
-}
-
-//
-// DaemonSocketIOConsumer
-//
-
-DaemonSocketIOConsumer::DaemonSocketIOConsumer()
-{ }
-
-DaemonSocketIOConsumer::~DaemonSocketIOConsumer()
-{ }
-
//
// DaemonSocketIO
//
class DaemonSocketIO final : public ConnectionOrientedSocketIO
{
public:
DaemonSocketIO(MessageLoop* aConsumerLoop,
@@ -391,17 +208,17 @@ DaemonSocket::SendSocketData(UnixSocketI
}
// |SocketBase|
void
DaemonSocket::Close()
{
if (!mIO) {
- CHROMIUM_LOG("Bluetooth daemon already disconnected!");
+ CHROMIUM_LOG("HAL daemon already disconnected!");
return;
}
MOZ_ASSERT(mIO->IsConsumerThread());
mIO->ShutdownOnConsumerThread();
mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
mIO = nullptr;
rename from ipc/bluetooth/BluetoothDaemonConnection.h
rename to ipc/hal/DaemonSocket.h
--- a/ipc/bluetooth/BluetoothDaemonConnection.h
+++ b/ipc/hal/DaemonSocket.h
@@ -1,123 +1,30 @@
/* -*- 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_bluetooth_DaemonSocket_h
-#define mozilla_ipc_bluetooth_DaemonSocket_h
+#ifndef mozilla_ipc_DaemonSocket_h
+#define mozilla_ipc_DaemonSocket_h
-#include "mozilla/Attributes.h"
-#include "mozilla/FileUtils.h"
#include "mozilla/ipc/ConnectionOrientedSocket.h"
-#include "nsAutoPtr.h"
-
-class MessageLoop;
namespace mozilla {
namespace ipc {
class DaemonSocketConsumer;
class DaemonSocketIO;
class DaemonSocketIOConsumer;
-/*
- * |DaemonSocketPDU| represents a single PDU that is transfered from or to
- * the Bluetooth daemon. Each PDU contains exactly one command.
- *
- * A PDU as the following format
- *
- * | 1 | 1 | 2 | n |
- * | service | opcode | payload length | payload |
- *
- * Service and Opcode each require 1 byte, the payload length requires 2
- * bytes, and the payload requires the number of bytes as stored in the
- * payload-length field.
- *
- * Each service and opcode can have a different payload with individual
- * length. For the exact details of the Bluetooth protocol, please refer
- * to
- *
- * https://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/hal-ipc-api.txt?id=5.24
- *
- */
-class DaemonSocketPDU final : public UnixSocketIOBuffer
-{
-public:
- enum {
- OFF_SERVICE = 0,
- OFF_OPCODE = 1,
- OFF_LENGTH = 2,
- OFF_PAYLOAD = 4,
- HEADER_SIZE = OFF_PAYLOAD,
- MAX_PAYLOAD_LENGTH = 1 << 16
- };
-
- DaemonSocketPDU(uint8_t aService, uint8_t aOpcode,
- uint16_t aPayloadSize);
- DaemonSocketPDU(size_t aPayloadSize);
- ~DaemonSocketPDU();
-
- void SetConsumer(DaemonSocketIOConsumer* aConsumer)
- {
- mConsumer = aConsumer;
- }
-
- void SetUserData(void* aUserData)
- {
- mUserData = aUserData;
- }
-
- void* GetUserData() const
- {
- return mUserData;
- }
-
- void GetHeader(uint8_t& aService, uint8_t& aOpcode,
- uint16_t& aPayloadSize);
-
- ssize_t Send(int aFd) override;
- ssize_t Receive(int aFd) override;
-
- int AcquireFd();
-
- nsresult UpdateHeader();
-
-private:
- size_t GetPayloadSize() const;
- void OnError(const char* aFunction, int aErrno);
-
- DaemonSocketIOConsumer* mConsumer;
- void* mUserData;
- ScopedClose mReceivedFd;
-};
-
-/*
- * |DaemonSocketIOConsumer| processes incoming PDUs from the Bluetooth
- * daemon. Please note that its method |Handle| runs on a different than the
- * consumer thread.
- */
-class DaemonSocketIOConsumer
-{
-public:
- virtual ~DaemonSocketIOConsumer();
-
- virtual void Handle(DaemonSocketPDU& aPDU) = 0;
- virtual void StoreUserData(const DaemonSocketPDU& aPDU) = 0;
-
-protected:
- DaemonSocketIOConsumer();
-};
-
-/*
- * |DaemonSocket| represents the socket to connect to the
- * Bluetooth daemon. It offers connection establishment and sending
- * PDUs. PDU receiving is performed by |DaemonSocketIOConsumer|.
+/**
+ * |DaemonSocket| represents the socket to connect to the HAL daemon. It
+ * offers connection establishment and sending PDUs. PDU receiving is
+ * performed by |DaemonSocketIOConsumer|.
*/
class DaemonSocket : public ConnectionOrientedSocket
{
public:
DaemonSocket(DaemonSocketIOConsumer* aIOConsumer,
DaemonSocketConsumer* aConsumer,
int aIndex);
virtual ~DaemonSocket();
rename from ipc/bluetooth/BluetoothDaemonConnectionConsumer.cpp
rename to ipc/hal/DaemonSocketConsumer.cpp
--- a/ipc/bluetooth/BluetoothDaemonConnectionConsumer.cpp
+++ b/ipc/hal/DaemonSocketConsumer.cpp
@@ -1,20 +1,30 @@
/* -*- 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 "BluetoothDaemonConnectionConsumer.h"
+#include "DaemonSocketConsumer.h"
namespace mozilla {
namespace ipc {
//
+// DaemonSocketIOConsumer
+//
+
+DaemonSocketIOConsumer::DaemonSocketIOConsumer()
+{ }
+
+DaemonSocketIOConsumer::~DaemonSocketIOConsumer()
+{ }
+
+//
// DaemonSocketConsumer
//
DaemonSocketConsumer::DaemonSocketConsumer()
{ }
DaemonSocketConsumer::~DaemonSocketConsumer()
{ }
rename from ipc/bluetooth/BluetoothDaemonConnectionConsumer.h
rename to ipc/hal/DaemonSocketConsumer.h
--- a/ipc/bluetooth/BluetoothDaemonConnectionConsumer.h
+++ b/ipc/hal/DaemonSocketConsumer.h
@@ -1,26 +1,40 @@
/* -*- 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_BluetoothDaemonConnectionConsumer_h
-#define mozilla_ipc_BluetoothDaemonConnectionConsumer_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/FileUtils.h"
-#include "mozilla/ipc/ConnectionOrientedSocket.h"
-#include "nsAutoPtr.h"
+#ifndef mozilla_ipc_DaemonSocketConsumer_h
+#define mozilla_ipc_DaemonSocketConsumer_h
namespace mozilla {
namespace ipc {
-/*
+class DaemonSocketPDU;
+
+/**
+ * |DaemonSocketIOConsumer| processes incoming PDUs from the
+ * HAL daemon. Please note that its method |Handle| runs on a
+ * different than the consumer thread.
+ */
+class DaemonSocketIOConsumer
+{
+public:
+ virtual ~DaemonSocketIOConsumer();
+
+ virtual void Handle(DaemonSocketPDU& aPDU) = 0;
+ virtual void StoreUserData(const DaemonSocketPDU& aPDU) = 0;
+
+protected:
+ DaemonSocketIOConsumer();
+};
+
+/**
* |DaemonSocketConsumer| handles socket events.
*/
class DaemonSocketConsumer
{
public:
/**
* Callback for socket success. Consumer-thread only.
*
new file mode 100644
--- /dev/null
+++ b/ipc/hal/DaemonSocketPDU.cpp
@@ -0,0 +1,188 @@
+/* -*- 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 "DaemonSocketPDU.h"
+#include "mozilla/ipc/DaemonSocketConsumer.h"
+
+#ifdef CHROMIUM_LOG
+#undef CHROMIUM_LOG
+#endif
+
+#if defined(MOZ_WIDGET_GONK)
+#include <android/log.h>
+#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args);
+#else
+#include <stdio.h>
+#define IODEBUG true
+#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
+#endif
+
+namespace mozilla {
+namespace ipc {
+
+//
+// DaemonSocketPDU
+//
+
+DaemonSocketPDU::DaemonSocketPDU(uint8_t aService, uint8_t aOpcode,
+ uint16_t aPayloadSize)
+ : mConsumer(nullptr)
+ , mUserData(nullptr)
+{
+ // Allocate memory
+ size_t availableSpace = HEADER_SIZE + aPayloadSize;
+ ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
+
+ // Reserve PDU header
+ uint8_t* data = Append(HEADER_SIZE);
+ MOZ_ASSERT(data);
+
+ // Setup PDU header
+ data[OFF_SERVICE] = aService;
+ data[OFF_OPCODE] = aOpcode;
+ memcpy(data + OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize));
+}
+
+DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize)
+ : mConsumer(nullptr)
+ , mUserData(nullptr)
+{
+ size_t availableSpace = HEADER_SIZE + aPayloadSize;
+ ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
+}
+
+DaemonSocketPDU::~DaemonSocketPDU()
+{
+ nsAutoArrayPtr<uint8_t> data(GetBuffer());
+ ResetBuffer(nullptr, 0, 0, 0);
+}
+
+void
+DaemonSocketPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode,
+ uint16_t& aPayloadSize)
+{
+ memcpy(&aService, GetData(OFF_SERVICE), sizeof(aService));
+ memcpy(&aOpcode, GetData(OFF_OPCODE), sizeof(aOpcode));
+ memcpy(&aPayloadSize, GetData(OFF_LENGTH), sizeof(aPayloadSize));
+}
+
+ssize_t
+DaemonSocketPDU::Send(int aFd)
+{
+ struct iovec iv;
+ memset(&iv, 0, sizeof(iv));
+ iv.iov_base = GetData(GetLeadingSpace());
+ iv.iov_len = GetSize();
+
+ struct msghdr msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+ msg.msg_control = nullptr;
+ msg.msg_controllen = 0;
+
+ ssize_t res = TEMP_FAILURE_RETRY(sendmsg(aFd, &msg, 0));
+ if (res < 0) {
+ MOZ_ASSERT(errno != EBADF); /* internal error */
+ OnError("sendmsg", errno);
+ return -1;
+ }
+
+ Consume(res);
+
+ if (mConsumer) {
+ // We successfully sent a PDU, now store the
+ // result runnable in the consumer.
+ mConsumer->StoreUserData(*this);
+ }
+
+ return res;
+}
+
+#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
+ ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
+ ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
+
+ssize_t
+DaemonSocketPDU::Receive(int aFd)
+{
+ struct iovec iv;
+ memset(&iv, 0, sizeof(iv));
+ iv.iov_base = GetData(0);
+ iv.iov_len = GetAvailableSpace();
+
+ uint8_t cmsgbuf[CMSG_SPACE(sizeof(int))];
+
+ struct msghdr msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+
+ ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL));
+ if (res < 0) {
+ MOZ_ASSERT(errno != EBADF); /* internal error */
+ OnError("recvmsg", errno);
+ return -1;
+ }
+ if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
+ return -1;
+ }
+
+ SetRange(0, res);
+
+ struct cmsghdr *chdr = CMSG_FIRSTHDR(&msg);
+
+ for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) {
+ if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) {
+ continue;
+ }
+ // Retrieve sent file descriptor. If multiple file descriptors
+ // have been sent, we close all but the final one.
+ mReceivedFd = *(static_cast<int*>(CMSG_DATA(chdr)));
+ }
+
+ return res;
+}
+
+int
+DaemonSocketPDU::AcquireFd()
+{
+ return mReceivedFd.forget();
+}
+
+nsresult
+DaemonSocketPDU::UpdateHeader()
+{
+ size_t len = GetPayloadSize();
+ if (len >= MAX_PAYLOAD_LENGTH) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ uint16_t len16 = static_cast<uint16_t>(len);
+
+ memcpy(GetData(OFF_LENGTH), &len16, sizeof(len16));
+
+ return NS_OK;
+}
+
+size_t
+DaemonSocketPDU::GetPayloadSize() const
+{
+ MOZ_ASSERT(GetSize() >= HEADER_SIZE);
+
+ return GetSize() - HEADER_SIZE;
+}
+
+void
+DaemonSocketPDU::OnError(const char* aFunction, int aErrno)
+{
+ CHROMIUM_LOG("%s failed with error %d (%s)",
+ aFunction, aErrno, strerror(aErrno));
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/ipc/hal/DaemonSocketPDU.h
@@ -0,0 +1,91 @@
+/* -*- 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_DaemonSocketPDU_h
+#define mozilla_ipc_DaemonSocketPDU_h
+
+#include "mozilla/FileUtils.h"
+#include "mozilla/ipc/SocketBase.h"
+
+namespace mozilla {
+namespace ipc {
+
+class DaemonSocketIOConsumer;
+
+/**
+ * |DaemonSocketPDU| represents a single PDU that is transfered from or to
+ * the HAL daemon. Each PDU contains exactly one command.
+ *
+ * A PDU as the following format
+ *
+ * | 1 | 1 | 2 | n |
+ * | service | opcode | payload length | payload |
+ *
+ * Service and Opcode each require 1 byte, the payload length requires 2
+ * bytes, and the payload requires the number of bytes as stored in the
+ * payload-length field.
+ *
+ * Each service and opcode can have a different payload with individual
+ * length. For the exact details of the HAL protocol, please refer to
+ *
+ * https://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/hal-ipc-api.txt?id=5.24
+ *
+ */
+class DaemonSocketPDU final : public UnixSocketIOBuffer
+{
+public:
+ enum {
+ OFF_SERVICE = 0,
+ OFF_OPCODE = 1,
+ OFF_LENGTH = 2,
+ OFF_PAYLOAD = 4,
+ HEADER_SIZE = OFF_PAYLOAD,
+ MAX_PAYLOAD_LENGTH = 1 << 16
+ };
+
+ DaemonSocketPDU(uint8_t aService, uint8_t aOpcode, uint16_t aPayloadSize);
+ DaemonSocketPDU(size_t aPayloadSize);
+ ~DaemonSocketPDU();
+
+ void SetConsumer(DaemonSocketIOConsumer* aConsumer)
+ {
+ mConsumer = aConsumer;
+ }
+
+ void SetUserData(void* aUserData)
+ {
+ mUserData = aUserData;
+ }
+
+ void* GetUserData() const
+ {
+ return mUserData;
+ }
+
+ void GetHeader(uint8_t& aService, uint8_t& aOpcode,
+ uint16_t& aPayloadSize);
+
+ ssize_t Send(int aFd) override;
+ ssize_t Receive(int aFd) override;
+
+ int AcquireFd();
+
+ nsresult UpdateHeader();
+
+private:
+ size_t GetPayloadSize() const;
+ void OnError(const char* aFunction, int aErrno);
+
+ DaemonSocketIOConsumer* mConsumer;
+ void* mUserData;
+ ScopedClose mReceivedFd;
+};
+
+}
+}
+
+#endif
+
rename from ipc/bluetooth/moz.build
rename to ipc/hal/moz.build
--- a/ipc/bluetooth/moz.build
+++ b/ipc/hal/moz.build
@@ -1,21 +1,23 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS.mozilla.ipc += [
- 'BluetoothDaemonConnection.h',
- 'BluetoothDaemonConnectionConsumer.h'
+ 'DaemonSocket.h',
+ 'DaemonSocketConsumer.h',
+ 'DaemonSocketPDU.h'
]
-SOURCES += [
- 'BluetoothDaemonConnection.cpp',
- 'BluetoothDaemonConnectionConsumer.cpp'
+UNIFIED_SOURCES += [
+ 'DaemonSocket.cpp',
+ 'DaemonSocketConsumer.cpp',
+ 'DaemonSocketPDU.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
FAIL_ON_WARNINGS = True
--- a/ipc/moz.build
+++ b/ipc/moz.build
@@ -9,27 +9,24 @@ DIRS += [
'glue',
'ipdl',
'testshell',
]
if CONFIG['MOZ_B2G_RIL']:
DIRS += ['ril']
-if CONFIG['MOZ_B2G_BT_BLUEDROID']:
- DIRS += ['bluetooth']
-
if CONFIG['MOZ_B2G_BT_BLUEZ']:
DIRS += ['dbus']
if CONFIG['MOZ_NFC']:
DIRS += ['nfc']
if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT'] or CONFIG['MOZ_NFC'] or CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['unixfd', 'unixsocket']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
- DIRS += ['keystore', 'netd']
+ DIRS += ['hal', 'keystore', 'netd']
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
DIRS += ['contentproc']
DIRS += ['app']