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 FNetBt_BluetoothSppInitiatorImpl.cpp
18 // @brief This is the implementation file for the _BluetoothSppInitiatorImpl class.
21 #include <FOspConfig.h>
22 #include <FBaseUuId.h>
23 #include <FNetBtBluetoothTypes.h>
24 #include <FNetBtBluetoothDevice.h>
25 #include <FNetBtIBluetoothSppInitiatorEventListener.h>
26 #include <FBaseSysLog.h>
27 #include "FNetBt_BluetoothSppInitiatorEvent.h"
28 #include "FNetBt_BluetoothSppInitiatorEventArg.h"
29 #include "FNetBt_BluetoothGapSystemAdapter.h"
30 #include "FNetBt_BluetoothSppSystemAdapter.h"
31 #include "FNetBt_BluetoothSppInitiatorImpl.h"
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Runtime;
37 namespace Tizen { namespace Net { namespace Bluetooth
40 _BluetoothSppInitiatorImpl::_BluetoothSppInitiatorImpl(void)
45 , __currentState(_BT_SPP_INI_STATE_DISABLED)
48 , __socketFd(_BT_INVALID_SOCKET_FD)
52 _BluetoothSppInitiatorImpl::~_BluetoothSppInitiatorImpl(void)
54 if (__pSppAdapter != null)
56 if ((__currentState == _BT_SPP_INI_STATE_BONDING)
57 || (__currentState == _BT_SPP_INI_STATE_CONNECT_READY)
58 || (__currentState == _BT_SPP_INI_STATE_CONNECTED))
60 (void) ProcessAsyncDisconnect(); // Ignores the result of this function.
64 if (__pGapAdapter != null)
66 __pGapAdapter->UnregisterManagerEventListener(*this);
67 __pGapAdapter->UnregisterDeviceEventListener(*this);
72 _BluetoothSppInitiatorImpl::Construct(IBluetoothSppInitiatorEventListener& listener)
75 std::unique_ptr<_BluetoothSppInitiatorEvent> pEvent;
77 r = __stateMutex.Create();
78 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create the state mutex.");
80 r = __pairingAddress.Construct(_BT_ADDRESS_LENGTH);
81 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct the address for pairing.");
83 __pGapAdapter = _BluetoothGapSystemAdapter::GetInstance();
84 SysTryReturn(NID_NET_BT, __pGapAdapter != null, E_SYSTEM, E_SYSTEM,
85 "[E_SYSTEM] Failed to invoke _BluetoothGapSystemAdapter::GetInstance().");
87 __pSppAdapter = _BluetoothSppSystemAdapter::GetInstance();
88 SysTryReturn(NID_NET_BT, __pSppAdapter != null, E_SYSTEM, E_SYSTEM,
89 "[E_SYSTEM] Failed to invoke _BluetoothSppSystemAdapter::GetInstance().");
91 pEvent.reset(new (std::nothrow) _BluetoothSppInitiatorEvent());
92 SysTryReturn(NID_NET_BT, pEvent != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
94 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct the event.");
95 // add the IBluetoothSppInitiatorEventListener instance to a new created _BluetoothSppInitiatorEvent.
96 r = pEvent->AddListener(listener, true);
97 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
98 "[%s] Propagating. Failed to add the application listener for SPP Initiator", GetErrorMessage(r));
100 // registers this callback listener to the system adapter for activation/deactivation event
101 r = __pGapAdapter->RegisterManagerEventListener(*this, true);
102 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
103 "[E_SYSTEM] Failed to register the callback listener to _BluetoothGapSystemAdapter.");
105 // registers this callback listener to the system adapter for paired event
106 r = __pGapAdapter->RegisterDeviceEventListener(*this);
109 __pGapAdapter->UnregisterManagerEventListener(*this);
111 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
112 "[E_SYSTEM] Failed to register the callback listener to _BluetoothGapSystemAdapter.");
114 // checks whether the Bluetooth is available
115 __stateMutex.Acquire();
117 if (__pGapAdapter->IsActivated() == true)
119 __currentState = _BT_SPP_INI_STATE_IDLE;
122 __stateMutex.Release();
124 __pEvent = move(pEvent);
130 _BluetoothSppInitiatorImpl::SendData(const Tizen::Base::ByteBuffer& buffer)
132 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
134 result r = E_FAILURE;
136 __stateMutex.Acquire();
138 switch (__currentState)
140 case _BT_SPP_INI_STATE_DISABLED:
144 case _BT_SPP_INI_STATE_IDLE:
145 case _BT_SPP_INI_STATE_BONDING: //TODO: this state should return E_INVALID_OPERATION. Versioning
146 case _BT_SPP_INI_STATE_CONNECT_READY:
147 case _BT_SPP_INI_STATE_REQ_CANCELING: //TODO: this state should return E_INVALID_OPERATION. Versioning
148 r = E_INVALID_OPERATION;
151 case _BT_SPP_INI_STATE_CONNECTED:
152 if (buffer.GetRemaining() > 0)
154 r = __pSppAdapter->SendSocketData(__socketFd, buffer);
167 __stateMutex.Release();
171 SysLogException(NID_NET_BT, r, "[%s] exception occurred on sending data.", GetErrorMessage(r));
174 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
180 _BluetoothSppInitiatorImpl::Connect(const BluetoothDevice& remoteDevice, const Tizen::Base::UuId& serviceUuid)
182 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
184 result r = E_FAILURE;
186 __stateMutex.Acquire();
188 switch (__currentState)
190 case _BT_SPP_INI_STATE_DISABLED:
191 case _BT_SPP_INI_STATE_REQ_CANCELING:
195 case _BT_SPP_INI_STATE_IDLE:
196 if (__pGapAdapter->IsPaired(*(remoteDevice.GetAddress())) == true)
198 r = __pSppAdapter->ConnectSocket(*(remoteDevice.GetAddress()), serviceUuid, *this);
201 __currentState = _BT_SPP_INI_STATE_CONNECT_READY;
206 // start the pairing process
207 if (__pGapAdapter->Pair(*(remoteDevice.GetAddress())) == E_SUCCESS)
209 // copy the address of the pairing device to the local variable
210 __pairingAddress.SetArray(remoteDevice.GetAddress()->GetPointer(), 0, _BT_ADDRESS_LENGTH);
211 __pairingAddress.SetPosition(0);
212 __pairingUuid = serviceUuid;
215 __currentState = _BT_SPP_INI_STATE_BONDING;
224 case _BT_SPP_INI_STATE_BONDING: //TODO: Versioning check
225 case _BT_SPP_INI_STATE_CONNECT_READY:
229 case _BT_SPP_INI_STATE_CONNECTED:
230 r = E_ALREADY_CONNECTED;
238 __stateMutex.Release();
242 SysLogException(NID_NET_BT, r, "[%s] exception occurred on requesting a connection.", GetErrorMessage(r));
245 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
251 _BluetoothSppInitiatorImpl::Disconnect(void)
253 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
255 result r = E_FAILURE;
257 __stateMutex.Acquire();
259 switch (__currentState)
261 case _BT_SPP_INI_STATE_DISABLED:
265 case _BT_SPP_INI_STATE_IDLE:
266 r = E_INVALID_OPERATION;
269 case _BT_SPP_INI_STATE_BONDING: //TODO: Versioning check
270 if (__pGapAdapter->CancelPair() == E_SUCCESS)
273 __currentState = _BT_SPP_INI_STATE_REQ_CANCELING;
275 // It will be changed to IDLE after receiving the OnBluetoothPaired event.
278 case _BT_SPP_INI_STATE_CONNECT_READY:
279 // TODO: how does it cancel to request the connection? __socketFd is not determined at this time.
280 r = ProcessAsyncDisconnect();
283 __currentState = _BT_SPP_INI_STATE_REQ_CANCELING;
285 // It will be changed to IDLE after receiving the OnSppDisconnected event.
288 case _BT_SPP_INI_STATE_REQ_CANCELING:
292 case _BT_SPP_INI_STATE_CONNECTED:
293 r = ProcessAsyncDisconnect();
296 __currentState = _BT_SPP_INI_STATE_IDLE;
298 // It will be changed to IDLE after receiving the OnSppDisconnected event.
306 __stateMutex.Release();
310 SysLogException(NID_NET_BT, r, "[%s] exception occurred on disconnecting the connection.", GetErrorMessage(r));
313 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
319 _BluetoothSppInitiatorImpl::OnBluetoothActivated(result r)
321 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
323 __stateMutex.Acquire();
325 if ((__currentState == _BT_SPP_INI_STATE_DISABLED) && (r == E_SUCCESS))
327 __currentState = _BT_SPP_INI_STATE_IDLE;
329 __stateMutex.Release();
331 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
335 _BluetoothSppInitiatorImpl::OnBluetoothDeactivated(result r)
337 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
339 __stateMutex.Acquire();
343 __currentState = _BT_SPP_INI_STATE_DISABLED;
346 __stateMutex.Release();
348 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
352 _BluetoothSppInitiatorImpl::OnSocketConnectionResponded(int socketFd, result r)
354 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
356 bool isFired = false;
358 __stateMutex.Acquire();
360 if ((__currentState == _BT_SPP_INI_STATE_CONNECT_READY)
361 || (__currentState == _BT_SPP_INI_STATE_REQ_CANCELING))
365 __currentState = _BT_SPP_INI_STATE_CONNECTED;
366 __socketFd = socketFd;
370 // including the cases as r == E_REJECTED or r == E_MAX_EXCEEDED
371 // E_MAX_EXCEEDED is originated in the previous version.
372 __currentState = _BT_SPP_INI_STATE_IDLE;
373 SysLogException(NID_NET_BT, r, "[%s] exception occurred on the response of the SPP connect request.", GetErrorMessage(r));
378 // ignore other cases
380 __stateMutex.Release();
384 _BluetoothSppInitiatorEventArg* pArg = new (std::nothrow) _BluetoothSppInitiatorEventArg(true, r);
387 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
392 __pEvent->FireAsync(*pArg);
396 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [CONNECT_RESPONDED_Event:%s]",
397 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
401 _BluetoothSppInitiatorImpl::OnSocketDisconnected(result r)
403 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
405 bool isFired = false;
407 __stateMutex.Acquire();
409 if (__currentState == _BT_SPP_INI_STATE_CONNECTED)
413 __currentState = _BT_SPP_INI_STATE_IDLE;
414 __socketFd = _BT_INVALID_SOCKET_FD;
418 // ignore other cases
420 __stateMutex.Release();
424 _BluetoothSppInitiatorEventArg* pArg = new (std::nothrow) _BluetoothSppInitiatorEventArg(false, r);
427 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
432 __pEvent->FireAsync(*pArg);
436 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [DISCONNECTED_Event:%s]",
437 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
441 _BluetoothSppInitiatorImpl::OnSocketDataReceived(Tizen::Base::ByteBuffer& buffer)
443 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
445 bool isFired = false;
447 __stateMutex.Acquire();
449 if (__currentState == _BT_SPP_INI_STATE_CONNECTED)
453 // ignore other cases
455 __stateMutex.Release();
459 _BluetoothSppInitiatorEventArg* pArg = new (std::nothrow) _BluetoothSppInitiatorEventArg(buffer);
462 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
467 // use Fire() instead of FireAsync() to improve the transfer rate.
468 __pEvent->Fire(*pArg);
472 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [DATA_RECIEVED_Event:%s]",
473 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
477 _BluetoothSppInitiatorImpl::OnBluetoothPaired(const BluetoothDevice* pPairedDevice, result r)
479 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
481 bool isFired = false;
482 result responseResult = E_SYSTEM;
484 __stateMutex.Acquire();
486 if (pPairedDevice->GetAddress()->Equals(__pairingAddress))
488 if (__currentState == _BT_SPP_INI_STATE_BONDING)
492 if (__pSppAdapter->ConnectSocket(__pairingAddress, __pairingUuid, *this) == E_SUCCESS)
494 __currentState = _BT_SPP_INI_STATE_CONNECT_READY;
498 // callback responded with E_SYSTEM
500 __currentState = _BT_SPP_INI_STATE_IDLE;
501 responseResult = E_SYSTEM;
506 // callback responded with r
508 __currentState = _BT_SPP_INI_STATE_IDLE;
512 __pairingAddress.Clear();
514 else if (__currentState == _BT_SPP_INI_STATE_REQ_CANCELING)
516 // callback responded with E_SYSTEM or E_OPERATION_CANCELED
518 __currentState = _BT_SPP_INI_STATE_IDLE;
519 responseResult = E_SYSTEM;
521 // ignore other cases
525 __stateMutex.Release();
529 _BluetoothSppInitiatorEventArg* pArg = new (std::nothrow) _BluetoothSppInitiatorEventArg(true, responseResult);
532 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
537 __pEvent->FireAsync(*pArg);
541 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [CONNECT_RESPONDED_Event:%s]",
542 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
546 _BluetoothSppInitiatorImpl::ProcessAsyncDisconnect(void)
548 result r = E_SUCCESS;
550 r = __pSppAdapter->DisconnectSocket(__socketFd);
552 // send a disconnected event here if the disconnect method is successful
553 // because the disconnect method of the underlying system is sync call. (transform sync into async)
556 __socketFd = _BT_INVALID_SOCKET_FD;
558 _BluetoothSppInitiatorEventArg* pArg = new (std::nothrow) _BluetoothSppInitiatorEventArg(false, r);
561 __pEvent->FireAsync(*pArg);
562 SysLog(NID_NET_BT, "[DISCONNECTED_Event:Fired]");
570 _BluetoothSppInitiatorImpl::GetStringOfCurrentState(void) const
572 const char* pStateString = null;
574 switch (__currentState)
576 case _BT_SPP_INI_STATE_DISABLED:
577 pStateString = "DISABLED";
580 case _BT_SPP_INI_STATE_IDLE:
581 pStateString = "IDLE";
584 case _BT_SPP_INI_STATE_BONDING:
585 pStateString = "BONDING";
588 case _BT_SPP_INI_STATE_CONNECT_READY:
589 pStateString = "CONNECT_READY";
592 case _BT_SPP_INI_STATE_REQ_CANCELING:
593 pStateString = "REQ_CANCELING";
596 case _BT_SPP_INI_STATE_CONNECTED:
597 pStateString = "CONNECTED";
601 pStateString = "Unknown";
608 } } } // Tizen::Net::Bluetooth