/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=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_BluetoothSocketMessageWatcher_h #define mozilla_dom_bluetooth_bluedroid_BluetoothSocketMessageWatcher_h #include "base/message_loop.h" #include "BluetoothCommon.h" BEGIN_BLUETOOTH_NAMESPACE class BluetoothSocketResultHandler; /* |SocketMessageWatcher| receives Bluedroid's socket setup * messages on the I/O thread. You need to inherit from this * class to make use of it. * * Bluedroid sends two socket info messages (20 bytes) at * the beginning of a connection to both peers. * * - 1st message: [channel:4] * - 2nd message: [size:2][bd address:6][channel:4][connection status:4] * * On the server side, the second message will contain a * socket file descriptor for the connection. The client * uses the original file descriptor. */ class SocketMessageWatcher : public MessageLoopForIO::Watcher { public: static const unsigned char MSG1_SIZE = 4; static const unsigned char MSG2_SIZE = 16; static const unsigned char OFF_CHANNEL1 = 0; static const unsigned char OFF_SIZE = 4; static const unsigned char OFF_BDADDRESS = 6; static const unsigned char OFF_CHANNEL2 = 12; static const unsigned char OFF_STATUS = 16; virtual ~SocketMessageWatcher(); virtual void Proceed(BluetoothStatus aStatus) = 0; void OnFileCanReadWithoutBlocking(int aFd) override; void OnFileCanWriteWithoutBlocking(int aFd) override; void Watch(); void StopWatching(); bool IsComplete() const; int GetFd() const; int32_t GetChannel1() const; int32_t GetSize() const; BluetoothAddress GetBdAddress() const; int32_t GetChannel2() const; int32_t GetConnectionStatus() const; int GetClientFd() const; BluetoothSocketResultHandler* GetResultHandler() const; protected: SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes); private: BluetoothStatus RecvMsg1(); BluetoothStatus RecvMsg2(); int16_t ReadInt16(unsigned long aOffset) const; int32_t ReadInt32(unsigned long aOffset) const; void ReadBdAddress(unsigned long aOffset, BluetoothAddress& aBdAddress) const; MessageLoopForIO::FileDescriptorWatcher mWatcher; int mFd; int mClientFd; unsigned char mLen; uint8_t mBuf[MSG1_SIZE + MSG2_SIZE]; RefPtr mRes; }; /* |SocketMessageWatcherTask| starts a SocketMessageWatcher * on the I/O task */ class SocketMessageWatcherTask final : public Task { public: SocketMessageWatcherTask(SocketMessageWatcher* aWatcher); void Run() override; private: SocketMessageWatcher* mWatcher; }; /* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher * on the I/O task */ class DeleteSocketMessageWatcherTask final : public Task { public: DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes); void Run() override; private: BluetoothSocketResultHandler* mRes; }; END_BLUETOOTH_NAMESPACE #endif // mozilla_dom_bluetooth_bluedroid_BluetoothSocketMessageWatcher_h