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_BluetoothSppAcceptorImpl.cpp
18 // @brief This is the implementation file for the _BluetoothSppAcceptorImpl class.
21 #include <FBaseByteBuffer.h>
22 #include <FBaseUuId.h>
23 #include <FOspConfig.h>
24 #include <FNetBtBluetoothTypes.h>
25 #include <FNetBtBluetoothDevice.h>
26 #include <FNetBtIBluetoothSppAcceptorEventListener.h>
27 #include <FBaseSysLog.h>
28 #include "FNetBt_BluetoothSppAcceptorEvent.h"
29 #include "FNetBt_BluetoothSppAcceptorEventArg.h"
30 #include "FNetBt_BluetoothSppAcceptorImpl.h"
31 #include "FNetBt_BluetoothSppSystemAdapter.h"
32 #include "FNetBt_BluetoothGapSystemAdapter.h"
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Runtime;
38 namespace Tizen { namespace Net { namespace Bluetooth
41 _BluetoothSppAcceptorImpl::_BluetoothSppAcceptorImpl(void)
46 , __currentState(_BT_SPP_ACC_STATE_DISABLED)
47 , __parentSocketFd(_BT_INVALID_SOCKET_FD)
48 , __childSocketFd(_BT_INVALID_SOCKET_FD)
52 _BluetoothSppAcceptorImpl::~_BluetoothSppAcceptorImpl(void)
54 if (__pSppAdapter != null)
56 if ((__currentState == _BT_SPP_ACC_STATE_ON_SERVICE) ||
57 (__currentState == _BT_SPP_ACC_STATE_CONNECT_REQUESTED) ||
58 (__currentState == _BT_SPP_ACC_STATE_CONNECTED))
60 (void) StopService(); // Ignores the result of this function.
64 if (__pGapAdapter != null)
66 __pGapAdapter->UnregisterManagerEventListener(*this);
71 _BluetoothSppAcceptorImpl::Construct(IBluetoothSppAcceptorEventListener& listener)
74 std::unique_ptr<_BluetoothSppAcceptorEvent> pEvent;
76 r = __stateMutex.Create();
77 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create the state mutex.");
79 __pGapAdapter = _BluetoothGapSystemAdapter::GetInstance();
80 SysTryReturn(NID_NET_BT, __pGapAdapter != null, E_SYSTEM, E_SYSTEM,
81 "[E_SYSTEM] Failed to invoke _BluetoothGapSystemAdapter::GetInstance().");
83 __pSppAdapter = _BluetoothSppSystemAdapter::GetInstance();
84 SysTryReturn(NID_NET_BT, __pSppAdapter != null, E_SYSTEM, E_SYSTEM,
85 "[E_SYSTEM] Failed to invoke _BluetoothSppSystemAdapter::GetInstance().");
87 pEvent.reset(new (std::nothrow) _BluetoothSppAcceptorEvent());
88 SysTryReturn(NID_NET_BT, pEvent != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
89 r = pEvent->Construct();
90 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct the event.");
91 // add the IBluetoothSppAcceptorEventListener instance to a new created _BluetoothSppAcceptorEvent.
92 r = pEvent->AddListener(listener, true);
93 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
94 "[%s] Propagating. Failed to add the application listener for SPP Acceptor", GetErrorMessage(r));
96 // registers this callback listener to the system adapter for activation/deactivation event
97 r = __pGapAdapter->RegisterManagerEventListener(*this, true);
98 SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
99 "[E_SYSTEM] Failed to register the callback listener to _BluetoothGapSystemAdapter.");
101 // check whether the Bluetooth is available
102 __stateMutex.Acquire();
104 if (__pGapAdapter->IsActivated() == true)
106 __currentState = _BT_SPP_ACC_STATE_IDLE;
109 __stateMutex.Release();
111 __pEvent = move(pEvent);
117 _BluetoothSppAcceptorImpl::AcceptConnection(void)
119 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
121 result r = E_SUCCESS;
122 int clientSocketFd = _BT_INVALID_SOCKET_FD;
124 __stateMutex.Acquire();
126 switch (__currentState)
128 case _BT_SPP_ACC_STATE_DISABLED:
132 case _BT_SPP_ACC_STATE_IDLE:
133 case _BT_SPP_ACC_STATE_ON_SERVICE:
134 case _BT_SPP_ACC_STATE_CONNECTED:
135 r = E_INVALID_OPERATION;
138 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
139 r = __pSppAdapter->AcceptSocketRequest(__parentSocketFd, clientSocketFd);
143 __currentState = _BT_SPP_ACC_STATE_CONNECTED;
144 __childSocketFd = clientSocketFd;
148 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
157 __stateMutex.Release();
161 SysLogException(NID_NET_BT, r, "[%s] exception occurred on accepting a connection request.", GetErrorMessage(r));
164 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
170 _BluetoothSppAcceptorImpl::RejectConnection()
172 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
174 result r = E_SUCCESS;
176 __stateMutex.Acquire();
178 switch (__currentState)
180 case _BT_SPP_ACC_STATE_DISABLED:
184 case _BT_SPP_ACC_STATE_IDLE:
185 case _BT_SPP_ACC_STATE_ON_SERVICE:
186 case _BT_SPP_ACC_STATE_CONNECTED:
187 r = E_INVALID_OPERATION;
190 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
191 r = __pSppAdapter->RejectSocketRequest(__parentSocketFd);
192 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
200 __stateMutex.Release();
204 SysLogException(NID_NET_BT, r, "[%s] exception occurred on rejecting a connection request.", GetErrorMessage(r));
207 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
213 _BluetoothSppAcceptorImpl::StartService(const Tizen::Base::UuId& serviceUuid)
215 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
217 result r = E_SUCCESS;
218 int serverSocketFd = _BT_INVALID_SOCKET_FD;
220 __stateMutex.Acquire();
222 switch (__currentState)
224 case _BT_SPP_ACC_STATE_DISABLED:
228 case _BT_SPP_ACC_STATE_IDLE:
229 r = __pSppAdapter->OpenServerSocket(serviceUuid, *this, serverSocketFd);
232 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
233 __parentSocketFd = serverSocketFd;
237 case _BT_SPP_ACC_STATE_ON_SERVICE:
238 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
242 case _BT_SPP_ACC_STATE_CONNECTED:
243 r = E_ALREADY_CONNECTED;
251 __stateMutex.Release();
255 SysLogException(NID_NET_BT, r, "[%s] exception occurred on starting SPP service.", GetErrorMessage(r));
258 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
264 _BluetoothSppAcceptorImpl::StopService(void)
266 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
268 result r = E_SUCCESS;
269 result resDisconnect = E_SUCCESS;
271 __stateMutex.Acquire();
273 switch (__currentState)
275 case _BT_SPP_ACC_STATE_DISABLED:
279 case _BT_SPP_ACC_STATE_IDLE:
280 r = E_INVALID_OPERATION;
283 case _BT_SPP_ACC_STATE_ON_SERVICE:
284 r = __pSppAdapter->CloseServerSocket(__parentSocketFd);
287 __currentState = _BT_SPP_ACC_STATE_IDLE;
288 __parentSocketFd = _BT_INVALID_SOCKET_FD;
292 // Stays in the current status, if StopSppServer() fails
293 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
294 r = __pSppAdapter->RejectSocketRequest(__parentSocketFd);
297 r = __pSppAdapter->CloseServerSocket(__parentSocketFd);
300 __currentState = _BT_SPP_ACC_STATE_IDLE;
301 __parentSocketFd = _BT_INVALID_SOCKET_FD;
305 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
310 case _BT_SPP_ACC_STATE_CONNECTED:
311 resDisconnect = ProcessAsyncDisconnect();
312 // stop server socket regardless whether disconnection is successful
313 r = __pSppAdapter->CloseServerSocket(__parentSocketFd);
316 __currentState = _BT_SPP_ACC_STATE_IDLE;
317 __parentSocketFd = _BT_INVALID_SOCKET_FD;
319 else if (resDisconnect == E_SUCCESS)
321 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
330 __stateMutex.Release();
334 SysLogException(NID_NET_BT, r, "[%s] exception occurred on stopping SPP service.", GetErrorMessage(r));
337 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
343 _BluetoothSppAcceptorImpl::SendData(const Tizen::Base::ByteBuffer& buffer)
345 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
347 result r = E_SUCCESS;
349 __stateMutex.Acquire();
351 switch (__currentState)
353 case _BT_SPP_ACC_STATE_DISABLED:
357 case _BT_SPP_ACC_STATE_IDLE:
358 case _BT_SPP_ACC_STATE_ON_SERVICE:
359 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
360 r = E_INVALID_OPERATION;
363 case _BT_SPP_ACC_STATE_CONNECTED:
364 if (buffer.GetRemaining() > 0)
366 r = __pSppAdapter->SendSocketData(__childSocketFd, buffer);
379 __stateMutex.Release();
383 SysLogException(NID_NET_BT, r, "[%s] exception occurred on sending data.", GetErrorMessage(r));
386 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
392 _BluetoothSppAcceptorImpl::Disconnect()
394 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
396 result r = E_SUCCESS;
398 __stateMutex.Acquire();
400 switch (__currentState)
402 case _BT_SPP_ACC_STATE_DISABLED:
406 case _BT_SPP_ACC_STATE_IDLE:
407 case _BT_SPP_ACC_STATE_ON_SERVICE:
408 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
409 r = E_INVALID_OPERATION;
412 case _BT_SPP_ACC_STATE_CONNECTED:
413 // send a disconnected event here if the disconnect method is successful
414 // because the disconnect method of the underlying system is sync call. (transform sync into async)
415 r = ProcessAsyncDisconnect();
418 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
427 __stateMutex.Release();
431 SysLogException(NID_NET_BT, r, "[%s] exception occurred on disconnecting the connection.", GetErrorMessage(r));
434 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
440 _BluetoothSppAcceptorImpl::OnBluetoothActivated(result r)
442 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
444 __stateMutex.Acquire();
446 if ((__currentState == _BT_SPP_ACC_STATE_DISABLED) && (r == E_SUCCESS))
448 __currentState = _BT_SPP_ACC_STATE_IDLE;
450 __stateMutex.Release();
452 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
456 _BluetoothSppAcceptorImpl::OnBluetoothDeactivated(result r)
458 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
460 __stateMutex.Acquire();
464 __currentState = _BT_SPP_ACC_STATE_DISABLED;
467 __stateMutex.Release();
469 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
473 _BluetoothSppAcceptorImpl::OnSocketConnectionRequested(const BluetoothDevice& device)
475 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
477 bool isFired = false;
479 __stateMutex.Acquire();
481 if (__currentState == _BT_SPP_ACC_STATE_ON_SERVICE)
483 __currentState = _BT_SPP_ACC_STATE_CONNECT_REQUESTED;
486 else if ((__currentState == _BT_SPP_ACC_STATE_CONNECT_REQUESTED) ||
487 (__currentState == _BT_SPP_ACC_STATE_CONNECTED))
489 (void) __pSppAdapter->RejectSocketRequest(__parentSocketFd);
491 // ignore othre cases
493 __stateMutex.Release();
497 _BluetoothSppAcceptorEventArg* pArg = new (std::nothrow) _BluetoothSppAcceptorEventArg(device);
500 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
505 __pEvent->FireAsync(*pArg);
509 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [CONNECT_REQUESTED_Event:%s]",
510 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
514 _BluetoothSppAcceptorImpl::OnSocketDisconnected(result r)
516 SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
518 bool isFired = false;
520 __stateMutex.Acquire();
522 if ((__currentState == _BT_SPP_ACC_STATE_CONNECT_REQUESTED) ||
523 (__currentState == _BT_SPP_ACC_STATE_CONNECTED))
527 __currentState = _BT_SPP_ACC_STATE_ON_SERVICE;
528 __childSocketFd = _BT_INVALID_SOCKET_FD;
533 // ignore other cases
535 __stateMutex.Release();
539 _BluetoothSppAcceptorEventArg* pArg = new (std::nothrow) _BluetoothSppAcceptorEventArg(r);
542 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
547 __pEvent->FireAsync(*pArg);
550 SysLogException(NID_NET_BT, r, "[%s] exception occurred on SPP-disconnect callback.", GetErrorMessage(r));
555 SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [DISCONNECTED_Event:%s]",
556 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
560 _BluetoothSppAcceptorImpl::OnSocketDataReceived(Tizen::Base::ByteBuffer& buffer)
562 bool isFired = false;
564 if (__currentState == _BT_SPP_ACC_STATE_CONNECTED)
566 _BluetoothSppAcceptorEventArg* pArg = new (std::nothrow) _BluetoothSppAcceptorEventArg(buffer);
569 SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
573 // use Fire() instead of FireAsync() to improve the transfer rate.
574 __pEvent->Fire(*pArg);
579 SysLog(NID_NET_BT, "[CurrentState:%s], [DATA_RECEIVED_Event:%s]",
580 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
584 _BluetoothSppAcceptorImpl::ProcessAsyncDisconnect(void)
586 result r = E_SUCCESS;
588 r = __pSppAdapter->DisconnectSocket(__childSocketFd);
590 // send a disconnected event here if the disconnect method is successful
591 // because the disconnect method of the underlying system is sync call. (transform sync into async)
594 __childSocketFd = _BT_INVALID_SOCKET_FD;
596 _BluetoothSppAcceptorEventArg* pArg = new (std::nothrow) _BluetoothSppAcceptorEventArg(r);
599 __pEvent->FireAsync(*pArg);
600 SysLog(NID_NET_BT, "[DISCONNECTED_Event:Fired]");
608 _BluetoothSppAcceptorImpl::GetStringOfCurrentState(void) const
610 const char* pStateString = null;
612 switch (__currentState)
614 case _BT_SPP_ACC_STATE_DISABLED:
615 pStateString = "DISABLED";
618 case _BT_SPP_ACC_STATE_IDLE:
619 pStateString = "IDLE";
622 case _BT_SPP_ACC_STATE_ON_SERVICE:
623 pStateString = "ON_SERVICE";
626 case _BT_SPP_ACC_STATE_CONNECT_REQUESTED:
627 pStateString = "CONNECT_REQUESTED";
630 case _BT_SPP_ACC_STATE_CONNECTED:
631 pStateString = "CONNECTED";
635 pStateString = "Unknown";
642 } } } // Tizen::Net::Bluetooth