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