2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
21 #include <JSWebAPIErrorFactory.h>
22 #include <system_info.h>
25 #include "BluetoothAdapter.h"
26 #include "BluetoothCallbackUtil.h"
27 #include "JSBluetoothDevice.h"
28 #include "JSBluetoothServiceHandler.h"
29 #include "JSBluetoothSocket.h"
30 #include "GlobalContextManager.h"
32 using namespace DeviceAPI::Common;
37 void BluetoothAdapter::onStateChangedCB(int result, bt_adapter_state_e adapterState, void *userData)
39 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
41 LoggerW("userData is NULL");
44 object->mEnabled = (adapterState == BT_ADAPTER_ENABLED) ? true : false;
46 if(object->mUserDataList[SET_POWERED] != NULL) { // requested event
47 bool state = (adapterState == BT_ADAPTER_ENABLED) ? true : false;
48 if(object->mRequestedState != state) {
49 LoggerW("Requested state is same to current state");
53 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_POWERED]);
54 object->mUserDataList[SET_POWERED].reset();
56 if(result == BT_ERROR_NONE) {
58 callback->invokeCallback("success");
60 else if(result == BT_ERROR_RESOURCE_BUSY) {
62 JSContextRef context = callback->getContext();
63 ServiceNotAvailableException error("Bluetooth device is busy");
64 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
69 JSContextRef context = callback->getContext();
70 UnknownException error("Unknown error");
71 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
75 else { // unexpected event
76 LoggerW("Bluetooth state is changed unexpectedly");
80 void BluetoothAdapter::onNameChangedCB(char *name, void *userData)
82 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
84 LoggerW("userData is NULL");
88 if(object->mUserDataList[SET_NAME] != NULL && !strcmp(object->mRequestedName.c_str(), name)) { // requested event
89 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_NAME]);
90 object->mUserDataList[SET_NAME].reset();
92 callback->invokeCallback("success");
94 bt_adapter_unset_name_changed_cb();
96 else { // unexpected event
97 LoggerW("Bluetooth name is changed unexpectedly");
101 void BluetoothAdapter::onVisibilityChangedCB(int result, bt_adapter_visibility_mode_e visibilityMode, void *userData)
103 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
105 LoggerW("userData is NULL");
109 if(object->mUserDataList[SET_VISIBLE] != NULL) { // requested event
110 //bool visibility = (visibilityMode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) ? false : true;
111 if(object->mRequestedVisibility != visibilityMode) {
112 LoggerW("Requested visibility is not same to current visibility");
116 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_VISIBLE]);
117 object->mUserDataList[SET_VISIBLE].reset();
119 if(result == BT_ERROR_NONE) {
121 callback->invokeCallback("success");
125 JSContextRef context = callback->getContext();
126 UnknownException error("Unknown error");
127 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
131 bt_adapter_unset_visibility_mode_changed_cb();
133 else { // unexpected event
134 LoggerW("Bluetooth visibility is changed unexpectedly");
138 void BluetoothAdapter::onDiscoveryStateChangedCB(int result, bt_adapter_device_discovery_state_e discoveryState,
139 bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
141 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
143 LoggerW("userData is NULL");
147 switch(discoveryState) {
148 case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
150 LoggerD("Discovery started");
151 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) { // requested event
152 MultiCallbackUserDataPtr callback =
153 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
155 if(result == BT_ERROR_NONE) {
157 // store MAC address of previously found device into mDisappearedDevices
158 object->mDisappearedDevices.clear();
159 for(std::vector<BluetoothDeviceSharedPtr>::iterator iter = object->mFoundDevices.begin();
160 iter != object->mFoundDevices.end(); iter++) {
161 BluetoothDeviceSharedPtr foundDevice = *iter;
162 object->mDisappearedDevices.push_back(foundDevice->getAddress());
165 object->mFoundDevices.clear();
167 callback->invokeCallback("onstarted");
171 object->mUserDataList[DISCOVER_DEVICES].reset();
173 JSContextRef context = callback->getContext();
174 UnknownException error("Unknown error");
175 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
179 if(object->mUserDataList[STOP_DISCOVERY] == NULL) // because same core API callback is used
180 bt_adapter_unset_device_discovery_state_changed_cb();
184 else { // unexpected event
185 LoggerW("Unexpected discovery");
189 case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
191 LoggerD("Discovery finished");
192 if(result == BT_ERROR_NONE || result == BT_ERROR_CANCELLED) {
193 // in case of discoverDevices()
194 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) {
195 MultiCallbackUserDataPtr callback =
196 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
199 if(object->mDisappearedDevices.size() > 0) {
200 LoggerD("There are disappeared devices");
201 for(std::vector<std::string>::iterator iter = object->mDisappearedDevices.begin();
202 iter != object->mDisappearedDevices.end(); iter++) {
204 callback->invokeCallback("ondevicedisappeared",
205 JSUtil::toJSValueRef(callback->getContext(), *iter));
209 if(object->mFoundDevices.size() > 0) { // There are found devices
210 LoggerD("There are found devices");
211 int num = object->mFoundDevices.size();
212 JSObjectRef devices[num];
213 for(int i = 0; i < num; i++) {
214 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(callback->getContext(), object->mFoundDevices[i]);
215 devices[i] = deviceObj;
218 object->mUserDataList[DISCOVER_DEVICES].reset();
220 callback->invokeCallback(
222 JSObjectMakeArray(callback->getContext(), num, devices, NULL) );
224 else { // There is no found device
225 LoggerD("There is no found device");
226 object->mUserDataList[DISCOVER_DEVICES].reset();
228 callback->invokeCallback(
230 JSObjectMakeArray(callback->getContext(), 0, NULL, NULL) );
235 // in case of stopDiscovery()
236 if(object->mUserDataList[STOP_DISCOVERY] != NULL) {
237 MultiCallbackUserDataPtr callback =
238 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[STOP_DISCOVERY]);
241 LoggerD("Call successCallback of stopDiscovery()");
242 object->mUserDataList[STOP_DISCOVERY].reset();
243 callback->invokeCallback("success");
247 //bt_adapter_unset_device_discovery_state_changed_cb();
250 LoggerW("Unexpected result of discovery finish");
254 case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
256 LoggerD("A device is found");
258 LoggerW("No information about found device");
262 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) { // requested event
263 MultiCallbackUserDataPtr callback =
264 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
266 if(result == BT_ERROR_NONE) {
267 // create BluetoothDevice
268 BluetoothDeviceSharedPtr device(new BluetoothDevice(discoveryInfo));
269 JSContextRef context = callback->getContext();
270 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device);
271 object->mFoundDevices.push_back(device);
273 // remove MAC address of found device from mDisappearedDevices
274 for(std::vector<std::string>::iterator iter = object->mDisappearedDevices.begin();
275 iter != object->mDisappearedDevices.end(); iter++) {
276 if(!strcmp(discoveryInfo->remote_address, (*iter).c_str())) {
277 object->mDisappearedDevices.erase(iter);
283 callback->invokeCallback("ondevicefound", deviceObj);
286 LoggerW("Unexpected result of discovery");
289 else { // unexpected event
290 LoggerW("Unexpected discovery");
296 LoggerW("Unknown state");
301 bool BluetoothAdapter::foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData)
303 BluetoothAdapterPtr adapter = static_cast<BluetoothAdapterPtr>(userData);
305 LoggerW("userData is NULL");
309 if(deviceInfo == NULL) {
310 LoggerW("deviceInfo is NULL");
314 std::vector<BluetoothDeviceSharedPtr>::iterator iter;
315 for(iter = adapter->knownDevices.begin(); iter != adapter->knownDevices.end(); ++iter) {
316 BluetoothDeviceSharedPtr foundDevice = *iter;
318 if(!strcmp(foundDevice->getAddress().c_str(), deviceInfo->remote_address)) {
319 foundDevice->updateInfo(deviceInfo);
324 if(iter == adapter->knownDevices.end()) {
325 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
326 adapter->knownDevices.push_back(device);
332 void BluetoothAdapter::onBondCreatedCB(int result, bt_device_info_s *deviceInfo, void *userData)
334 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
336 LoggerW("userData is NULL");
341 LoggerW("deviceInfo is NULL");
345 if(object->mUserDataList[CREATE_BONDING] != NULL &&
346 !strcmp(object->mCreateBondingAddress.c_str(), deviceInfo->remote_address)) { // requested event
348 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[CREATE_BONDING]);
349 object->mUserDataList[CREATE_BONDING].reset();
351 if(result == BT_ERROR_NONE && deviceInfo != NULL) {
353 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
354 JSContextRef context = callback->getContext();
355 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device);
356 callback->invokeCallback("success", deviceObj);
361 JSContextRef context = callback->getContext();
362 UnknownException error("Unknown error");
363 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
367 bt_device_unset_bond_created_cb();
368 object->mCreateBondingAddress.clear();
370 else { // unexpected event
371 LoggerW("A bonding is created unexpectedly");
375 void BluetoothAdapter::onBondDestroyedCB(int result, char *remoteAddress, void *userData)
377 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
379 LoggerW("userData is NULL");
383 if(object->mUserDataList[DESTROY_BONDING] != NULL &&
384 !strcmp(object->mDestroyBondingAddress.c_str(), remoteAddress)) { // requested event
386 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DESTROY_BONDING]);
387 object->mUserDataList[DESTROY_BONDING].reset();
389 if(result == BT_ERROR_NONE) {
391 callback->invokeCallback("success");
395 JSContextRef context = callback->getContext();
396 UnknownException error("Unknown error");
397 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
401 bt_device_unset_bond_destroyed_cb();
402 object->mDestroyBondingAddress.clear();
404 else { // unexpected event
405 LoggerW("A bonding is destroyed unexpectedly");
409 void BluetoothAdapter::onSocketConnected(int result, bt_socket_connection_state_e state, bt_socket_connection_s *connection, void *userData)
411 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
413 LoggerW("userData is NULL");
418 LoggerW("connection is NULL");
422 if(connection->local_role == BT_SOCKET_SERVER) {
423 RegisteredUUIDMapT::iterator iter = object->mRegisteredUUID.find(connection->service_uuid);
424 if(iter == object->mRegisteredUUID.end()) {
425 LoggerW("Connection state is changed unexpectedly");
429 if(state == BT_SOCKET_CONNECTED) { // connected when Server
430 if(result == BT_ERROR_NONE) {
431 // Update BluetoothServiceHandler
432 BluetoothServiceHandlerPtr service = iter->second;
433 service->setConnectionState(true);
435 // Call BluetoothServiceHandler.onconnect
436 BluetoothSocketPtr socket = new BluetoothSocket(connection);
437 MultiCallbackUserDataPtr callback = service->getOnConnect();
438 JSContextRef context = callback->getContext();
439 JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket);
441 callback->invokeCallback("onconnect", socketObj);
443 // Update mConnectedSocket
444 object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(connection->socket_fd, socket));
445 bt_socket_set_data_received_cb(onSocketReceivedCB, userData);
448 LoggerW("Establishing a connection failed");
452 else { // disconnected when Server
453 if(result == BT_ERROR_NONE) {
454 // Update BluetoothServiceHandler
455 BluetoothServiceHandlerPtr service = iter->second;
456 service->setConnectionState(false);
458 // call BluetoothSocket.onclose;
459 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd);
460 if(i == object->mConnectedSocket.end()) {
461 LoggerW("Unknown connected socket");
464 //BluetoothSocketSharedPtr socket = i->second;
465 BluetoothSocketPtr socket = i->second;
466 socket->setConnectionState(false);
467 MultiCallbackUserDataPtr callback = socket->getOnClose();
469 callback->invokeCallback("onclose");
471 // Update mConnectedSocket
472 object->mConnectedSocket.erase(i);
475 LoggerW("Disconnecting a connection failed");
479 else if(connection->local_role == BT_SOCKET_CLIENT) {
481 if(state == BT_SOCKET_CONNECTED) { // connected when Client
482 std::string remoteAddress(connection->remote_address);
483 ConnReqMultiMapT::iterator iter;
485 iter = object->mConnReqMap.find(remoteAddress);
486 if(iter != object->mConnReqMap.end() && !strcmp(iter->second->mUUID.c_str(), connection->service_uuid)) {
489 } while(iter != object->mConnReqMap.end());
491 if(iter == object->mConnReqMap.end()) {
492 LoggerW("Connection state is changed unexpectedly");
496 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(iter->second->mUserData);
498 if(result == BT_ERROR_NONE) {
499 // Update mConnectedSocket
500 BluetoothSocketPtr socket = new BluetoothSocket(connection);
501 object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(connection->socket_fd, socket));
502 bt_socket_set_data_received_cb(onSocketReceivedCB, userData);
504 // Call successcallback of connectToServiceByUUID
505 JSContextRef context = callback->getContext();
506 JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket);
508 callback->invokeCallback("success", socketObj);
510 // Update mConnReqMap
511 object->mConnReqMap.erase(iter);
514 // Call errorcallback of connectToServiceByUUID
515 JSContextRef context = callback->getContext();
516 NotFoundException error("Not found");
518 callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error));
520 // Update mConnReqMap
521 object->mConnReqMap.erase(iter);
525 else { // disconnected when Client
526 if(result == BT_ERROR_NONE) {
527 // call BluetoothSocket.onclose;
528 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd);
529 if(i == object->mConnectedSocket.end()) {
530 LoggerW("Unknown connected socket");
534 BluetoothSocketPtr socket = i->second;
535 socket->setConnectionState(false);
536 MultiCallbackUserDataPtr callback = socket->getOnClose();
538 callback->invokeCallback("onclose");
540 // Update mConnectedSocket
541 object->mConnectedSocket.erase(i);
544 LoggerW("Disconnecting a connection failed");
549 LoggerW("Unknown role");
553 if(object->mConnectedSocket.size() == 0) {
554 bt_socket_unset_data_received_cb();
557 if(object->mRegisteredUUID.size() == 0 && object->mConnReqMap.size() == 0 && object->mConnectedSocket.size() == 0) {
558 bt_socket_unset_connection_state_changed_cb();
562 void BluetoothAdapter::onSocketReceivedCB(bt_socket_received_data_s *data, void *userData)
564 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
566 LoggerW("userData is NULL");
571 LoggerW("data is NULL");
575 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(data->socket_fd);
576 if(i == object->mConnectedSocket.end()) {
577 LoggerW("Unknown connected socket");
581 // Store received data
582 BluetoothSocketPtr socket = i->second;
583 socket->storeRecivedData(data->data, static_cast<unsigned long>(data->data_size));
585 // Call BluetoothSocket.onmessage
586 MultiCallbackUserDataPtr callback = socket->getOnMessage();
588 callback->invokeCallback("onmessage");
591 BluetoothAdapter::BluetoothAdapter():
594 if(bt_initialize() != BT_ERROR_NONE) {
595 LoggerE("bt_initialize() failed");
598 bt_adapter_state_e state;
599 if (bt_adapter_get_state(&state) == BT_ERROR_NONE) {
600 if (state == BT_ADAPTER_ENABLED) {
605 if(bt_adapter_set_state_changed_cb(onStateChangedCB, this) != BT_ERROR_NONE) {
606 LoggerE("bt_adapter_set_state_changed_cb() failed");
609 if(bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this) != BT_ERROR_NONE) {
610 LoggerE("bt_adapter_set_device_discovery_state_changed_cb() failed");
614 BluetoothAdapter::~BluetoothAdapter()
616 // unset platform callback
617 bt_adapter_unset_state_changed_cb();
618 bt_adapter_unset_name_changed_cb();
619 bt_adapter_unset_visibility_mode_changed_cb();
620 bt_adapter_unset_device_discovery_state_changed_cb();
621 bt_device_unset_bond_created_cb();
622 bt_device_unset_bond_destroyed_cb();
623 bt_socket_unset_connection_state_changed_cb();
624 bt_socket_unset_data_received_cb();
627 for(int i = 0; i <= DESTROY_BONDING; i++) {
628 mUserDataList[i].reset();
630 mRegisteredUUID.clear();
632 mFoundDevices.clear();
633 mConnectedSocket.clear();
636 void BluetoothAdapter::unloadFrame(JSContextRef context)
638 LoggerD("Clean mUserDataList");
639 for(int i = 0; i <= DESTROY_BONDING; i++) {
640 if(mUserDataList[i]) {
641 MultiCallbackUserDataPtr callback = mUserDataList[i];
642 if(!GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) {
643 mUserDataList[i].reset();
648 LoggerD("Clean mConnReqMap");
649 for(ConnReqMultiMapT::iterator iter = mConnReqMap.begin(); iter != mConnReqMap.end(); ) {
650 ConnReqMultiMapT::iterator temp = iter++;
651 MultiCallbackUserDataPtr callback = temp->second->mUserData;
652 if(!callback && !GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) {
653 mConnReqMap.erase(temp);
658 void BluetoothAdapter::unregisterUUID(std::string &uuid)
660 mRegisteredUUID.erase(mRegisteredUUID.find(uuid));
661 if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
662 bt_socket_unset_connection_state_changed_cb();
666 bool BluetoothAdapter::closeConnectedSocket(int socket)
668 if(mEnabled == true) {
669 ConnectedSocketMapT::iterator iter = mConnectedSocket.find(socket);
670 if(iter == mConnectedSocket.end()) {
671 LoggerW("Already disconnected");
675 mConnectedSocket.erase(iter);
676 if(mConnectedSocket.size() == 0) {
677 bt_socket_unset_data_received_cb();
680 if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
681 bt_socket_unset_connection_state_changed_cb();
687 LoggerE("Bluetooth is not powered");
692 void BluetoothAdapter::removeConnReq(std::string &remoteAddress)
694 mConnReqMap.erase(remoteAddress);
696 if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
697 if(bt_socket_unset_connection_state_changed_cb() != BT_ERROR_NONE) {
698 LoggerW("Unsetting connection event callback failed");
703 BluetoothAdapter* BluetoothAdapter::getInstance()
705 static BluetoothAdapter instance;
709 bool BluetoothAdapter::isBluetoothSupported()
711 bool isSupported = false;
713 if(system_info_get_value_bool(SYSTEM_INFO_KEY_BLUETOOTH_SUPPORTED, &isSupported) != SYSTEM_INFO_ERROR_NONE) {
714 LoggerE("Can't know whether Bluetooth is supported or not");
720 bool BluetoothAdapter::isValidAddress(std::string &address)
722 pcrecpp::RE re("(([0-9a-zA-Z]+):)+([0-9a-zA-Z]+)");
723 std::string compareAddress = "00:12:47:08:9A:A6";
725 if (!re.FullMatch(address)) {
726 LoggerE("Invalid address");
730 if (address.size() != compareAddress.size())
732 LoggerE("Invalid size");
739 bool BluetoothAdapter::isValidUUID(std::string &uuid)
741 pcrecpp::RE re("(([0-9a-zA-Z]+)-)+([0-9a-zA-Z]+)");
742 std::string compareUUID = "00001101-0000-1000-8000-00805F9B34FB";
744 if (!re.FullMatch(uuid))
746 LoggerE("Invalid UUID");
750 if (uuid.size() != compareUUID.size())
752 LoggerE("Invalid size");
759 std::string BluetoothAdapter::getName() const
762 std::string str = "";
764 if(bt_adapter_get_name(&name) == BT_ERROR_NONE) {
772 LoggerE("bt_adapter_get_name() failed");
778 void BluetoothAdapter::setName(std::string &name, MultiCallbackUserDataPtr userData)
780 if(mEnabled == true) {
781 std::string adapterName = getName();
782 if(adapterName == name) { // in case of same name
783 LoggerD("same name");
784 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
788 if(mUserDataList[SET_NAME] == NULL) {
789 bt_adapter_set_name_changed_cb(onNameChangedCB, this);
790 mUserDataList[SET_NAME] = userData;
792 LoggerE("Already requested");
793 UnknownException *error = new UnknownException("Already requested");
794 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
798 int ret = bt_adapter_set_name(name.c_str());
803 LoggerD("bt_adapter_set_name() succeeded");
804 mRequestedName = name;
807 case BT_ERROR_INVALID_PARAMETER:
809 LoggerE("Invalid value");
810 InvalidValuesException *error = new InvalidValuesException("Invalid value");
811 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
816 LoggerE("Invalid value");
817 UnknownException *error = new UnknownException("Unknown exception");
818 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
822 bt_adapter_unset_name_changed_cb();
823 mUserDataList[SET_NAME].reset();
824 } else { // Not enabled
825 LoggerE("Bluetooth device is turned off");
826 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
827 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
831 std::string BluetoothAdapter::getAddress() const
833 char* address = NULL;
834 std::string str = "";
836 if (bt_adapter_get_address(&address) == BT_ERROR_NONE) {
837 if (address != NULL) {
842 LoggerW("address is NULL");
846 LoggerE("bt_adapter_get_address() failed");
852 bool BluetoothAdapter::getPowered() const
857 void BluetoothAdapter::setPowered(bool powered, MultiCallbackUserDataPtr userData)
859 if(powered == mEnabled) {
860 LoggerD("same state");
861 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
865 if(mUserDataList[SET_POWERED] == NULL) {
866 mUserDataList[SET_POWERED] = userData;
869 LoggerE("Already requested");
870 ServiceNotAvailableException *error = new ServiceNotAvailableException("Already requested");
871 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
875 mRequestedState = powered;
876 if(powered == true) {
877 int ret = bt_adapter_enable();
882 LoggerD("bt_adapter_enable() succeeded");
885 case BT_ERROR_ALREADY_DONE:
887 // call successCallback
888 LoggerD("BT_ERROR_ALREADY_DONE");
889 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
892 case BT_ERROR_NOW_IN_PROGRESS:
894 LoggerD("BT_ERROR_NOW_IN_PROGRESS");
895 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is busy");
896 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
901 LoggerD("Unknown error");
902 UnknownException *error = new UnknownException("Unknown error");
903 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
907 int ret = bt_adapter_disable();
912 LoggerD("bt_adapter_disable() succeeded");
915 case BT_ERROR_NOT_ENABLED:
917 // call successCallback
918 LoggerD("Already disabled");
919 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
922 case BT_ERROR_NOW_IN_PROGRESS:
924 LoggerD("BT_ERROR_NOW_IN_PROGRESS");
925 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is busy");
926 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
931 LoggerD("Unknown error");
932 UnknownException *error = new UnknownException("Unknown error");
933 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
938 mUserDataList[SET_POWERED].reset();
941 bool BluetoothAdapter::getVisible() const
943 bt_adapter_visibility_mode_e mode;
945 if (bt_adapter_get_visibility(&mode, NULL) == BT_ERROR_NONE) {
946 if (mode != BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
954 void BluetoothAdapter::setVisible(bool visible, unsigned int timeout, MultiCallbackUserDataPtr userData)
956 if(mEnabled == true) {
957 bt_adapter_visibility_mode_e discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
958 if(visible == true) {
960 discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE;
962 discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
965 bt_adapter_visibility_mode_e current = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
967 if(bt_adapter_get_visibility(¤t , &time) != BT_ERROR_NONE) {
968 LoggerE("bt_adapter_get_visibility() failed");
969 UnknownException *error = new UnknownException("Can't get current visibility");
970 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
974 if(discoverable_mode == current) {
975 if(discoverable_mode != BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE) {
976 LoggerD("same visibility");
977 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
980 else if((unsigned int)time == timeout) {
981 LoggerD("same visibility");
982 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
987 if(mUserDataList[SET_VISIBLE] == NULL) {
988 bt_adapter_set_visibility_mode_changed_cb(onVisibilityChangedCB, this);
989 mUserDataList[SET_VISIBLE] = userData;
991 UnknownException *error = new UnknownException("Already requested");
992 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
996 mRequestedVisibility = discoverable_mode;
997 int ret = bt_adapter_set_visibility(discoverable_mode, timeout);
1001 LoggerD("bt_adapter_set_visibility() succeeded");
1004 case BT_ERROR_INVALID_PARAMETER:
1006 InvalidValuesException *error = new InvalidValuesException("Invalid value");
1007 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1012 UnknownException *error = new UnknownException("Unknown error");
1013 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1017 bt_adapter_unset_visibility_mode_changed_cb();
1018 mUserDataList[SET_VISIBLE].reset();
1019 } else { // Not enabled
1020 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1021 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1026 void BluetoothAdapter::discoverDevices(MultiCallbackUserDataPtr userData)
1028 if(mUserDataList[DISCOVER_DEVICES] == NULL) {
1029 mUserDataList[DISCOVER_DEVICES] = userData;
1032 if(mUserDataList[STOP_DISCOVERY] == NULL)
1033 bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this);
1036 LoggerE("Already requested");
1037 UnknownException *error = new UnknownException("Already requested");
1038 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1042 if(mEnabled == true) {
1043 int ret = bt_adapter_start_device_discovery();
1047 LoggerD("bt_adapter_start_device_discovery() succeeded");
1052 LoggerE("Unknown exception");
1053 UnknownException *error = new UnknownException("Unknown error");
1054 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1057 } else { // Not enabled
1058 LoggerE("Bluetooth device is turned off");
1059 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1060 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1063 mUserDataList[DISCOVER_DEVICES].reset();
1065 if(mUserDataList[STOP_DISCOVERY] == NULL) {
1066 bt_adapter_unset_device_discovery_state_changed_cb();
1071 void BluetoothAdapter::stopDiscovery(MultiCallbackUserDataPtr userData)
1073 if(mEnabled == true) {
1075 bool isDiscovering = false;
1076 bt_adapter_is_discovering(&isDiscovering);
1077 if(!isDiscovering) {
1078 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
1082 if(mUserDataList[STOP_DISCOVERY] == NULL) {
1083 mUserDataList[STOP_DISCOVERY] = userData;
1086 if(mUserDataList[DISCOVER_DEVICES] == NULL)
1087 bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this);
1090 LoggerD("Already requested");
1091 UnknownException *error = new UnknownException("Already requested");
1092 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1096 int ret = bt_adapter_stop_device_discovery();
1100 LoggerD("bt_adapter_stop_device_discovery() succeeded");
1105 UnknownException *error = new UnknownException("Unknown error");
1106 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1110 mUserDataList[STOP_DISCOVERY].reset();
1112 if(mUserDataList[DISCOVER_DEVICES] == NULL) {
1113 bt_adapter_unset_device_discovery_state_changed_cb();
1116 } else { // Not enabled
1117 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1118 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1122 void BluetoothAdapter::getKnownDevices(MultiCallbackUserDataPtr userData)
1124 BluetoothCallbackUtil::syncToAsyncDeviceArrayCallback(userData);
1127 void BluetoothAdapter::getDevice(std::string &address, MultiCallbackUserDataPtr userData)
1129 BluetoothCallbackUtil::syncToAsyncDeviceCallback(userData, address);
1132 void BluetoothAdapter::createBonding(std::string &address, MultiCallbackUserDataPtr userData)
1134 if(!isValidAddress(address)) {
1135 LoggerE("Wrong address");
1136 NotFoundException *error = new NotFoundException("Wrong address");
1137 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1141 if(mUserDataList[CREATE_BONDING] == NULL) {
1142 bt_device_set_bond_created_cb(onBondCreatedCB, this);
1143 mCreateBondingAddress = address;
1144 mUserDataList[CREATE_BONDING] = userData;
1146 LoggerE("Already requested");
1147 UnknownException *error = new UnknownException("Already requested");
1148 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1152 if(mEnabled == true) {
1153 int ret = bt_device_create_bond(address.c_str());
1158 LoggerD("bt_device_create_bond() succeeded");
1161 case BT_ERROR_INVALID_PARAMETER:
1163 LoggerE("Not found");
1164 NotFoundException *error = new NotFoundException("Not found");
1165 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1170 LoggerE("Unknown exception");
1171 UnknownException *error = new UnknownException("Unknown error");
1172 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1175 } else { // Not enabled
1176 LoggerE("Bluetooth device is turned off");
1177 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1178 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1181 bt_device_unset_bond_created_cb();
1182 mCreateBondingAddress.clear();
1183 mUserDataList[CREATE_BONDING].reset();
1186 void BluetoothAdapter::destroyBonding(std::string &address, MultiCallbackUserDataPtr userData)
1188 if(!isValidAddress(address)) {
1189 LoggerE("Wrong address");
1190 NotFoundException *error = new NotFoundException("Wrong address");
1191 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1195 if(mUserDataList[DESTROY_BONDING] == NULL) {
1196 bt_device_set_bond_destroyed_cb(onBondDestroyedCB, this);
1197 mDestroyBondingAddress = address;
1198 mUserDataList[DESTROY_BONDING] = userData;
1200 LoggerD("Already requested");
1201 UnknownException *error = new UnknownException("Already requested");
1202 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1206 if(mEnabled == true) {
1207 bt_device_info_s *deviceInfo = NULL;
1208 if(bt_adapter_get_bonded_device_info(address.c_str(), &deviceInfo) != BT_ERROR_NONE || deviceInfo == NULL) {
1209 LoggerD("There is no bonding");
1210 NotFoundException *error = new NotFoundException("Not found");
1211 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1214 bt_adapter_free_device_info(deviceInfo);
1215 int ret = bt_device_destroy_bond(address.c_str());
1220 LoggerD("bt_device_destroy_bond() succeeded");
1223 case BT_ERROR_INVALID_PARAMETER:
1225 NotFoundException *error = new NotFoundException("Not found");
1226 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1231 UnknownException *error = new UnknownException("Unknown error");
1232 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1236 } else { // Not enabled
1237 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1238 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1241 bt_device_unset_bond_destroyed_cb();
1242 mDestroyBondingAddress.clear();
1243 mUserDataList[DESTROY_BONDING].reset();
1246 void BluetoothAdapter::registerRFCOMMServiceByUUID(std::string &uuid, std::string &name, MultiCallbackUserDataPtr userData)
1248 BluetoothCallbackUtil::syncToAsyncServiceCallback(userData, uuid, name);
1251 void BluetoothAdapter::connectToServiceByUUID(std::string &remoteAddress, std::string &uuid, Common::MultiCallbackUserDataPtr userData)
1253 if(!isValidUUID(uuid)) {
1254 LoggerE("Wrong UUID");
1255 InvalidValuesException *error = new InvalidValuesException("Wrong UUID");
1256 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1261 if(mEnabled == true) {
1262 int ret = bt_socket_connect_rfcomm(remoteAddress.c_str(), uuid.c_str());
1267 LoggerD("bt_socket_connect_rfcomm() succeeded");
1268 bt_socket_set_connection_state_changed_cb(onSocketConnected, this);
1270 BluetoothConnReqPtr connReq = new BluetoothConnReq(uuid, userData);
1271 mConnReqMap.insert(std::pair<std::string, BluetoothConnReqPtr>(remoteAddress, connReq));
1274 case BT_ERROR_INVALID_PARAMETER:
1275 case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
1277 InvalidValuesException *error = new InvalidValuesException("Invalid value");
1278 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1283 UnknownException *error = new UnknownException("Unknown error");
1284 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1287 } else { // Not enabled
1288 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1289 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1293 void BluetoothAdapter::returnKnownDevices(Common::MultiCallbackUserDataPtr userData)
1295 if(mEnabled == true) {
1296 knownDevices = mFoundDevices;
1297 if(bt_adapter_foreach_bonded_device(foreachBondedDevicesCB, this) == BT_ERROR_NONE) {
1298 if(knownDevices.size() > 0) { // There are found devices
1299 LoggerD("There are found devices");
1300 int num = knownDevices.size();
1301 JSObjectRef devices[num];
1302 for(int i = 0; i < num; i++) {
1303 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(userData->getContext(), knownDevices[i]);
1304 devices[i] = deviceObj;
1307 userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), num, devices, NULL));
1309 else { // There is no found device
1310 userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), 0, NULL, NULL) );
1314 LoggerE("Unknown exception");
1315 userData->invokeCallback(
1317 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception"))
1320 } else { // Not enabled
1321 LoggerE("Bluetooth device is turned off");
1322 userData->invokeCallback(
1324 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1329 void BluetoothAdapter::returnDevice(std::string &address, Common::MultiCallbackUserDataPtr userData)
1331 if(!isValidAddress(address)) {
1332 LoggerE("Wrong address");
1333 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("Wrong address")));
1337 if(mEnabled == true) {
1338 bt_device_info_s *deviceInfo = NULL;
1339 if(bt_adapter_get_bonded_device_info(address.c_str(), &deviceInfo) == BT_ERROR_NONE &&
1340 deviceInfo != NULL) {
1341 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
1342 bt_adapter_free_device_info(deviceInfo);
1344 LoggerD("invoke successCallback");
1345 userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), device));
1349 std::vector<BluetoothDeviceSharedPtr>::iterator iter;
1350 for(iter = mFoundDevices.begin(); iter != mFoundDevices.end(); ++iter) {
1351 BluetoothDeviceSharedPtr foundDevice = *iter;
1352 if(!strcmp(foundDevice->getAddress().c_str(), address.c_str())) {
1353 LoggerD("Found in mFoundDevices");
1354 userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), foundDevice));
1359 if(iter == mFoundDevices.end()) {
1360 LoggerE("Can't find this device");
1362 userData->invokeCallback(
1364 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("There is no device with the given address"))
1368 } else { // Not enabled
1369 LoggerE("Bluetooth device is turned off");
1370 userData->invokeCallback(
1372 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1377 void BluetoothAdapter::returnRegisteredService(std::string &uuid, std::string &name, Common::MultiCallbackUserDataPtr userData)
1379 if(!isValidUUID(uuid)) {
1380 LoggerE("Wrong UUID");
1381 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Wrong UUID")));
1385 if(mEnabled == true) {
1388 if(bt_adapter_is_service_used(uuid.c_str(), &isRegistered) == BT_ERROR_NONE && isRegistered == true) {
1389 LoggerD("Already registered");
1390 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Already registered")));
1395 int ret = bt_socket_create_rfcomm(uuid.c_str(), &socket);
1400 LoggerD("bt_socket_create_rfcomm() succeeded");
1401 int ret = bt_socket_listen_and_accept_rfcomm(socket, 0);
1405 LoggerD("bt_socket_listen() succeeded");
1406 bt_socket_set_connection_state_changed_cb(onSocketConnected, this);
1408 BluetoothServiceHandlerPtr serviceHandler = new BluetoothServiceHandler(uuid, name, socket);
1409 mRegisteredUUID.insert(std::pair<std::string, BluetoothServiceHandlerPtr>(uuid, serviceHandler));
1411 JSObjectRef serviceObj = JSBluetoothServiceHandler::createJSObject(userData->getContext(), serviceHandler);
1412 userData->invokeCallback("success", serviceObj);
1415 case BT_ERROR_INVALID_PARAMETER:
1417 LoggerD("Invalid value");
1418 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value")));
1423 LoggerD("Unknown exception");
1424 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception")));
1430 case BT_ERROR_INVALID_PARAMETER:
1432 LoggerD("Invalid value");
1433 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value")));
1438 LoggerD("Unknown exception");
1439 userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception")));
1442 } else { // Not enabled
1443 LoggerE("Bluetooth device is turned off");
1444 userData->invokeCallback(
1446 JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))