2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // @file FNetBtBluetoothOppClientImpl.cpp
18 // @brief This is the implementation file for the _BluetoothOppClientImpl class.
21 #include <FNetBtBluetoothTypes.h>
22 #include <FNetBtBluetoothDevice.h>
23 #include <FNetBtIBluetoothOppClientEventListener.h>
24 #include <FBaseSysLog.h>
25 #include <FIo_FileImpl.h>
26 #include <FApp_AppInfo.h>
27 #include "FNetBt_BluetoothOppClientImpl.h"
28 #include "FNetBt_BluetoothOppSystemAdapter.h"
29 #include "FNetBt_BluetoothGapSystemAdapter.h"
30 #include "FNetBt_BluetoothOppClientEvent.h"
31 #include "FNetBt_BluetoothOppClientEventArg.h"
34 using namespace Tizen::App;
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Runtime;
38 namespace Tizen { namespace Net { namespace Bluetooth
41 _BluetoothOppClientImpl::_BluetoothOppClientImpl(void)
46 , __currentState(_BT_OPP_CLI_STATE_DISABLED)
49 , __minProgressInterval(__defaultProgressInterval)
50 , __previousProgress(0)
54 _BluetoothOppClientImpl::~_BluetoothOppClientImpl(void)
56 if (__pOppAdapter != null)
58 if ((__currentState == _BT_OPP_CLI_STATE_PUSH_READY)
59 || (__currentState == _BT_OPP_CLI_STATE_ON_TRANSFER))
65 if (__pGapAdapter != null)
67 __pGapAdapter->UnregisterManagerEventListener(*this);
68 __pGapAdapter->UnregisterDeviceEventListener(*this);
73 _BluetoothOppClientImpl::Construct(IBluetoothOppClientEventListener& listener)
76 std::unique_ptr<_BluetoothOppClientEvent> pEvent;
78 r = __stateMutex.Create();
79 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create the state mutex.");
81 r = __pairingAddress.Construct(_BT_ADDRESS_LENGTH);
82 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct the address for pairing.");
84 __pGapAdapter = _BluetoothGapSystemAdapter::GetInstance();
85 SysTryReturn(NID_NET_BT, __pGapAdapter != null, E_SYSTEM, E_SYSTEM,
86 "[E_SYSTEM] Failed to invoke _BluetoothGapSystemAdapter::GetInstance().");
88 __pOppAdapter = _BluetoothOppSystemAdapter::GetInstance();
90 pEvent.reset(new (std::nothrow) _BluetoothOppClientEvent());
91 SysTryReturn(NID_NET_BT, pEvent != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
92 r = pEvent->Construct();
93 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct the event.");
94 // add the IBluetoothOppClientEventListener instance to a new created _BluetoothOppClientEvent.
95 r = pEvent->AddListener(listener, true);
96 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
97 "[%s] Propagating. Failed to add the application listener for OPP client", GetErrorMessage(r));
99 // registers this callback listener to the system adapter for activation/deactivation event
100 r = __pGapAdapter->RegisterManagerEventListener(*this, true);
101 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
102 "[E_SYSTEM] Failed to register the callback listener to _BluetoothGapSystemAdapter.");
104 // registers this callback listener to the system adapter for paired event
105 r = __pGapAdapter->RegisterDeviceEventListener(*this);
108 __pGapAdapter->UnregisterManagerEventListener(*this);
110 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
111 "[E_SYSTEM] Failed to register the callback listener to _BluetoothGapSystemAdapter.");
113 // checks whether the Bluetooth is available
114 __stateMutex.Acquire();
116 if (__pGapAdapter->IsActivated() == true)
118 __currentState = _BT_OPP_CLI_STATE_IDLE;
121 __stateMutex.Release();
123 __pEvent = move(pEvent);
130 _BluetoothOppClientImpl::PushFile(const BluetoothDevice& remoteDevice, const Base::String& filePath)
132 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
134 result r = E_FAILURE;
137 __stateMutex.Acquire();
139 switch (__currentState)
141 case _BT_OPP_CLI_STATE_DISABLED:
145 case _BT_OPP_CLI_STATE_IDLE:
146 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
148 if (Tizen::Io::_FileImpl::ConvertVirtualToPhysicalPath(filePath, physicalPath) != E_SUCCESS)
150 r = E_INACCESSIBLE_PATH;
156 physicalPath = filePath;
159 if (__pGapAdapter->IsPaired(*(remoteDevice.GetAddress())) == true)
161 r = __pOppAdapter->PushOppFile(*this, *(remoteDevice.GetAddress()), physicalPath);
164 __currentState = _BT_OPP_CLI_STATE_PUSH_READY;
169 // start the pairing process
170 if (__pGapAdapter->Pair(*(remoteDevice.GetAddress())) == E_SUCCESS)
172 // copy the address of the pairing device to the local variable
173 __pairingAddress.SetArray(remoteDevice.GetAddress()->GetPointer(), 0, _BT_ADDRESS_LENGTH);
174 __pairingAddress.SetPosition(0);
175 // copy the file path to the local variable
176 __pushedFilePath.Clear();
177 __pushedFilePath = physicalPath;
180 __currentState = _BT_OPP_CLI_STATE_BONDING;
189 case _BT_OPP_CLI_STATE_BONDING:
190 case _BT_OPP_CLI_STATE_PUSH_READY:
191 case _BT_OPP_CLI_STATE_REQ_CANCELING: //TODO: this state should return E_INVALID_OPERATION. (Versioning)
192 case _BT_OPP_CLI_STATE_ON_TRANSFER:
193 case _BT_OPP_CLI_STATE_TRANS_CANCELING: //TODO: this state should return E_INVALID_OPERATION. (Versioning)
198 // ignore other cases
202 __stateMutex.Release();
206 SysLogException(NID_NET_BT, r, "[%s] exception occurred on pushing a file.", GetErrorMessage(r));
209 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
215 _BluetoothOppClientImpl::CancelPush()
217 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
219 result r = E_FAILURE;
221 __stateMutex.Acquire();
223 switch (__currentState)
225 case _BT_OPP_CLI_STATE_DISABLED:
229 case _BT_OPP_CLI_STATE_IDLE:
230 r = E_INVALID_OPERATION;
233 case _BT_OPP_CLI_STATE_REQ_CANCELING:
234 case _BT_OPP_CLI_STATE_TRANS_CANCELING:
238 case _BT_OPP_CLI_STATE_BONDING: //TODO: Versioning check
239 if (__pGapAdapter->CancelPair() == E_SUCCESS)
242 __currentState = _BT_OPP_CLI_STATE_REQ_CANCELING;
244 // It will be changed to IDLE after receiving the OnBluetoothPaired event.
247 case _BT_OPP_CLI_STATE_PUSH_READY:
248 r = __pOppAdapter->CancelOppPush();
252 __currentState = _BT_OPP_CLI_STATE_REQ_CANCELING;
254 // It will be changed to IDLE after receiving the OnOppTransferDone event.
257 case _BT_OPP_CLI_STATE_ON_TRANSFER:
258 r = __pOppAdapter->CancelOppPush();
262 __currentState = _BT_OPP_CLI_STATE_TRANS_CANCELING;
264 // It will be changed to IDLE after receiving the OnOppTransferDone event.
268 // ignore other cases
272 __stateMutex.Release();
276 SysLogException(NID_NET_BT, r, "[%s] exception occurred on canceling the push.", GetErrorMessage(r));
279 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
285 _BluetoothOppClientImpl::SetMinProgressInterval(int percent)
287 result r = E_SUCCESS;
289 if ((percent < 1) || (percent > 100))
292 SysLogException(NID_NET_BT, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The input argument - percent - is outside the valid range.");
296 __minProgressInterval = percent;
303 _BluetoothOppClientImpl::OnBluetoothActivated(result r)
305 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
307 __stateMutex.Acquire();
309 if ((__currentState == _BT_OPP_CLI_STATE_DISABLED)
312 __currentState = _BT_OPP_CLI_STATE_IDLE;
315 __stateMutex.Release();
317 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
321 _BluetoothOppClientImpl::OnBluetoothDeactivated(result r)
323 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
325 __stateMutex.Acquire();
329 __currentState = _BT_OPP_CLI_STATE_DISABLED;
332 __stateMutex.Release();
334 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
338 _BluetoothOppClientImpl::OnOppPushResponded(result r)
340 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
342 bool isFired = false;
344 __stateMutex.Acquire();
346 if ((__currentState == _BT_OPP_CLI_STATE_PUSH_READY) || (__currentState == _BT_OPP_CLI_STATE_REQ_CANCELING))
350 __currentState = _BT_OPP_CLI_STATE_ON_TRANSFER;
352 else // including both cases of being canceled by the user and rejected by the remote device
354 __currentState = _BT_OPP_CLI_STATE_IDLE;
355 SysLogException(NID_NET_BT, r, "[%s] exception occurred on the response of the OPP push request.", GetErrorMessage(r));
361 __stateMutex.Release();
365 _BluetoothOppClientEventArg* pArg = new (std::nothrow) _BluetoothOppClientEventArg(r);
368 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
373 __pEvent->FireAsync(*pArg);
377 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [PUSH_RESPONDED_Event:%s]",
378 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
382 _BluetoothOppClientImpl::OnOppTransferInProgress(int percent)
384 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [Progress:%d]", GetStringOfCurrentState(), percent);
386 bool isFired = false;
388 __stateMutex.Acquire();
390 if ((__currentState == _BT_OPP_CLI_STATE_ON_TRANSFER) || (__currentState == _BT_OPP_CLI_STATE_TRANS_CANCELING))
392 if (((percent - __previousProgress) >= __minProgressInterval) || (percent >= 100))
395 __previousProgress = percent;
399 __stateMutex.Release();
403 _BluetoothOppClientEventArg* pArg = new (std::nothrow) _BluetoothOppClientEventArg(percent);
406 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
411 __pEvent->FireAsync(*pArg);
415 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [TRANSFER_IN_PROGRESS_Event:%s]",
416 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
420 _BluetoothOppClientImpl::OnOppTransferDone(const Tizen::Base::String& filePath, int fileSize, bool isCompleted)
422 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [filePath:%ls], [fileSize:%d], [%s]",
423 GetStringOfCurrentState(), filePath.GetPointer(), fileSize, isCompleted ? "Completed" : "Incompleted");
425 bool isFired = false;
426 String pushedFilePath;
427 result r = E_SUCCESS;
429 __stateMutex.Acquire();
431 if ((__currentState == _BT_OPP_CLI_STATE_ON_TRANSFER) || (__currentState == _BT_OPP_CLI_STATE_TRANS_CANCELING))
433 __currentState = _BT_OPP_CLI_STATE_IDLE;
435 __previousProgress = 0; // initialization for the next push transaction
438 __stateMutex.Release();
440 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
442 r = Tizen::Io::_FileImpl::ConvertPhysicalToVirtualPath(__pushedFilePath, pushedFilePath);
445 SysLogException(NID_NET_BT, r, "[%s] exception occurred on converting the file path from physical to virtual.", GetErrorMessage(r));
446 pushedFilePath = __pushedFilePath;
451 pushedFilePath = __pushedFilePath;
456 _BluetoothOppClientEventArg* pArg = new (std::nothrow) _BluetoothOppClientEventArg(pushedFilePath, fileSize, isCompleted);
459 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
464 __pEvent->FireAsync(*pArg);
468 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [TRANSFER_DONE_Event:%s]",
469 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
473 _BluetoothOppClientImpl::OnBluetoothPaired(const BluetoothDevice* pPairedDevice, result r)
475 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
477 bool isFired = false;
478 result responseResult = E_SYSTEM;
480 __stateMutex.Acquire();
482 if (pPairedDevice->GetAddress()->Equals(__pairingAddress))
484 if (__currentState == _BT_OPP_CLI_STATE_BONDING)
488 if (__pOppAdapter->PushOppFile(*this, __pairingAddress, __pushedFilePath) == E_SUCCESS)
490 __currentState = _BT_OPP_CLI_STATE_PUSH_READY;
494 // callback responded with E_SYSTEM
496 __currentState = _BT_OPP_CLI_STATE_IDLE;
497 responseResult = E_SYSTEM;
502 // callback responded with r
504 __currentState = _BT_OPP_CLI_STATE_IDLE;
508 __pairingAddress.Clear();
510 else if (__currentState == _BT_OPP_CLI_STATE_REQ_CANCELING)
512 // callback responded with E_SYSTEM or E_OPERATION_CANCELED
514 __currentState = _BT_OPP_CLI_STATE_IDLE;
515 responseResult = E_SYSTEM;
520 __stateMutex.Release();
524 _BluetoothOppClientEventArg* pArg = new (std::nothrow) _BluetoothOppClientEventArg(responseResult);
527 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
532 __pEvent->FireAsync(*pArg);
536 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [PUSH_RESPONDED_Event:%s]",
537 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
541 _BluetoothOppClientImpl::GetStringOfCurrentState(void) const
543 const char* pStateString = null;
545 switch (__currentState)
547 case _BT_OPP_CLI_STATE_DISABLED:
548 pStateString = "DISABLED";
551 case _BT_OPP_CLI_STATE_IDLE:
552 pStateString = "IDLE";
555 case _BT_OPP_CLI_STATE_BONDING:
556 pStateString = "BONDING";
559 case _BT_OPP_CLI_STATE_PUSH_READY:
560 pStateString = "PUSH_READY";
563 case _BT_OPP_CLI_STATE_REQ_CANCELING:
564 pStateString = "REQ_CANCELING";
567 case _BT_OPP_CLI_STATE_ON_TRANSFER:
568 pStateString = "ON_TRANSFER";
571 case _BT_OPP_CLI_STATE_TRANS_CANCELING:
572 pStateString = "TRANS_CANCELING";
576 pStateString = "Unknown";
583 } } } // Tizen::Net::Bluetooth