1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/bluetooth/bluez/BluetoothOppManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,222 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_bluetooth_bluetoothoppmanager_h__ 1.11 +#define mozilla_dom_bluetooth_bluetoothoppmanager_h__ 1.12 + 1.13 +#include "BluetoothCommon.h" 1.14 +#include "BluetoothProfileManagerBase.h" 1.15 +#include "BluetoothSocketObserver.h" 1.16 +#include "DeviceStorage.h" 1.17 +#include "mozilla/dom/ipc/Blob.h" 1.18 +#include "mozilla/ipc/UnixSocket.h" 1.19 +#include "nsCOMArray.h" 1.20 + 1.21 +class nsIOutputStream; 1.22 +class nsIInputStream; 1.23 +class nsIVolumeMountLock; 1.24 + 1.25 +BEGIN_BLUETOOTH_NAMESPACE 1.26 + 1.27 +class BluetoothSocket; 1.28 +class ObexHeaderSet; 1.29 +class SendFileBatch; 1.30 + 1.31 +class BluetoothOppManager : public BluetoothSocketObserver 1.32 + , public BluetoothProfileManagerBase 1.33 +{ 1.34 +public: 1.35 + BT_DECL_PROFILE_MGR_BASE 1.36 + virtual void GetName(nsACString& aName) 1.37 + { 1.38 + aName.AssignLiteral("OPP"); 1.39 + } 1.40 + 1.41 + static const int MAX_PACKET_LENGTH = 0xFFFE; 1.42 + 1.43 + virtual ~BluetoothOppManager(); 1.44 + static BluetoothOppManager* Get(); 1.45 + void ClientDataHandler(mozilla::ipc::UnixSocketRawData* aMessage); 1.46 + void ServerDataHandler(mozilla::ipc::UnixSocketRawData* aMessage); 1.47 + 1.48 + bool Listen(); 1.49 + 1.50 + bool SendFile(const nsAString& aDeviceAddress, BlobParent* aActor); 1.51 + bool SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob); 1.52 + bool StopSendingFile(); 1.53 + bool ConfirmReceivingFile(bool aConfirm); 1.54 + 1.55 + void SendConnectRequest(); 1.56 + void SendPutHeaderRequest(const nsAString& aFileName, int aFileSize); 1.57 + void SendPutRequest(uint8_t* aFileBody, int aFileBodyLength); 1.58 + void SendPutFinalRequest(); 1.59 + void SendDisconnectRequest(); 1.60 + 1.61 + void ExtractPacketHeaders(const ObexHeaderSet& aHeader); 1.62 + bool ExtractBlobHeaders(); 1.63 + void CheckPutFinal(uint32_t aNumRead); 1.64 + 1.65 + // The following functions are inherited from BluetoothSocketObserver 1.66 + void ReceiveSocketData( 1.67 + BluetoothSocket* aSocket, 1.68 + nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE; 1.69 + virtual void OnSocketConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE; 1.70 + virtual void OnSocketConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE; 1.71 + virtual void OnSocketDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE; 1.72 + 1.73 +private: 1.74 + BluetoothOppManager(); 1.75 + bool Init(); 1.76 + void HandleShutdown(); 1.77 + 1.78 + void StartFileTransfer(); 1.79 + void StartSendingNextFile(); 1.80 + void FileTransferComplete(); 1.81 + void UpdateProgress(); 1.82 + void ReceivingFileConfirmation(); 1.83 + bool CreateFile(); 1.84 + bool WriteToFile(const uint8_t* aData, int aDataLength); 1.85 + void DeleteReceivedFile(); 1.86 + void ReplyToConnect(); 1.87 + void ReplyToDisconnectOrAbort(); 1.88 + void ReplyToPut(bool aFinal, bool aContinue); 1.89 + void ReplyError(uint8_t aError); 1.90 + void AfterOppConnected(); 1.91 + void AfterFirstPut(); 1.92 + void AfterOppDisconnected(); 1.93 + void ValidateFileName(); 1.94 + bool IsReservedChar(char16_t c); 1.95 + void ClearQueue(); 1.96 + void RetrieveSentFileName(); 1.97 + void NotifyAboutFileChange(); 1.98 + bool AcquireSdcardMountLock(); 1.99 + void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize); 1.100 + void AppendBlobToSend(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob); 1.101 + void DiscardBlobsToSend(); 1.102 + bool ProcessNextBatch(); 1.103 + void ConnectInternal(const nsAString& aDeviceAddress); 1.104 + 1.105 + /** 1.106 + * Usually we won't get a full PUT packet in one operation, which means that 1.107 + * a packet may be devided into several parts and BluetoothOppManager should 1.108 + * be in charge of assembling. 1.109 + * 1.110 + * @return true if a packet has been fully received. 1.111 + * false if the received length exceeds/not reaches the expected 1.112 + * length. 1.113 + */ 1.114 + bool ComposePacket(uint8_t aOpCode, 1.115 + mozilla::ipc::UnixSocketRawData* aMessage); 1.116 + 1.117 + /** 1.118 + * OBEX session status. 1.119 + * Set when OBEX session is established. 1.120 + */ 1.121 + bool mConnected; 1.122 + nsString mConnectedDeviceAddress; 1.123 + 1.124 + /** 1.125 + * Remote information 1.126 + */ 1.127 + uint8_t mRemoteObexVersion; 1.128 + uint8_t mRemoteConnectionFlags; 1.129 + int mRemoteMaxPacketLength; 1.130 + 1.131 + /** 1.132 + * For sending files, we decide our next action based on current command and 1.133 + * previous one. 1.134 + * For receiving files, we don't need previous command and it is set to 0 1.135 + * as a default value. 1.136 + */ 1.137 + int mLastCommand; 1.138 + 1.139 + int mPacketLength; 1.140 + int mPutPacketReceivedLength; 1.141 + int mBodySegmentLength; 1.142 + int mUpdateProgressCounter; 1.143 + 1.144 + /** 1.145 + * When it is true and the target service on target device couldn't be found, 1.146 + * refreshing SDP records is necessary. 1.147 + */ 1.148 + bool mNeedsUpdatingSdpRecords; 1.149 + 1.150 + /** 1.151 + * Set when StopSendingFile() is called. 1.152 + */ 1.153 + bool mAbortFlag; 1.154 + 1.155 + /** 1.156 + * Set when receiving the first PUT packet of a new file 1.157 + */ 1.158 + bool mNewFileFlag; 1.159 + 1.160 + /** 1.161 + * Set when receiving a PutFinal packet 1.162 + */ 1.163 + bool mPutFinalFlag; 1.164 + 1.165 + /** 1.166 + * Set when FileTransferComplete() is called 1.167 + */ 1.168 + bool mSendTransferCompleteFlag; 1.169 + 1.170 + /** 1.171 + * Set when a transfer is successfully completed. 1.172 + */ 1.173 + bool mSuccessFlag; 1.174 + 1.175 + /** 1.176 + * True: Receive file (Server) 1.177 + * False: Send file (Client) 1.178 + */ 1.179 + bool mIsServer; 1.180 + 1.181 + /** 1.182 + * Set when receiving the first PUT packet and wait for 1.183 + * ConfirmReceivingFile() to be called. 1.184 + */ 1.185 + bool mWaitingForConfirmationFlag; 1.186 + 1.187 + nsString mFileName; 1.188 + nsString mContentType; 1.189 + uint32_t mFileLength; 1.190 + uint32_t mSentFileLength; 1.191 + bool mWaitingToSendPutFinal; 1.192 + 1.193 + nsAutoArrayPtr<uint8_t> mBodySegment; 1.194 + nsAutoArrayPtr<uint8_t> mReceivedDataBuffer; 1.195 + 1.196 + int mCurrentBlobIndex; 1.197 + nsCOMPtr<nsIDOMBlob> mBlob; 1.198 + nsTArray<SendFileBatch> mBatches; 1.199 + 1.200 + /** 1.201 + * A seperate member thread is required because our read calls can block 1.202 + * execution, which is not allowed to happen on the IOThread. 1.203 + */ 1.204 + nsCOMPtr<nsIThread> mReadFileThread; 1.205 + nsCOMPtr<nsIOutputStream> mOutputStream; 1.206 + nsCOMPtr<nsIInputStream> mInputStream; 1.207 + nsCOMPtr<nsIVolumeMountLock> mMountLock; 1.208 + nsRefPtr<DeviceStorageFile> mDsFile; 1.209 + 1.210 + // If a connection has been established, mSocket will be the socket 1.211 + // communicating with the remote socket. We maintain the invariant that if 1.212 + // mSocket is non-null, mRfcommSocket and mL2capSocket must be null (and vice 1.213 + // versa). 1.214 + nsRefPtr<BluetoothSocket> mSocket; 1.215 + 1.216 + // Server sockets. Once an inbound connection is established, it will hand 1.217 + // over the ownership to mSocket, and get a new server socket while Listen() 1.218 + // is called. 1.219 + nsRefPtr<BluetoothSocket> mRfcommSocket; 1.220 + nsRefPtr<BluetoothSocket> mL2capSocket; 1.221 +}; 1.222 + 1.223 +END_BLUETOOTH_NAMESPACE 1.224 + 1.225 +#endif