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