update the header for Doxygen
[platform/framework/native/bluetooth.git] / src / FNetBt_BluetoothOppServerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17 // @file    FNetBt_BluetoothOppServerImpl.cpp
18 // @brief   This is the implementation file for the _BluetoothOppServerImpl class.
19 //
20
21 #include <FNetBtBluetoothTypes.h>
22 #include <FNetBtBluetoothDevice.h>
23 #include <FNetBtIBluetoothOppServerEventListener.h>
24 #include <FBaseSysLog.h>
25 #include <FIo_FileImpl.h>
26 #include <FApp_AppInfo.h>
27 #include "FNetBt_BluetoothOppServerImpl.h"
28 #include "FNetBt_BluetoothOppSystemAdapter.h"
29 #include "FNetBt_BluetoothGapSystemAdapter.h"
30 #include "FNetBt_BluetoothOppServerEvent.h"
31 #include "FNetBt_BluetoothOppServerEventArg.h"
32
33 using namespace std;
34 using namespace Tizen::App;
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Runtime;
37
38 namespace Tizen { namespace Net { namespace Bluetooth
39 {
40
41 _BluetoothOppServerImpl::_BluetoothOppServerImpl(void)
42         : __pGapAdapter(null)
43         , __pOppAdapter(null)
44         , __pEvent(null)
45         , __stateMutex()
46         , __currentState(_BT_OPP_SVR_STATE_DISABLED)
47         , __pushedFileName()
48         , __minProgressInterval(__defaultProgressInterval)
49         , __previousProgress(0)
50 {
51 }
52
53 _BluetoothOppServerImpl::~_BluetoothOppServerImpl(void)
54 {
55         if (__pOppAdapter != null)
56         {
57                 if ((__currentState == _BT_OPP_SVR_STATE_ON_SERVICE)
58                         || (__currentState == _BT_OPP_SVR_STATE_PUSH_REQUESTED)
59                         || (__currentState == _BT_OPP_SVR_STATE_ON_TRANSFER))
60                 {
61                         (void) StopService(); // Ignores the result of this function.
62                 }
63                 __pOppAdapter = null;
64         }
65
66         if (__pGapAdapter != null)
67         {
68                 __pGapAdapter->UnregisterManagerEventListener(*this);
69                 __pGapAdapter = null;
70         }
71 }
72
73 result
74 _BluetoothOppServerImpl::Construct(IBluetoothOppServerEventListener& listener)
75 {
76         result r = E_SUCCESS;
77         unique_ptr<_BluetoothOppServerEvent> pEvent;
78
79         r = __stateMutex.Create();
80         SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create the state mutex.");
81
82         __pGapAdapter = _BluetoothGapSystemAdapter::GetInstance();
83         SysTryReturn(NID_NET_BT, __pGapAdapter != null, E_SYSTEM, E_SYSTEM,
84                                 "[E_SYSTEM] Failed to invoke _BluetoothSysteAdapter::GetInstance().");
85
86         __pOppAdapter = _BluetoothOppSystemAdapter::GetInstance();
87
88         pEvent.reset(new (std::nothrow) _BluetoothOppServerEvent());
89         SysTryReturn(NID_NET_BT, pEvent != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
90         r = pEvent->Construct();
91         SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct the event.");
92         // add the IBluetoothOppServerEventListener instance to a new created _BluetoothOppServerEvent.
93         r = pEvent->AddListener(listener, true);
94         SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
95                                 "[%s] Propagating. Failed to add the application listener for OPP Server", GetErrorMessage(r));
96
97         // registers this callback listener to the system adapter for activation/deactivation event
98         r = __pGapAdapter->RegisterManagerEventListener(*this, true);
99         SysTryReturn(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, E_SYSTEM,
100                            "[E_SYSTEM] Failed to register the callback listener to _BluetoothSystemAdapter.");
101
102         // check whether the Bluetooth is available
103         __stateMutex.Acquire();
104
105         if (__pGapAdapter->IsActivated() == true)
106         {
107                 __currentState = _BT_OPP_SVR_STATE_IDLE;
108         }
109
110         __stateMutex.Release();
111
112         __pEvent = move(pEvent);
113
114         return E_SUCCESS;
115 }
116
117 result
118 _BluetoothOppServerImpl::AcceptPush(void)
119 {
120         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
121
122         result r = E_FAILURE;
123
124         __stateMutex.Acquire();
125
126         switch (__currentState)
127         {
128         case _BT_OPP_SVR_STATE_DISABLED:
129                 r = E_INVALID_STATE;
130                 break;
131
132         case _BT_OPP_SVR_STATE_IDLE:
133         case _BT_OPP_SVR_STATE_ON_SERVICE:
134         case _BT_OPP_SVR_STATE_ON_TRANSFER:
135         case _BT_OPP_SVR_STATE_ON_STOPPING:
136                 r = E_INVALID_OPERATION;
137                 break;
138
139         case _BT_OPP_SVR_STATE_PUSH_REQUESTED:
140                 r = __pOppAdapter->AcceptOppPush(__pushedFileName);
141
142                 if (r == E_SUCCESS)
143                 {
144                         __currentState = _BT_OPP_SVR_STATE_ON_TRANSFER;
145                 }
146                 else
147                 {
148                         __currentState = _BT_OPP_SVR_STATE_ON_SERVICE;
149                 }
150                 break;
151
152         default:
153                 // ignore other cases
154                 break;
155         }
156
157         __stateMutex.Release();
158
159         if (r != E_SUCCESS)
160         {
161                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on accepting a push request.", GetErrorMessage(r));
162         }
163
164         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
165
166         return r;
167 }
168
169 result
170 _BluetoothOppServerImpl::RejectPush(void)
171 {
172         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
173
174         result r = E_FAILURE;
175
176         __stateMutex.Acquire();
177
178         switch (__currentState)
179         {
180         case _BT_OPP_SVR_STATE_DISABLED:
181                 r = E_INVALID_STATE;
182                 break;
183
184         case _BT_OPP_SVR_STATE_IDLE:
185         case _BT_OPP_SVR_STATE_ON_SERVICE:
186         case _BT_OPP_SVR_STATE_ON_TRANSFER:
187         case _BT_OPP_SVR_STATE_ON_STOPPING:
188                 r = E_INVALID_OPERATION;
189                 break;
190
191         case _BT_OPP_SVR_STATE_PUSH_REQUESTED:
192                 r = __pOppAdapter->RejectOppPush();
193
194                 // change the state into ON_SERVICE regardless of the result
195                 __currentState = _BT_OPP_SVR_STATE_ON_SERVICE;
196                 break;
197
198         default:
199                 // ignore other cases
200                 break;
201         }
202
203         __stateMutex.Release();
204
205         if (r != E_SUCCESS)
206         {
207                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on rejecting a push request.", GetErrorMessage(r));
208         }
209
210         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
211
212         return r;
213 }
214
215 result
216 _BluetoothOppServerImpl::SetDestinationPath(const Tizen::Base::String& dstPath)
217 {
218         result r = E_INVALID_OPERATION;
219         String physicalPath;
220
221         if ((__currentState != _BT_OPP_SVR_STATE_ON_TRANSFER) &&
222                 (__currentState != _BT_OPP_SVR_STATE_ON_STOPPING))
223         {
224                 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
225                 {
226                         if (Tizen::Io::_FileImpl::ConvertVirtualToPhysicalPath(dstPath, physicalPath) != E_SUCCESS)
227                         {
228                                 r = E_INACCESSIBLE_PATH;
229                         }
230                         else
231                         {
232                                 r = __pOppAdapter->SetOppReceivePath(physicalPath);
233                         }
234                 }
235                 else
236                 {
237                         r = __pOppAdapter->SetOppReceivePath(dstPath);
238                 }
239         }
240
241         if (r != E_SUCCESS)
242         {
243                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on setting the destination path.", GetErrorMessage(r));
244         }
245
246         return r;
247 }
248
249 result
250 _BluetoothOppServerImpl::SetMinProgressInterval(int percent)
251 {
252         result r = E_SUCCESS;
253
254         if ((percent < 1) || (percent > 100))
255         {
256                 r = E_OUT_OF_RANGE;
257                 SysLogException(NID_NET_BT, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The input argument - percent - is outside the valid range.");
258         }
259         else
260         {
261                 __minProgressInterval = percent;
262         }
263
264         return r;
265 }
266
267 result
268 _BluetoothOppServerImpl::StartService(const Tizen::Base::String& dstPath)
269 {
270         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
271
272         result r = E_FAILURE;
273         String physicalPath;
274
275         __stateMutex.Acquire();
276
277         switch (__currentState)
278         {
279         case _BT_OPP_SVR_STATE_DISABLED:
280                 r = E_INVALID_STATE;
281                 break;
282
283         case _BT_OPP_SVR_STATE_IDLE:
284                 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
285                 {
286                         if (Tizen::Io::_FileImpl::ConvertVirtualToPhysicalPath(dstPath, physicalPath) != E_SUCCESS)
287                         {
288                                 r = E_INACCESSIBLE_PATH;
289                                 break;
290                         }
291                 }
292                 else
293                 {
294                         physicalPath = dstPath;
295                 }
296
297                 r = __pOppAdapter->StartOppServer(*this, physicalPath);
298
299                 if (r == E_SUCCESS)
300                 {
301                         __currentState = _BT_OPP_SVR_STATE_ON_SERVICE;
302                 }
303                 break;
304
305         case _BT_OPP_SVR_STATE_ON_SERVICE:
306         case _BT_OPP_SVR_STATE_PUSH_REQUESTED:
307         case _BT_OPP_SVR_STATE_ON_TRANSFER:
308                 r = E_IN_PROGRESS;
309                 break;
310
311         case _BT_OPP_SVR_STATE_ON_STOPPING:
312                 r = E_INVALID_OPERATION;
313                 break;
314
315         default:
316                 // ignore other cases
317                 break;
318         }
319
320         __stateMutex.Release();
321
322         if (r != E_SUCCESS)
323         {
324                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on starting OPP service.", GetErrorMessage(r));
325         }
326
327         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
328
329         return r;
330 }
331
332 result
333 _BluetoothOppServerImpl::StopService(void)
334 {
335         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
336
337         result r = E_FAILURE;
338
339         __stateMutex.Acquire();
340
341         switch (__currentState)
342         {
343         case _BT_OPP_SVR_STATE_DISABLED:
344                 r = E_INVALID_STATE;
345                 break;
346
347         case _BT_OPP_SVR_STATE_IDLE:
348                 r = E_INVALID_OPERATION;
349                 break;
350
351         case _BT_OPP_SVR_STATE_ON_SERVICE:
352         case _BT_OPP_SVR_STATE_ON_STOPPING:
353                 r = __pOppAdapter->StopOppServer();
354                 if (r == E_SUCCESS)
355                 {
356                         __currentState = _BT_OPP_SVR_STATE_IDLE;
357                 }
358                 break;
359
360         case _BT_OPP_SVR_STATE_PUSH_REQUESTED:
361                 r = __pOppAdapter->RejectOppPush();
362                 if (r == E_SUCCESS)
363                 {
364                         r = __pOppAdapter->StopOppServer();
365                         if (r == E_SUCCESS)
366                         {
367                                 __currentState = _BT_OPP_SVR_STATE_IDLE;
368                         }
369                         else
370                         {
371                                 __currentState = _BT_OPP_SVR_STATE_ON_SERVICE;
372                         }
373                 }
374                 // Stays in the current status, if the rejection fails
375                 break;
376
377         case _BT_OPP_SVR_STATE_ON_TRANSFER:
378                 r = __pOppAdapter->StopOppTransfer();
379                 r = TransExceptionsInclusive(r ,E_FAILURE, E_OPERATION_FAILED);
380                 if (r == E_SUCCESS)
381                 {
382                         r = __pOppAdapter->StopOppServer();
383                         if (r == E_SUCCESS)
384                         {
385                                 __currentState = _BT_OPP_SVR_STATE_IDLE;
386                         }
387                         else
388                         {
389                                 __currentState = _BT_OPP_SVR_STATE_ON_SERVICE;
390                         }
391                 }
392                 // Stays in the current status, if the terminating file transfer fails
393                 break;
394
395         default:
396                 // ignore other cases
397                 break;
398         }
399
400         __stateMutex.Release();
401
402         if (r != E_SUCCESS)
403         {
404                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on stopping OPP service.", GetErrorMessage(r));
405         }
406
407         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
408
409         return r;
410 }
411
412 result
413 _BluetoothOppServerImpl::StopTransfer(void)
414 {
415         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
416
417         result r = E_OPERATION_FAILED;
418
419         __stateMutex.Acquire();
420
421         switch (__currentState)
422         {
423         case _BT_OPP_SVR_STATE_DISABLED:
424                 r = E_INVALID_STATE;
425                 break;
426
427         case _BT_OPP_SVR_STATE_IDLE:
428         case _BT_OPP_SVR_STATE_ON_SERVICE:
429         case _BT_OPP_SVR_STATE_PUSH_REQUESTED:
430         case _BT_OPP_SVR_STATE_ON_STOPPING:
431                 r = E_INVALID_OPERATION;
432                 break;
433
434         case _BT_OPP_SVR_STATE_ON_TRANSFER:
435                 r = __pOppAdapter->StopOppTransfer();
436                 if (r == E_SUCCESS)
437                 {
438                         __currentState = _BT_OPP_SVR_STATE_ON_STOPPING;
439                 }
440                 // It will be changed to IDLE after receiving the TransferDone event.
441                 break;
442
443         default:
444                 // ignore other cases
445                 break;
446         }
447
448         __stateMutex.Release();
449
450         if (r != E_SUCCESS)
451         {
452                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on stopping OPP service.", GetErrorMessage(r));
453         }
454
455         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
456
457         return r;
458 }
459
460 void
461 _BluetoothOppServerImpl::OnBluetoothActivated(result r)
462 {
463         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
464
465         __stateMutex.Acquire();
466
467         if ((__currentState == _BT_OPP_SVR_STATE_DISABLED) && (r == E_SUCCESS))
468         {
469                 __currentState = _BT_OPP_SVR_STATE_IDLE;
470         }
471
472         __stateMutex.Release();
473
474         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
475 }
476
477 void
478 _BluetoothOppServerImpl::OnBluetoothDeactivated(result r)
479 {
480         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [ActionResult:%s]", GetStringOfCurrentState(), GetErrorMessage(r));
481
482         __stateMutex.Acquire();
483
484         if (r == E_SUCCESS)
485         {
486                 __currentState = _BT_OPP_SVR_STATE_DISABLED;
487         }
488
489         __stateMutex.Release();
490
491         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s]", GetStringOfCurrentState());
492 }
493
494 void
495 _BluetoothOppServerImpl::OnOppPushRequested(const BluetoothDevice& device)
496 {
497         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s]", GetStringOfCurrentState());
498
499         bool isFired = false;
500
501         __stateMutex.Acquire();
502
503         if (__currentState == _BT_OPP_SVR_STATE_ON_SERVICE)
504         {
505                 __currentState = _BT_OPP_SVR_STATE_PUSH_REQUESTED;
506                 isFired = true;
507         }
508         else if ((__currentState == _BT_OPP_SVR_STATE_PUSH_REQUESTED)
509                          || (__currentState == _BT_OPP_SVR_STATE_ON_TRANSFER)
510                          || (__currentState == _BT_OPP_SVR_STATE_ON_STOPPING))
511         {
512                 (void) __pOppAdapter->RejectOppPush(); // ignore the result
513         }
514         // ignore other cases
515
516         __stateMutex.Release();
517
518         if (isFired)
519         {
520                 _BluetoothOppServerEventArg* pArg = new (std::nothrow) _BluetoothOppServerEventArg(device);
521                 if (pArg == null)
522                 {
523                         SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
524                         isFired = false;
525                 }
526                 else
527                 {
528                         __pEvent->FireAsync(*pArg);
529                 }
530         }
531
532         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [PUSH_REQUESTED_Event:%s]",
533                                 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
534 }
535
536 void
537 _BluetoothOppServerImpl::OnOppTransferInProgress(int percent)
538 {
539         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [Progress:%d]", GetStringOfCurrentState(), percent);
540
541         bool isFired = false;
542
543         __stateMutex.Acquire();
544
545         if ((__currentState == _BT_OPP_SVR_STATE_ON_TRANSFER) || (__currentState == _BT_OPP_SVR_STATE_ON_STOPPING))
546         {
547                 if (((percent - __previousProgress) >= __minProgressInterval) || (percent >= 100))
548                 {
549                         isFired = true;
550                         __previousProgress = percent;
551                 }
552         }
553         // ignore other scases
554
555         __stateMutex.Release();
556
557         if (isFired)
558         {
559                 _BluetoothOppServerEventArg* pArg = new (std::nothrow) _BluetoothOppServerEventArg(percent);
560                 if (pArg == null)
561                 {
562                         SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
563                         isFired = false;
564                 }
565                 else
566                 {
567                         __pEvent->FireAsync(*pArg);
568                 }
569         }
570
571         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [TRANSFER_IN_PROGRESS_Event:%s]",
572                                 GetStringOfCurrentState(), isFired ? "Fired" : "NotFired");
573 }
574
575 void
576 _BluetoothOppServerImpl::OnOppTransferDone(const Tizen::Base::String& filePath, int fileSize, bool isCompleted)
577 {
578         SysLog(NID_NET_BT, "EntryPoint, [CurrentState:%s], [TransferDone:%s]",
579                                 GetStringOfCurrentState(), isCompleted ? "Completed" : "NotCompleted");
580
581         result r = E_SUCCESS;
582         bool isFired = false;
583
584         __stateMutex.Acquire();
585
586         if (__currentState == _BT_OPP_SVR_STATE_IDLE)
587         {
588                 isFired = true;
589                 __previousProgress = 0;        // initialization for the next push transaction
590         }
591         else if ((__currentState == _BT_OPP_SVR_STATE_ON_TRANSFER) || (__currentState == _BT_OPP_SVR_STATE_ON_STOPPING))
592         {
593                 __currentState = _BT_OPP_SVR_STATE_ON_SERVICE;
594                 isFired = true;
595                 __previousProgress = 0;        // initialization for the next push transaction
596         }
597         // ignore other cases
598
599         __stateMutex.Release();
600
601         if (isFired)
602         {
603                 _BluetoothOppServerEventArg* pArg = new (std::nothrow) _BluetoothOppServerEventArg(filePath, fileSize, isCompleted);
604                 if (pArg == null)
605                 {
606                         SysLogException(NID_NET_BT, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
607                         isFired = false;
608                 }
609                 else
610                 {
611                         __pEvent->FireAsync(*pArg);
612                 }
613         }
614
615         if ((isFired) && (r != E_SUCCESS))
616         {
617                 SysLogException(NID_NET_BT, r, "[%s] exception occurred on stopping OPP service in the transfer-done callback.", GetErrorMessage(r));
618         }
619
620         SysLog(NID_NET_BT, "ExitPoint, [CurrentState:%s], [ActionResult:%s], [TRANSFER_DONE_Event:%s]",
621                                 GetStringOfCurrentState(), GetErrorMessage(r), isFired ? "Fired" : "NotFired");
622 }
623
624 const char*
625 _BluetoothOppServerImpl::GetStringOfCurrentState(void) const
626 {
627         const char* pStateString = null;
628
629         switch (__currentState)
630         {
631         case _BT_OPP_SVR_STATE_DISABLED:
632                 pStateString = "DISABLED";
633                 break;
634
635         case _BT_OPP_SVR_STATE_IDLE:
636                 pStateString = "IDLE";
637                 break;
638
639         case _BT_OPP_SVR_STATE_ON_SERVICE:
640                 pStateString = "ON_SERVICE";
641                 break;
642
643         case _BT_OPP_SVR_STATE_PUSH_REQUESTED:
644                 pStateString = "PUSH_REQUESTED";
645                 break;
646
647         case _BT_OPP_SVR_STATE_ON_TRANSFER:
648                 pStateString = "ON_TRANSFER";
649                 break;
650
651         case _BT_OPP_SVR_STATE_ON_STOPPING:
652                 pStateString = "ON_STOPPING";
653                 break;
654
655         default:
656                 pStateString = "Unknown";
657                 break;
658         }
659
660         return pStateString;
661 }
662
663 } } } // Tizen::Net::Bluetooth