Update change log and spec for wrt-plugins-tizen_0.4.29
[framework/web/wrt-plugins-tizen.git] / src / Bluetooth / BluetoothAdapter.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 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
18 #include <pcrecpp.h>
19
20 #include <Logger.h>
21 #include <JSWebAPIErrorFactory.h>
22 #include <system_info.h>
23 #include <JSUtil.h>
24
25 #include "BluetoothAdapter.h"
26 #include "BluetoothCallbackUtil.h"
27 #include "JSBluetoothDevice.h"
28 #include "JSBluetoothServiceHandler.h"
29 #include "JSBluetoothSocket.h"
30 #include "GlobalContextManager.h"
31
32 using namespace DeviceAPI::Common;
33
34 namespace DeviceAPI {
35 namespace Bluetooth {
36
37 void BluetoothAdapter::onStateChangedCB(int result, bt_adapter_state_e adapterState, void *userData)
38 {
39     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
40     if(!object) {
41         LoggerW("userData is NULL");
42         return;
43     }
44     object->mEnabled = (adapterState == BT_ADAPTER_ENABLED) ? true : false;
45
46     if(object->mUserDataList[SET_POWERED] != NULL) {  // requested event
47         bool state = (adapterState == BT_ADAPTER_ENABLED) ? true : false;    
48         if(object->mRequestedState != state) {
49             LoggerW("Requested state is same to current state");
50             return;        
51         }
52         
53         MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_POWERED]);
54         object->mUserDataList[SET_POWERED].reset();
55         
56         if(result == BT_ERROR_NONE) {
57             if(callback)
58                 callback->invokeCallback("success");
59         }
60         else if(result == BT_ERROR_RESOURCE_BUSY) {
61             if(callback) {
62                 JSContextRef context = callback->getContext();
63                 ServiceNotAvailableException error("Bluetooth device is busy");
64                 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
65             }    
66         }
67         else {
68             if(callback) {
69                 JSContextRef context = callback->getContext();
70                 UnknownException error("Unknown error");
71                 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
72             }
73         }
74     }
75     else {  // unexpected event
76         LoggerW("Bluetooth state is changed unexpectedly");
77     }
78 }
79
80 void BluetoothAdapter::onNameChangedCB(char *name, void *userData)
81 {
82     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
83     if(!object) {
84         LoggerW("userData is NULL");
85         return;
86     }
87
88     if(object->mUserDataList[SET_NAME] != NULL && !strcmp(object->mRequestedName.c_str(), name)) {  // requested event      
89         MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_NAME]);
90         object->mUserDataList[SET_NAME].reset();
91         if(callback)
92             callback->invokeCallback("success");        
93         
94         bt_adapter_unset_name_changed_cb();
95     }
96     else {  // unexpected event
97         LoggerW("Bluetooth name is changed unexpectedly");
98     }
99 }
100
101 void BluetoothAdapter::onVisibilityChangedCB(int result, bt_adapter_visibility_mode_e visibilityMode, void *userData)
102 {
103     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
104     if(!object) {
105         LoggerW("userData is NULL");
106         return;
107     }
108
109     if(object->mUserDataList[SET_VISIBLE] != NULL) {  // requested event
110         //bool visibility = (visibilityMode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) ? false : true;    
111         if(object->mRequestedVisibility != visibilityMode) {
112             LoggerW("Requested visibility is not same to current visibility");
113             return;
114         }    
115     
116         MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_VISIBLE]);
117         object->mUserDataList[SET_VISIBLE].reset();
118         
119         if(result == BT_ERROR_NONE) {
120             if(callback)
121                 callback->invokeCallback("success");
122         }
123         else {
124             if(callback) {
125                 JSContextRef context = callback->getContext();
126                 UnknownException error("Unknown error");
127                 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
128             }
129         }
130         
131         bt_adapter_unset_visibility_mode_changed_cb();
132     }
133     else {  // unexpected event
134         LoggerW("Bluetooth visibility is changed unexpectedly");
135     }
136 }
137
138 void BluetoothAdapter::onDiscoveryStateChangedCB(int result, bt_adapter_device_discovery_state_e discoveryState, 
139         bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
140 {
141     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
142     if(!object) {
143         LoggerW("userData is NULL");
144         return;
145     }
146
147     switch(discoveryState) {
148         case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
149         {
150             LoggerD("Discovery started");
151             if(object->mUserDataList[DISCOVER_DEVICES] != NULL) {  // requested event
152                 MultiCallbackUserDataPtr callback = 
153                         static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
154                         
155                 if(result == BT_ERROR_NONE) {
156
157                     // store MAC address of previously found device into mDisappearedDevices
158                     object->mDisappearedDevices.clear();
159                     for(std::vector<BluetoothDeviceSharedPtr>::iterator iter = object->mFoundDevices.begin(); 
160                             iter != object->mFoundDevices.end(); iter++) {
161                         BluetoothDeviceSharedPtr foundDevice = *iter;
162                         object->mDisappearedDevices.push_back(foundDevice->getAddress());
163                     }
164                     
165                     object->mFoundDevices.clear();
166                     if(callback)
167                         callback->invokeCallback("onstarted");
168                 }
169                 else {
170                     if(callback) {
171                         object->mUserDataList[DISCOVER_DEVICES].reset();
172                     
173                         JSContextRef context = callback->getContext();
174                         UnknownException error("Unknown error");                        
175                         callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
176                     }
177
178                     /*
179                     if(object->mUserDataList[STOP_DISCOVERY] == NULL)    // because same core API callback is used 
180                         bt_adapter_unset_device_discovery_state_changed_cb();
181                     */    
182                 }            
183             }
184             else {  // unexpected event
185                 LoggerW("Unexpected discovery");
186             }
187             break;
188         }
189         case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
190         {
191             LoggerD("Discovery finished");
192             if(result == BT_ERROR_NONE || result == BT_ERROR_CANCELLED) {
193                 // in case of discoverDevices()
194                 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) {
195                     MultiCallbackUserDataPtr callback = 
196                             static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
197
198                     if(callback) {
199                         if(object->mDisappearedDevices.size() > 0) {
200                             LoggerD("There are disappeared devices");
201                             for(std::vector<std::string>::iterator iter = object->mDisappearedDevices.begin();
202                                     iter != object->mDisappearedDevices.end(); iter++) {
203                         
204                                 callback->invokeCallback("ondevicedisappeared",
205                                         JSUtil::toJSValueRef(callback->getContext(), *iter));                                
206                             }
207                         }
208                         
209                         if(object->mFoundDevices.size() > 0) { // There are found devices
210                             LoggerD("There are found devices");                        
211                             int num = object->mFoundDevices.size();
212                             JSObjectRef devices[num];
213                             for(int i = 0; i < num; i++) {
214                                 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(callback->getContext(), object->mFoundDevices[i]);                        
215                                 devices[i] = deviceObj;
216                             }
217                             
218                             object->mUserDataList[DISCOVER_DEVICES].reset();
219                         
220                             callback->invokeCallback(
221                                     "onfinished",
222                                     JSObjectMakeArray(callback->getContext(), num, devices, NULL) );                            
223                         }
224                         else {  // There is no found device
225                             LoggerD("There is no found device");
226                             object->mUserDataList[DISCOVER_DEVICES].reset();                
227                             
228                             callback->invokeCallback(
229                                     "onfinished",
230                                     JSObjectMakeArray(callback->getContext(), 0, NULL, NULL) );
231                         }
232                     }
233                 }
234
235                 // in case of stopDiscovery()
236                 if(object->mUserDataList[STOP_DISCOVERY] != NULL) {
237                     MultiCallbackUserDataPtr callback = 
238                             static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[STOP_DISCOVERY]);
239
240                     if(callback) {
241                         LoggerD("Call successCallback of stopDiscovery()");
242                         object->mUserDataList[STOP_DISCOVERY].reset();
243                         callback->invokeCallback("success");                        
244                     }
245                 }
246
247                 //bt_adapter_unset_device_discovery_state_changed_cb();
248             }
249             else {
250                 LoggerW("Unexpected result of discovery finish");
251             }
252             break;
253         }
254         case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
255         {
256             LoggerD("A device is found");
257             if(!discoveryInfo) {
258                 LoggerW("No information about found device");
259                 return;    
260             }
261         
262             if(object->mUserDataList[DISCOVER_DEVICES] != NULL) {  // requested event
263                 MultiCallbackUserDataPtr callback = 
264                         static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
265                         
266                 if(result == BT_ERROR_NONE) {
267                     // create BluetoothDevice
268                     BluetoothDeviceSharedPtr device(new BluetoothDevice(discoveryInfo));
269                     JSContextRef context = callback->getContext();
270                     JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device);
271                     object->mFoundDevices.push_back(device);
272
273                     // remove MAC address of found device from mDisappearedDevices
274                     for(std::vector<std::string>::iterator iter = object->mDisappearedDevices.begin();
275                             iter != object->mDisappearedDevices.end(); iter++) {
276                         if(!strcmp(discoveryInfo->remote_address, (*iter).c_str())) {
277                             object->mDisappearedDevices.erase(iter);
278                             break;
279                         }
280                     }
281
282                     if(callback)
283                         callback->invokeCallback("ondevicefound", deviceObj);
284                 }
285                 else {
286                     LoggerW("Unexpected result of discovery");
287                 }            
288             }
289             else {  // unexpected event
290                 LoggerW("Unexpected discovery");
291             }
292             break;
293         }
294         default:
295         {
296             LoggerW("Unknown state");
297         }
298     }
299 }
300
301 bool BluetoothAdapter::foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData)
302 {
303     BluetoothAdapterPtr adapter = static_cast<BluetoothAdapterPtr>(userData);
304     if(!adapter) {
305         LoggerW("userData is NULL");
306         return true;
307     }
308
309     if(deviceInfo == NULL) {
310         LoggerW("deviceInfo is NULL");
311         return true;
312     }
313
314     std::vector<BluetoothDeviceSharedPtr>::iterator iter;
315     for(iter = adapter->knownDevices.begin(); iter != adapter->knownDevices.end(); ++iter) {
316         BluetoothDeviceSharedPtr foundDevice = *iter;
317
318         if(!strcmp(foundDevice->getAddress().c_str(), deviceInfo->remote_address)) {
319             foundDevice->updateInfo(deviceInfo);
320             break;
321         }
322     }
323
324     if(iter == adapter->knownDevices.end()) {
325         BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
326         adapter->knownDevices.push_back(device);        
327     }
328
329     return true;
330 }
331
332 void BluetoothAdapter::onBondCreatedCB(int result, bt_device_info_s *deviceInfo, void *userData)
333 {
334     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
335     if(!object) {
336         LoggerW("userData is NULL");
337         return;
338     }
339    
340     if(!deviceInfo) {
341         LoggerW("deviceInfo is NULL");
342         return;    
343     }
344
345     if(object->mUserDataList[CREATE_BONDING] != NULL &&
346             !strcmp(object->mCreateBondingAddress.c_str(), deviceInfo->remote_address)) {  // requested event
347     
348         MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[CREATE_BONDING]);
349         object->mUserDataList[CREATE_BONDING].reset();
350         
351         if(result == BT_ERROR_NONE && deviceInfo != NULL) {
352             if(callback) {
353                 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
354                 JSContextRef context = callback->getContext();
355                 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device);
356                 callback->invokeCallback("success", deviceObj);
357             }
358         }
359         else {
360             if(callback) {
361                 JSContextRef context = callback->getContext();
362                 UnknownException error("Unknown error");
363                 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
364             }
365         }        
366         
367         bt_device_unset_bond_created_cb();
368         object->mCreateBondingAddress.clear();
369     }
370     else {  // unexpected event
371         LoggerW("A bonding is created unexpectedly");
372     }
373 }
374
375 void BluetoothAdapter::onBondDestroyedCB(int result, char *remoteAddress, void *userData)
376 {
377     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
378     if(!object) {
379         LoggerW("userData is NULL");
380         return;
381     }
382
383     if(object->mUserDataList[DESTROY_BONDING] != NULL &&
384             !strcmp(object->mDestroyBondingAddress.c_str(), remoteAddress)) {  // requested event
385     
386         MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DESTROY_BONDING]);
387         object->mUserDataList[DESTROY_BONDING].reset();
388         
389         if(result == BT_ERROR_NONE) {
390             if(callback)
391                 callback->invokeCallback("success");
392         }
393         else {
394             if(callback) {
395                 JSContextRef context = callback->getContext();
396                 UnknownException error("Unknown error");
397                 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
398             }
399         }        
400         
401         bt_device_unset_bond_destroyed_cb();
402         object->mDestroyBondingAddress.clear();
403     }
404     else {  // unexpected event
405         LoggerW("A bonding is destroyed unexpectedly");
406     }
407 }
408
409 void BluetoothAdapter::onSocketConnected(int result, bt_socket_connection_state_e state, bt_socket_connection_s *connection, void *userData)
410 {
411     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
412     if(!object) {
413         LoggerW("userData is NULL");
414         return;
415     }
416
417     if(!connection) {
418         LoggerW("connection is NULL");
419         return;    
420     }
421     
422     if(connection->local_role == BT_SOCKET_SERVER) {
423         RegisteredUUIDMapT::iterator iter = object->mRegisteredUUID.find(connection->service_uuid);
424         if(iter == object->mRegisteredUUID.end()) {
425             LoggerW("Connection state is changed unexpectedly");
426             return;        
427         }
428
429         if(state == BT_SOCKET_CONNECTED) {  // connected when Server
430             if(result == BT_ERROR_NONE) {
431                 // Update BluetoothServiceHandler
432                 BluetoothServiceHandlerPtr service = iter->second;
433                 service->setConnectionState(true);
434
435                 // Call BluetoothServiceHandler.onconnect
436                 BluetoothSocketPtr socket = new BluetoothSocket(connection);
437                 MultiCallbackUserDataPtr callback = service->getOnConnect();
438                 JSContextRef context = callback->getContext();
439                 JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket);
440                 if(callback)
441                     callback->invokeCallback("onconnect", socketObj);
442
443                 // Update mConnectedSocket
444                 object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(connection->socket_fd, socket));
445                 bt_socket_set_data_received_cb(onSocketReceivedCB, userData);
446             }
447             else {
448                 LoggerW("Establishing a connection failed");
449             }
450             return;
451         }
452         else {  // disconnected when Server
453             if(result == BT_ERROR_NONE) {
454                 // Update BluetoothServiceHandler
455                 BluetoothServiceHandlerPtr service = iter->second;
456                 service->setConnectionState(false);
457
458                 // call BluetoothSocket.onclose;
459                 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd);
460                 if(i == object->mConnectedSocket.end()) {
461                     LoggerW("Unknown connected socket");
462                     return;
463                 }
464                 //BluetoothSocketSharedPtr socket = i->second;
465                 BluetoothSocketPtr socket = i->second;
466                 socket->setConnectionState(false);
467                 MultiCallbackUserDataPtr callback = socket->getOnClose();
468                 if(callback)
469                     callback->invokeCallback("onclose");
470                 
471                 // Update mConnectedSocket
472                 object->mConnectedSocket.erase(i);
473             }
474             else {
475                 LoggerW("Disconnecting a connection failed");
476             }        
477         }        
478     }
479     else if(connection->local_role == BT_SOCKET_CLIENT) {
480
481         if(state == BT_SOCKET_CONNECTED) {  // connected when Client
482             std::string remoteAddress(connection->remote_address);
483             ConnReqMultiMapT::iterator iter;
484             do {
485                 iter = object->mConnReqMap.find(remoteAddress);
486                 if(iter != object->mConnReqMap.end() && !strcmp(iter->second->mUUID.c_str(), connection->service_uuid)) {
487                     break;
488                 }
489             } while(iter != object->mConnReqMap.end());
490
491             if(iter == object->mConnReqMap.end()) {
492                 LoggerW("Connection state is changed unexpectedly");
493                 return;
494             }
495
496             MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(iter->second->mUserData);
497
498             if(result == BT_ERROR_NONE) {
499                 // Update mConnectedSocket
500                 BluetoothSocketPtr socket = new BluetoothSocket(connection);
501                 object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(connection->socket_fd, socket));
502                 bt_socket_set_data_received_cb(onSocketReceivedCB, userData);
503
504                 // Call successcallback of connectToServiceByUUID 
505                 JSContextRef context = callback->getContext();
506                 JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket);
507                 if(callback)
508                     callback->invokeCallback("success", socketObj);
509
510                 // Update mConnReqMap
511                 object->mConnReqMap.erase(iter);
512             }
513             else {
514                 // Call errorcallback of connectToServiceByUUID
515                 JSContextRef context = callback->getContext();
516                 NotFoundException error("Not found");
517                 if(callback)
518                     callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
519
520                 // Update mConnReqMap
521                 object->mConnReqMap.erase(iter);
522             }
523             return;
524         }
525         else {  // disconnected when Client
526             if(result == BT_ERROR_NONE) {
527                 // call BluetoothSocket.onclose;
528                 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd);
529                 if(i == object->mConnectedSocket.end()) {
530                     LoggerW("Unknown connected socket");
531                     return;
532                 }
533                 
534                 BluetoothSocketPtr socket = i->second;
535                 socket->setConnectionState(false);
536                 MultiCallbackUserDataPtr callback = socket->getOnClose();
537                 if(callback)
538                     callback->invokeCallback("onclose");
539             
540                 // Update mConnectedSocket
541                 object->mConnectedSocket.erase(i);                
542             }
543             else {
544                 LoggerW("Disconnecting a connection failed");
545             }
546         }        
547     }
548     else {
549         LoggerW("Unknown role");
550         return;    
551     }
552
553     if(object->mConnectedSocket.size() == 0) {
554         bt_socket_unset_data_received_cb();
555     }
556     
557     if(object->mRegisteredUUID.size() == 0 && object->mConnReqMap.size() == 0 && object->mConnectedSocket.size() == 0) {
558         bt_socket_unset_connection_state_changed_cb();
559     }
560 }
561
562 void BluetoothAdapter::onSocketReceivedCB(bt_socket_received_data_s *data, void *userData)
563 {
564     BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
565     if(!object) {
566         LoggerW("userData is NULL");
567         return;
568     }
569
570     if(!data) {
571         LoggerW("data is NULL");
572         return;    
573     }
574
575     ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(data->socket_fd);
576     if(i == object->mConnectedSocket.end()) {
577         LoggerW("Unknown connected socket");
578         return;
579     }
580
581     // Store received data
582     BluetoothSocketPtr socket = i->second;
583     socket->storeRecivedData(data->data, static_cast<unsigned long>(data->data_size));
584
585     // Call BluetoothSocket.onmessage
586     MultiCallbackUserDataPtr callback = socket->getOnMessage();
587     if(callback)
588         callback->invokeCallback("onmessage");
589 }
590
591 BluetoothAdapter::BluetoothAdapter(): 
592         mEnabled(false)
593 {
594     if(bt_initialize() != BT_ERROR_NONE) {
595         LoggerE("bt_initialize() failed");
596     }
597
598     bt_adapter_state_e state;
599     if (bt_adapter_get_state(&state) == BT_ERROR_NONE) {
600         if (state == BT_ADAPTER_ENABLED) {
601             mEnabled = true;
602         }
603     }    
604
605     if(bt_adapter_set_state_changed_cb(onStateChangedCB, this) != BT_ERROR_NONE) {
606         LoggerE("bt_adapter_set_state_changed_cb() failed");
607     }
608
609     if(bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this) != BT_ERROR_NONE) {
610         LoggerE("bt_adapter_set_device_discovery_state_changed_cb() failed");
611     }    
612 }
613
614 BluetoothAdapter::~BluetoothAdapter()
615 {
616     // unset platform callback
617     bt_adapter_unset_state_changed_cb();
618     bt_adapter_unset_name_changed_cb();
619     bt_adapter_unset_visibility_mode_changed_cb();
620     bt_adapter_unset_device_discovery_state_changed_cb();
621     bt_device_unset_bond_created_cb();
622     bt_device_unset_bond_destroyed_cb();
623     bt_socket_unset_connection_state_changed_cb();
624     bt_socket_unset_data_received_cb();
625     bt_deinitialize();
626
627     for(int i = 0; i <= DESTROY_BONDING; i++) {
628         mUserDataList[i].reset();
629     }
630     mRegisteredUUID.clear();
631     mConnReqMap.clear();
632     mFoundDevices.clear();
633     mConnectedSocket.clear();
634 }
635
636 void BluetoothAdapter::unloadFrame(JSContextRef context)
637 {
638     LoggerD("Clean mUserDataList");
639     for(int i = 0; i <= DESTROY_BONDING; i++) {
640         if(mUserDataList[i]) {
641             MultiCallbackUserDataPtr callback = mUserDataList[i];
642             if(!GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) {
643                 mUserDataList[i].reset();
644             }
645         }
646     }
647
648     LoggerD("Clean mConnReqMap");
649     for(ConnReqMultiMapT::iterator iter = mConnReqMap.begin(); iter != mConnReqMap.end(); ) {
650         ConnReqMultiMapT::iterator temp = iter++;
651         MultiCallbackUserDataPtr callback = temp->second->mUserData;        
652         if(!callback && !GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) {
653             mConnReqMap.erase(temp);
654         }
655     }
656 }
657
658 void BluetoothAdapter::unregisterUUID(std::string &uuid)
659 {
660     mRegisteredUUID.erase(mRegisteredUUID.find(uuid));
661     if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
662         bt_socket_unset_connection_state_changed_cb();
663     }
664 }
665
666 bool BluetoothAdapter::closeConnectedSocket(int socket)
667 {
668     if(mEnabled == true) {
669         ConnectedSocketMapT::iterator iter = mConnectedSocket.find(socket);
670         if(iter == mConnectedSocket.end()) {
671             LoggerW("Already disconnected");
672             return true;
673         }
674
675         mConnectedSocket.erase(iter);
676         if(mConnectedSocket.size() == 0) {
677             bt_socket_unset_data_received_cb();
678         }
679
680         if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
681             bt_socket_unset_connection_state_changed_cb();
682         }
683         
684         return true;    
685     }
686     else {
687         LoggerE("Bluetooth is not powered");
688         return false;
689     }
690 }
691
692 void BluetoothAdapter::removeConnReq(std::string &remoteAddress)
693 {
694     mConnReqMap.erase(remoteAddress);
695
696     if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
697         if(bt_socket_unset_connection_state_changed_cb() != BT_ERROR_NONE) {
698             LoggerW("Unsetting connection event callback failed");
699         }
700     }
701 }
702
703 BluetoothAdapter* BluetoothAdapter::getInstance()
704 {
705     static BluetoothAdapter instance;
706     return &instance;
707 }
708
709 bool BluetoothAdapter::isBluetoothSupported()
710 {
711     bool isSupported = false;
712     
713     if(system_info_get_value_bool(SYSTEM_INFO_KEY_BLUETOOTH_SUPPORTED, &isSupported) != SYSTEM_INFO_ERROR_NONE) {
714         LoggerE("Can't know whether Bluetooth is supported or not");
715     }
716     
717     return isSupported;
718 }
719
720 bool BluetoothAdapter::isValidAddress(std::string &address)
721 {
722     pcrecpp::RE re("(([0-9a-zA-Z]+):)+([0-9a-zA-Z]+)");
723     std::string compareAddress = "00:12:47:08:9A:A6";
724
725     if (!re.FullMatch(address)) {
726         LoggerE("Invalid address");
727         return false;
728     }
729
730     if (address.size() != compareAddress.size())
731     {
732         LoggerE("Invalid size");
733         return false;
734     }
735
736     return true;
737 }
738
739 bool BluetoothAdapter::isValidUUID(std::string &uuid)
740 {
741     pcrecpp::RE re("(([0-9a-zA-Z]+)-)+([0-9a-zA-Z]+)");
742     std::string compareUUID = "00001101-0000-1000-8000-00805F9B34FB";
743
744     if (!re.FullMatch(uuid))
745     {
746         LoggerE("Invalid UUID");
747         return false;
748     }
749
750     if (uuid.size() != compareUUID.size())
751     {
752         LoggerE("Invalid size");
753         return false;
754     }
755
756     return true;
757 }
758
759 std::string BluetoothAdapter::getName() const
760 {
761     char* name = NULL; 
762     std::string str = "";
763
764     if(bt_adapter_get_name(&name) == BT_ERROR_NONE) {
765         if (name != NULL)
766         {
767             str = name;
768             free(name);
769         }
770     }
771     else {
772         LoggerE("bt_adapter_get_name() failed");
773     }
774     
775     return str;
776 }
777
778 void BluetoothAdapter::setName(std::string &name, MultiCallbackUserDataPtr userData)
779 {
780     if(mEnabled == true) {
781         std::string adapterName = getName();
782         if(adapterName == name) {   // in case of same name
783             LoggerD("same name");
784             BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
785             return;
786         }
787
788         if(mUserDataList[SET_NAME] == NULL) {
789             bt_adapter_set_name_changed_cb(onNameChangedCB, this);
790             mUserDataList[SET_NAME] = userData;
791         } else {
792             LoggerE("Already requested");
793             UnknownException *error = new UnknownException("Already requested");
794             BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
795             return;
796         }
797         
798         int ret = bt_adapter_set_name(name.c_str());
799         
800         switch(ret) {
801             case BT_ERROR_NONE:
802             {
803                 LoggerD("bt_adapter_set_name() succeeded");
804                 mRequestedName = name;
805                 return;            
806             }
807             case BT_ERROR_INVALID_PARAMETER:
808             {
809                 LoggerE("Invalid value");
810                 InvalidValuesException *error = new InvalidValuesException("Invalid value");
811                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
812                 break;
813             }
814             default:
815             {
816                 LoggerE("Invalid value");
817                 UnknownException *error = new UnknownException("Unknown exception");
818                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
819             }            
820         }
821         
822         bt_adapter_unset_name_changed_cb();
823         mUserDataList[SET_NAME].reset();         
824     } else {   // Not enabled
825         LoggerE("Bluetooth device is turned off");
826         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
827         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
828     }
829 }
830
831 std::string BluetoothAdapter::getAddress() const
832 {
833     char* address = NULL; 
834     std::string str = "";
835
836     if (bt_adapter_get_address(&address) == BT_ERROR_NONE) {
837         if (address != NULL) {
838             str = address;
839             free(address);
840         }
841         else {
842             LoggerW("address is NULL");
843         }
844     }
845     else {
846         LoggerE("bt_adapter_get_address() failed");
847     }
848     
849     return str;
850 }
851
852 bool BluetoothAdapter::getPowered() const
853 {
854     return mEnabled;    
855 }
856
857 void BluetoothAdapter::setPowered(bool powered, MultiCallbackUserDataPtr userData)
858 {
859     if(powered == mEnabled) {    
860         LoggerD("same state");
861         BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
862         return;
863     }
864
865     if(mUserDataList[SET_POWERED] == NULL) {
866         mUserDataList[SET_POWERED] = userData;
867     } else {
868         // Already requested
869         LoggerE("Already requested");
870         ServiceNotAvailableException *error = new ServiceNotAvailableException("Already requested");
871         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
872         return;
873     }
874
875     mRequestedState = powered;
876     if(powered == true) {
877         int ret = bt_adapter_enable();
878
879         switch(ret) {
880             case BT_ERROR_NONE:
881             {
882                 LoggerD("bt_adapter_enable() succeeded");
883                 return;
884             }
885             case BT_ERROR_ALREADY_DONE:
886             {
887                 // call successCallback
888                 LoggerD("BT_ERROR_ALREADY_DONE");
889                 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
890                 break;
891             }
892             case BT_ERROR_NOW_IN_PROGRESS:
893             {
894                 LoggerD("BT_ERROR_NOW_IN_PROGRESS");
895                 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is busy");
896                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
897                 break;
898             }
899             default:
900             {
901                 LoggerD("Unknown error");
902                 UnknownException *error = new UnknownException("Unknown error");
903                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
904             }
905         }
906     } else {
907         int ret = bt_adapter_disable();
908         
909         switch(ret) {
910             case BT_ERROR_NONE:
911             {
912                 LoggerD("bt_adapter_disable() succeeded");
913                 return;
914             }
915             case BT_ERROR_NOT_ENABLED:
916             {
917                 // call successCallback
918                 LoggerD("Already disabled");
919                 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
920                 break;
921             }
922             case BT_ERROR_NOW_IN_PROGRESS:
923             {
924                 LoggerD("BT_ERROR_NOW_IN_PROGRESS");
925                 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is busy");
926                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
927                 break;
928             }
929             default:
930             {
931                 LoggerD("Unknown error");
932                 UnknownException *error = new UnknownException("Unknown error");
933                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
934             }
935         }
936     }
937
938     mUserDataList[SET_POWERED].reset();  
939 }
940
941 bool BluetoothAdapter::getVisible() const
942 {
943     bt_adapter_visibility_mode_e mode;
944
945     if (bt_adapter_get_visibility(&mode, NULL) == BT_ERROR_NONE) {
946         if (mode != BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
947             return true;
948         }
949     }
950     
951     return false;
952 }
953
954 void BluetoothAdapter::setVisible(bool visible, unsigned int timeout, MultiCallbackUserDataPtr userData)
955 {
956     if(mEnabled == true) {        
957         bt_adapter_visibility_mode_e discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
958         if(visible == true) {
959             if(timeout == 0)
960                 discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE;        
961             else
962                 discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
963         }
964         
965         bt_adapter_visibility_mode_e current = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
966         int time = 0;
967         if(bt_adapter_get_visibility(&current , &time) != BT_ERROR_NONE) {
968             LoggerE("bt_adapter_get_visibility() failed");
969             UnknownException *error = new UnknownException("Can't get current visibility");
970             BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);            
971             return;
972         }
973         
974         if(discoverable_mode == current) {
975             if(discoverable_mode != BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE) {
976                 LoggerD("same visibility");
977                 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
978                 return;
979             }
980             else if((unsigned int)time == timeout) {
981                 LoggerD("same visibility");
982                 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
983                 return;
984             }
985         }
986
987         if(mUserDataList[SET_VISIBLE] == NULL) {
988             bt_adapter_set_visibility_mode_changed_cb(onVisibilityChangedCB, this);
989             mUserDataList[SET_VISIBLE] = userData;
990         } else {
991             UnknownException *error = new UnknownException("Already requested");
992             BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
993             return;
994         }        
995         
996         mRequestedVisibility = discoverable_mode;    
997         int ret = bt_adapter_set_visibility(discoverable_mode, timeout);        
998         switch(ret) {
999             case BT_ERROR_NONE:
1000             {
1001                 LoggerD("bt_adapter_set_visibility() succeeded");
1002                 return;            
1003             }
1004             case BT_ERROR_INVALID_PARAMETER:
1005             {
1006                 InvalidValuesException *error = new InvalidValuesException("Invalid value");
1007                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1008                 break;
1009             }
1010             default:
1011             {
1012                 UnknownException *error = new UnknownException("Unknown error");
1013                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1014             }
1015         }
1016         
1017         bt_adapter_unset_visibility_mode_changed_cb();
1018         mUserDataList[SET_VISIBLE].reset();         
1019     } else {   // Not enabled
1020         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
1021         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1022     }
1023
1024 }
1025
1026 void BluetoothAdapter::discoverDevices(MultiCallbackUserDataPtr userData)
1027 {
1028     if(mUserDataList[DISCOVER_DEVICES] == NULL) {
1029         mUserDataList[DISCOVER_DEVICES] = userData;
1030
1031         /*
1032         if(mUserDataList[STOP_DISCOVERY] == NULL)
1033             bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this);     
1034         */    
1035     } else {
1036         LoggerE("Already requested");
1037         UnknownException *error = new UnknownException("Already requested");
1038         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1039         return;
1040     }
1041     
1042     if(mEnabled == true) {          
1043         int ret = bt_adapter_start_device_discovery();
1044         switch(ret) {
1045             case BT_ERROR_NONE:
1046             {
1047                 LoggerD("bt_adapter_start_device_discovery() succeeded");
1048                 return;
1049             }
1050             default:
1051             {
1052                 LoggerE("Unknown exception");
1053                 UnknownException *error = new UnknownException("Unknown error");
1054                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1055             }            
1056         }
1057     } else {   // Not enabled
1058         LoggerE("Bluetooth device is turned off");
1059         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
1060         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1061     }
1062
1063     mUserDataList[DISCOVER_DEVICES].reset(); 
1064     /*
1065     if(mUserDataList[STOP_DISCOVERY] == NULL) {
1066         bt_adapter_unset_device_discovery_state_changed_cb();
1067     }
1068     */
1069 }
1070
1071 void BluetoothAdapter::stopDiscovery(MultiCallbackUserDataPtr userData)
1072 {
1073     if(mEnabled == true) {
1074     
1075         bool isDiscovering = false;
1076         bt_adapter_is_discovering(&isDiscovering);
1077         if(!isDiscovering) {
1078             BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
1079             return;
1080         }
1081
1082         if(mUserDataList[STOP_DISCOVERY] == NULL) {
1083             mUserDataList[STOP_DISCOVERY] = userData;
1084
1085             /*
1086             if(mUserDataList[DISCOVER_DEVICES] == NULL)
1087                 bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this);     
1088             */
1089         } else {
1090             LoggerD("Already requested");
1091             UnknownException *error = new UnknownException("Already requested");
1092             BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1093             return;
1094         }
1095     
1096         int ret = bt_adapter_stop_device_discovery();
1097         switch(ret) {
1098             case BT_ERROR_NONE:
1099             {
1100                 LoggerD("bt_adapter_stop_device_discovery() succeeded");
1101                 return;            
1102             }
1103             default:
1104             {
1105                 UnknownException *error = new UnknownException("Unknown error");
1106                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1107             }            
1108         }
1109
1110         mUserDataList[STOP_DISCOVERY].reset(); 
1111         /*
1112         if(mUserDataList[DISCOVER_DEVICES] == NULL) {
1113             bt_adapter_unset_device_discovery_state_changed_cb();
1114         }
1115         */
1116     } else {   // Not enabled
1117         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
1118         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1119     }
1120 }
1121
1122 void BluetoothAdapter::getKnownDevices(MultiCallbackUserDataPtr userData)
1123 {
1124     BluetoothCallbackUtil::syncToAsyncDeviceArrayCallback(userData);
1125 }
1126
1127 void BluetoothAdapter::getDevice(std::string &address, MultiCallbackUserDataPtr userData)
1128 {
1129     BluetoothCallbackUtil::syncToAsyncDeviceCallback(userData, address);
1130 }
1131
1132 void BluetoothAdapter::createBonding(std::string &address, MultiCallbackUserDataPtr userData)
1133 {
1134     if(!isValidAddress(address)) {
1135         LoggerE("Wrong address");
1136         NotFoundException *error = new NotFoundException("Wrong address");
1137         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1138         return;
1139     }
1140
1141     if(mUserDataList[CREATE_BONDING] == NULL) {
1142         bt_device_set_bond_created_cb(onBondCreatedCB, this);
1143         mCreateBondingAddress = address;
1144         mUserDataList[CREATE_BONDING] = userData;
1145     } else {
1146         LoggerE("Already requested");
1147         UnknownException *error = new UnknownException("Already requested");
1148         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1149         return;
1150     }
1151     
1152     if(mEnabled == true) {
1153         int ret = bt_device_create_bond(address.c_str());
1154         
1155         switch(ret) {
1156             case BT_ERROR_NONE:
1157             {
1158                 LoggerD("bt_device_create_bond() succeeded");
1159                 return;            
1160             }
1161             case BT_ERROR_INVALID_PARAMETER:
1162             {
1163                 LoggerE("Not found");
1164                 NotFoundException *error = new NotFoundException("Not found");
1165                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1166                 break;
1167             }
1168             default:
1169             {
1170                 LoggerE("Unknown exception");
1171                 UnknownException *error = new UnknownException("Unknown error");
1172                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1173             }            
1174         }        
1175     } else {   // Not enabled
1176         LoggerE("Bluetooth device is turned off");
1177         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
1178         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1179     }
1180
1181     bt_device_unset_bond_created_cb();
1182     mCreateBondingAddress.clear();
1183     mUserDataList[CREATE_BONDING].reset(); 
1184 }
1185
1186 void BluetoothAdapter::destroyBonding(std::string &address, MultiCallbackUserDataPtr userData)
1187 {
1188     if(!isValidAddress(address)) {
1189         LoggerE("Wrong address");
1190         NotFoundException *error = new NotFoundException("Wrong address");
1191         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1192         return;
1193     }
1194
1195     if(mUserDataList[DESTROY_BONDING] == NULL) {
1196         bt_device_set_bond_destroyed_cb(onBondDestroyedCB, this);
1197         mDestroyBondingAddress = address;
1198         mUserDataList[DESTROY_BONDING] = userData;
1199     } else {
1200         LoggerD("Already requested");
1201         UnknownException *error = new UnknownException("Already requested");
1202         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1203         return;
1204     }
1205     
1206     if(mEnabled == true) {
1207         bt_device_info_s *deviceInfo = NULL;
1208         if(bt_adapter_get_bonded_device_info(address.c_str(), &deviceInfo) != BT_ERROR_NONE || deviceInfo == NULL) {
1209             LoggerD("There is no bonding");
1210             NotFoundException *error = new NotFoundException("Not found");
1211             BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1212         }
1213         else {
1214             bt_adapter_free_device_info(deviceInfo);
1215             int ret = bt_device_destroy_bond(address.c_str());
1216             
1217             switch(ret) {
1218                 case BT_ERROR_NONE:
1219                 {
1220                     LoggerD("bt_device_destroy_bond() succeeded");
1221                     return;            
1222                 }
1223                 case BT_ERROR_INVALID_PARAMETER:
1224                 {
1225                     NotFoundException *error = new NotFoundException("Not found");
1226                     BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1227                     break;
1228                 }
1229                 default:
1230                 {
1231                     UnknownException *error = new UnknownException("Unknown error");
1232                     BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1233                 }            
1234             }        
1235         }
1236     } else {   // Not enabled
1237         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
1238         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1239     }
1240
1241     bt_device_unset_bond_destroyed_cb();
1242     mDestroyBondingAddress.clear();
1243     mUserDataList[DESTROY_BONDING].reset(); 
1244 }
1245
1246 void BluetoothAdapter::registerRFCOMMServiceByUUID(std::string &uuid, std::string &name, MultiCallbackUserDataPtr userData)
1247 {
1248     BluetoothCallbackUtil::syncToAsyncServiceCallback(userData, uuid, name);
1249 }
1250
1251 void BluetoothAdapter::connectToServiceByUUID(std::string &remoteAddress, std::string &uuid, Common::MultiCallbackUserDataPtr userData)
1252 {
1253     if(!isValidUUID(uuid)) {
1254         LoggerE("Wrong UUID");
1255         InvalidValuesException *error = new InvalidValuesException("Wrong UUID");
1256         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1257         return;
1258     }
1259     
1260
1261     if(mEnabled == true) {
1262         int ret = bt_socket_connect_rfcomm(remoteAddress.c_str(), uuid.c_str());
1263         
1264         switch(ret) {
1265             case BT_ERROR_NONE:
1266             {
1267                 LoggerD("bt_socket_connect_rfcomm() succeeded");
1268                 bt_socket_set_connection_state_changed_cb(onSocketConnected, this);
1269                 
1270                 BluetoothConnReqPtr connReq = new BluetoothConnReq(uuid, userData);
1271                 mConnReqMap.insert(std::pair<std::string, BluetoothConnReqPtr>(remoteAddress, connReq));
1272                 break;            
1273             }
1274             case BT_ERROR_INVALID_PARAMETER:
1275             case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
1276             {
1277                 InvalidValuesException *error = new InvalidValuesException("Invalid value");
1278                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1279                 break;
1280             }
1281             default:
1282             {
1283                 UnknownException *error = new UnknownException("Unknown error");
1284                 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1285             }            
1286         }        
1287     } else {   // Not enabled
1288         ServiceNotAvailableException *error =  new ServiceNotAvailableException("Bluetooth device is turned off");
1289         BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1290     }
1291 }
1292
1293 void BluetoothAdapter::returnKnownDevices(Common::MultiCallbackUserDataPtr userData)
1294 {
1295     if(mEnabled == true) {
1296         knownDevices = mFoundDevices;
1297         if(bt_adapter_foreach_bonded_device(foreachBondedDevicesCB, this) == BT_ERROR_NONE) {
1298             if(knownDevices.size() > 0) { // There are found devices
1299                 LoggerD("There are found devices");                        
1300                 int num = knownDevices.size();
1301                 JSObjectRef devices[num];
1302                 for(int i = 0; i < num; i++) {
1303                     JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(userData->getContext(), knownDevices[i]);                        
1304                     devices[i] = deviceObj;
1305                 }
1306
1307                 userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), num, devices, NULL));
1308             }
1309             else {  // There is no found device
1310                 userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), 0, NULL, NULL) );
1311             }
1312         }
1313         else {
1314             LoggerE("Unknown exception");
1315             userData->invokeCallback(
1316                     "error", 
1317                     JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception"))
1318             );
1319         }
1320     } else {   // Not enabled
1321         LoggerE("Bluetooth device is turned off");
1322         userData->invokeCallback(
1323                 "error",
1324                 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1325         );
1326     }
1327 }
1328
1329 void BluetoothAdapter::returnDevice(std::string &address, Common::MultiCallbackUserDataPtr userData)
1330 {
1331     if(!isValidAddress(address)) {
1332         LoggerE("Wrong address");
1333         userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("Wrong address")));
1334         return;
1335     }
1336
1337     if(mEnabled == true) {      
1338         bt_device_info_s *deviceInfo = NULL;
1339         if(bt_adapter_get_bonded_device_info(address.c_str(), &deviceInfo) == BT_ERROR_NONE &&
1340                 deviceInfo != NULL) {
1341             BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
1342             bt_adapter_free_device_info(deviceInfo);
1343
1344             LoggerD("invoke successCallback");
1345             userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), device));
1346             return;
1347         }
1348
1349         std::vector<BluetoothDeviceSharedPtr>::iterator iter;
1350         for(iter = mFoundDevices.begin(); iter != mFoundDevices.end(); ++iter) {
1351                 BluetoothDeviceSharedPtr foundDevice = *iter;
1352             if(!strcmp(foundDevice->getAddress().c_str(), address.c_str())) {
1353                 LoggerD("Found in mFoundDevices");                
1354                 userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), foundDevice));
1355                 break;
1356             }
1357         }
1358         
1359         if(iter == mFoundDevices.end()) {
1360             LoggerE("Can't find this device");
1361
1362             userData->invokeCallback(
1363                     "error",
1364                     JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("There is no device with the given address"))
1365             );            
1366         }        
1367
1368     } else {   // Not enabled
1369         LoggerE("Bluetooth device is turned off");
1370         userData->invokeCallback(
1371                 "error",
1372                 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1373         );
1374     }
1375 }
1376
1377 void BluetoothAdapter::returnRegisteredService(std::string &uuid, std::string &name, Common::MultiCallbackUserDataPtr userData)
1378 {
1379     if(!isValidUUID(uuid)) {
1380         LoggerE("Wrong UUID");
1381         userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Wrong UUID")));
1382         return;
1383     }
1384
1385     if(mEnabled == true) {
1386     
1387         bool isRegistered;
1388         if(bt_adapter_is_service_used(uuid.c_str(), &isRegistered) == BT_ERROR_NONE && isRegistered == true) {
1389             LoggerD("Already registered");
1390             userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Already registered")));
1391             return;
1392         }        
1393
1394         int socket = -1;
1395         int ret = bt_socket_create_rfcomm(uuid.c_str(), &socket);
1396         
1397         switch(ret) {
1398             case BT_ERROR_NONE:
1399             {
1400                 LoggerD("bt_socket_create_rfcomm() succeeded");
1401                 int ret = bt_socket_listen_and_accept_rfcomm(socket, 0);
1402                 switch(ret) {
1403                     case BT_ERROR_NONE:
1404                     {
1405                         LoggerD("bt_socket_listen() succeeded");                        
1406                         bt_socket_set_connection_state_changed_cb(onSocketConnected, this);
1407
1408                         BluetoothServiceHandlerPtr serviceHandler = new BluetoothServiceHandler(uuid, name, socket);
1409                         mRegisteredUUID.insert(std::pair<std::string, BluetoothServiceHandlerPtr>(uuid, serviceHandler));
1410                         
1411                         JSObjectRef serviceObj = JSBluetoothServiceHandler::createJSObject(userData->getContext(), serviceHandler);
1412                         userData->invokeCallback("success", serviceObj);
1413                         break;
1414                     }
1415                     case BT_ERROR_INVALID_PARAMETER:
1416                     {
1417                         LoggerD("Invalid value");
1418                         userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value")));
1419                         break;
1420                     }
1421                     default:
1422                     {
1423                         LoggerD("Unknown exception");
1424                         userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception")));
1425                     }                    
1426                 }
1427                 
1428                 break;            
1429             }
1430             case BT_ERROR_INVALID_PARAMETER:
1431             {
1432                 LoggerD("Invalid value");
1433                 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value")));
1434                 break;
1435             }
1436             default:
1437             {
1438                 LoggerD("Unknown exception");
1439                 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception")));
1440             }            
1441         }        
1442     } else {   // Not enabled
1443         LoggerE("Bluetooth device is turned off");
1444         userData->invokeCallback(
1445                 "error",
1446                 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1447         );
1448     }
1449 }
1450
1451
1452 } // Bluetooth
1453 } // DeviceAPI