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 <JSWebAPIError.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)
41 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
43 LoggerW("userData is NULL");
46 object->mEnabled = (adapterState == BT_ADAPTER_ENABLED) ? true : false;
48 if(object->mUserDataList[SET_POWERED] != NULL) { // requested event
49 bool state = (adapterState == BT_ADAPTER_ENABLED) ? true : false;
50 if(object->mRequestedState != state) {
51 LoggerW("Requested state is same to current state");
55 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_POWERED]);
56 object->mUserDataList[SET_POWERED].reset();
58 if(result == BT_ERROR_NONE) {
60 callback->invokeCallback("success");
62 else if(result == BT_ERROR_RESOURCE_BUSY) {
64 JSContextRef context = callback->getContext();
65 ServiceNotAvailableException error("Bluetooth device is busy");
66 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
71 JSContextRef context = callback->getContext();
72 UnknownException error("Unknown error");
73 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
77 else { // unexpected event
78 LoggerW("Bluetooth state is changed unexpectedly");
82 void BluetoothAdapter::onNameChangedCB(char *name, void *userData)
86 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
88 LoggerW("userData is NULL");
92 if(object->mUserDataList[SET_NAME] != NULL && !strcmp(object->mRequestedName.c_str(), name)) { // requested event
93 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_NAME]);
94 object->mUserDataList[SET_NAME].reset();
96 callback->invokeCallback("success");
98 bt_adapter_unset_name_changed_cb();
100 else { // unexpected event
101 LoggerW("Bluetooth name is changed unexpectedly");
105 void BluetoothAdapter::onVisibilityChangedCB(int result, bt_adapter_visibility_mode_e visibilityMode, void *userData)
109 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
111 LoggerW("userData is NULL");
115 if(object->mUserDataList[SET_VISIBLE] != NULL) { // requested event
116 //bool visibility = (visibilityMode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) ? false : true;
117 if(object->mRequestedVisibility != visibilityMode) {
118 LoggerW("Requested visibility is not same to current visibility");
122 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[SET_VISIBLE]);
123 object->mUserDataList[SET_VISIBLE].reset();
125 if(result == BT_ERROR_NONE) {
127 callback->invokeCallback("success");
131 JSContextRef context = callback->getContext();
132 UnknownException error("Unknown error");
133 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
137 bt_adapter_unset_visibility_mode_changed_cb();
139 else { // unexpected event
140 LoggerW("Bluetooth visibility is changed unexpectedly");
144 void BluetoothAdapter::onDiscoveryStateChangedCB(int result, bt_adapter_device_discovery_state_e discoveryState,
145 bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
149 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
151 LoggerW("userData is NULL");
155 switch(discoveryState) {
156 case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
158 LoggerD("BT_ADAPTER_DEVICE_DISCOVERY_STARTED");
159 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) { // requested event
160 MultiCallbackUserDataPtr callback =
161 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
163 if(result == BT_ERROR_NONE) {
165 // store MAC address of previously found device into mDisappearedDevices
166 object->mDisappearedDevices.clear();
167 for(std::vector<BluetoothDeviceSharedPtr>::iterator iter = object->mFoundDevices.begin();
168 iter != object->mFoundDevices.end(); iter++) {
169 BluetoothDeviceSharedPtr foundDevice = *iter;
170 object->mDisappearedDevices.push_back(foundDevice->getAddress());
173 object->mFoundDevices.clear();
175 callback->invokeCallback("onstarted");
179 LoggerD("Reset DISCOVER_DEVICES");
180 object->mUserDataList[DISCOVER_DEVICES].reset();
182 JSContextRef context = callback->getContext();
183 UnknownException error("Unknown error");
184 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
188 if(object->mUserDataList[STOP_DISCOVERY] == NULL) // because same core API callback is used
189 bt_adapter_unset_device_discovery_state_changed_cb();
193 else { // unexpected event
194 LoggerW("Unexpected discovery");
198 case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
200 LoggerD("BT_ADAPTER_DEVICE_DISCOVERY_FINISHED");
201 if(result == BT_ERROR_NONE || result == BT_ERROR_CANCELLED) {
202 // in case of discoverDevices()
203 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) {
204 MultiCallbackUserDataPtr callback =
205 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
208 LoggerD("Call onfinished()");
209 if(object->mDisappearedDevices.size() > 0) {
210 LoggerD("There are disappeared devices");
211 for(std::vector<std::string>::iterator iter = object->mDisappearedDevices.begin();
212 iter != object->mDisappearedDevices.end(); iter++) {
214 callback->invokeCallback("ondevicedisappeared",
215 JSUtil::toJSValueRef(callback->getContext(), *iter));
219 if(object->mFoundDevices.size() > 0) { // There are found devices
220 LoggerD("There are found devices");
221 int num = object->mFoundDevices.size();
222 JSObjectRef devices[num];
223 for(int i = 0; i < num; i++) {
224 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(callback->getContext(), object->mFoundDevices[i]);
225 devices[i] = deviceObj;
228 LoggerD("Reset DISCOVER_DEVICES");
229 object->mUserDataList[DISCOVER_DEVICES].reset();
231 callback->invokeCallback(
233 JSObjectMakeArray(callback->getContext(), num, devices, NULL) );
235 else { // There is no found device
236 LoggerD("There is no found device");
238 LoggerD("Reset DISCOVER_DEVICES");
239 object->mUserDataList[DISCOVER_DEVICES].reset();
241 callback->invokeCallback(
243 JSObjectMakeArray(callback->getContext(), 0, NULL, NULL) );
248 // in case of stopDiscovery()
249 if(object->mUserDataList[STOP_DISCOVERY] != NULL) {
250 MultiCallbackUserDataPtr callback =
251 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[STOP_DISCOVERY]);
254 LoggerD("Call successCallback of stopDiscovery()");
255 object->mUserDataList[STOP_DISCOVERY].reset();
256 callback->invokeCallback("success");
260 //bt_adapter_unset_device_discovery_state_changed_cb();
263 LoggerW("result MUST be BT_ERROR_NONE or BT_ERROR_CANCELLED when BT_ADAPTER_DEVICE_DISCOVERY_FINISHED");
267 case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
269 LoggerD("BT_ADAPTER_DEVICE_DISCOVERY_FOUND");
271 LoggerW("discoveryInfo is NULL");
275 if(object->mUserDataList[DISCOVER_DEVICES] != NULL) { // requested event
276 MultiCallbackUserDataPtr callback =
277 static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DISCOVER_DEVICES]);
279 if(result == BT_ERROR_NONE) {
280 // create BluetoothDevice
281 BluetoothDeviceSharedPtr device(new BluetoothDevice(discoveryInfo));
282 JSContextRef context = callback->getContext();
283 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device);
284 object->mFoundDevices.push_back(device);
286 // remove MAC address of found device from mDisappearedDevices
287 for(std::vector<std::string>::iterator iter = object->mDisappearedDevices.begin();
288 iter != object->mDisappearedDevices.end(); iter++) {
289 if(!strcmp(discoveryInfo->remote_address, (*iter).c_str())) {
290 LoggerD("This device is still found");
291 object->mDisappearedDevices.erase(iter);
297 callback->invokeCallback("ondevicefound", deviceObj);
300 LoggerW("result MUST be BT_ERROR_NONE when BT_ADAPTER_DEVICE_DISCOVERY_FOUND");
303 else { // unexpected event
304 LoggerW("Unexpected discovery");
310 LoggerW("Unknown state");
315 bool BluetoothAdapter::foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData)
319 BluetoothAdapterPtr adapter = static_cast<BluetoothAdapterPtr>(userData);
321 LoggerW("userData is NULL");
325 if(deviceInfo == NULL) {
326 LoggerW("deviceInfo is NULL");
330 std::vector<BluetoothDeviceSharedPtr>::iterator iter;
331 for(iter = adapter->knownDevices.begin(); iter != adapter->knownDevices.end(); ++iter) {
332 BluetoothDeviceSharedPtr foundDevice = *iter;
334 if(!strcmp(foundDevice->getAddress().c_str(), deviceInfo->remote_address)) {
335 LoggerD("Already known device");
336 foundDevice->updateInfo(deviceInfo);
341 if(iter == adapter->knownDevices.end()) {
342 LoggerD("Add a device into foundDevices");
343 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
344 adapter->knownDevices.push_back(device);
350 void BluetoothAdapter::onBondCreatedCB(int result, bt_device_info_s *deviceInfo, void *userData)
354 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
356 LoggerW("userData is NULL");
361 LoggerW("deviceInfo is NULL");
365 if(object->mUserDataList[CREATE_BONDING] != NULL &&
366 !strcmp(object->mCreateBondingAddress.c_str(), deviceInfo->remote_address)) { // requested event
368 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[CREATE_BONDING]);
369 object->mUserDataList[CREATE_BONDING].reset();
371 if(result == BT_ERROR_NONE && deviceInfo != NULL) {
373 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
374 JSContextRef context = callback->getContext();
375 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device);
376 callback->invokeCallback("success", deviceObj);
381 JSContextRef context = callback->getContext();
382 UnknownException error("Unknown error");
383 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
387 bt_device_unset_bond_created_cb();
388 object->mCreateBondingAddress.clear();
390 else { // unexpected event
391 LoggerW("A bonding is created unexpectedly");
395 void BluetoothAdapter::onBondDestroyedCB(int result, char *remoteAddress, void *userData)
399 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
401 LoggerW("userData is NULL");
405 if(object->mUserDataList[DESTROY_BONDING] != NULL &&
406 !strcmp(object->mDestroyBondingAddress.c_str(), remoteAddress)) { // requested event
408 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(object->mUserDataList[DESTROY_BONDING]);
409 object->mUserDataList[DESTROY_BONDING].reset();
411 if(result == BT_ERROR_NONE) {
413 callback->invokeCallback("success");
417 JSContextRef context = callback->getContext();
418 UnknownException error("Unknown error");
419 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
423 bt_device_unset_bond_destroyed_cb();
424 object->mDestroyBondingAddress.clear();
426 else { // unexpected event
427 LoggerW("A bonding is created unexpectedly");
431 void BluetoothAdapter::onSocketConnected(int result, bt_socket_connection_state_e state, bt_socket_connection_s *connection, void *userData)
435 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
437 LoggerW("userData is NULL");
442 LoggerW("connection is NULL");
446 if(connection->local_role == BT_SOCKET_SERVER) {
447 RegisteredUUIDMapT::iterator iter = object->mRegisteredUUID.find(connection->service_uuid);
448 if(iter == object->mRegisteredUUID.end()) {
449 LoggerW("Connection state is changed unexpectedly");
453 if(state == BT_SOCKET_CONNECTED) { // connected when Server
454 if(result == BT_ERROR_NONE) {
455 // Update BluetoothServiceHandler
456 BluetoothServiceHandlerPtr service = iter->second;
457 service->setConnectionState(true);
459 // Call BluetoothServiceHandler.onconnect
460 BluetoothSocketPtr socket = new BluetoothSocket(connection);
461 MultiCallbackUserDataPtr callback = service->getOnConnect();
462 JSContextRef context = callback->getContext();
463 JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket);
465 callback->invokeCallback("onconnect", socketObj);
467 // Update mConnectedSocket
468 object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(connection->socket_fd, socket));
469 bt_socket_set_data_received_cb(onSocketReceivedCB, userData);
472 LoggerW("Establishing a connection failed");
476 else { // disconnected when Server
477 if(result == BT_ERROR_NONE) {
478 // Update BluetoothServiceHandler
479 BluetoothServiceHandlerPtr service = iter->second;
480 service->setConnectionState(false);
482 // call BluetoothSocket.onclose;
483 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd);
484 if(i == object->mConnectedSocket.end()) {
485 LoggerW("Unknown connected socket");
488 //BluetoothSocketSharedPtr socket = i->second;
489 BluetoothSocketPtr socket = i->second;
490 socket->setConnectionState(false);
491 MultiCallbackUserDataPtr callback = socket->getOnClose();
493 callback->invokeCallback("onclose");
495 // Update mConnectedSocket
496 object->mConnectedSocket.erase(i);
499 LoggerW("Disconnecting a connection failed");
503 else if(connection->local_role == BT_SOCKET_CLIENT) {
505 if(state == BT_SOCKET_CONNECTED) { // connected when Client
506 std::string remoteAddress(connection->remote_address);
507 ConnReqMultiMapT::iterator iter;
509 iter = object->mConnReqMap.find(remoteAddress);
510 if(iter != object->mConnReqMap.end() && !strcmp(iter->second->mUUID.c_str(), connection->service_uuid)) {
514 } while(iter != object->mConnReqMap.end());
516 if(iter == object->mConnReqMap.end()) {
517 LoggerW("Connection state is changed unexpectedly");
521 MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(iter->second->mUserData);
523 if(result == BT_ERROR_NONE) {
524 // Update mConnectedSocket
525 BluetoothSocketPtr socket = new BluetoothSocket(connection);
526 object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(connection->socket_fd, socket));
527 bt_socket_set_data_received_cb(onSocketReceivedCB, userData);
529 // Call successcallback of connectToServiceByUUID
530 JSContextRef context = callback->getContext();
531 JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket);
533 callback->invokeCallback("success", socketObj);
535 // Update mConnReqMap
536 object->mConnReqMap.erase(iter);
539 // Call errorcallback of connectToServiceByUUID
540 JSContextRef context = callback->getContext();
541 NotFoundException error("Not found");
543 callback->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(context, error));
545 // Update mConnReqMap
546 object->mConnReqMap.erase(iter);
550 else { // disconnected when Client
551 if(result == BT_ERROR_NONE) {
552 // call BluetoothSocket.onclose;
553 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd);
554 if(i == object->mConnectedSocket.end()) {
555 LoggerW("Unknown connected socket");
559 BluetoothSocketPtr socket = i->second;
560 socket->setConnectionState(false);
561 MultiCallbackUserDataPtr callback = socket->getOnClose();
563 callback->invokeCallback("onclose");
565 // Update mConnectedSocket
566 object->mConnectedSocket.erase(i);
569 LoggerW("Disconnecting a connection failed");
574 LoggerW("Unknown role");
578 if(object->mConnectedSocket.size() == 0) {
579 bt_socket_unset_data_received_cb();
582 if(object->mRegisteredUUID.size() == 0 && object->mConnReqMap.size() == 0 && object->mConnectedSocket.size() == 0) {
583 LoggerD("mRegisteredUUID.size()=%d, mConnReqMap.size()=%d, mConnectedSocket.size()=%d",
584 object->mRegisteredUUID.size(), object->mConnReqMap.size(), object->mConnectedSocket.size());
585 bt_socket_unset_connection_state_changed_cb();
589 void BluetoothAdapter::onSocketReceivedCB(bt_socket_received_data_s *data, void *userData)
593 BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(userData);
595 LoggerW("userData is NULL");
600 LoggerW("data is NULL");
604 ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(data->socket_fd);
605 if(i == object->mConnectedSocket.end()) {
606 LoggerW("Unknown connected socket");
610 // Store received data
611 BluetoothSocketPtr socket = i->second;
612 socket->storeRecivedData(data->data, static_cast<unsigned long>(data->data_size));
614 // Call BluetoothSocket.onmessage
615 MultiCallbackUserDataPtr callback = socket->getOnMessage();
617 callback->invokeCallback("onmessage");
620 BluetoothAdapter::BluetoothAdapter():
625 if(bt_initialize() != BT_ERROR_NONE) {
626 LoggerE("bt_initialize() failed");
629 bt_adapter_state_e state;
630 if (bt_adapter_get_state(&state) == BT_ERROR_NONE) {
631 if (state == BT_ADAPTER_ENABLED) {
636 if(bt_adapter_set_state_changed_cb(onStateChangedCB, this) != BT_ERROR_NONE) {
637 LoggerE("bt_adapter_set_state_changed_cb() failed");
640 if(bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this) != BT_ERROR_NONE) {
641 LoggerE("bt_adapter_set_device_discovery_state_changed_cb() failed");
645 BluetoothAdapter::~BluetoothAdapter()
649 // unset platform callback
650 bt_adapter_unset_state_changed_cb();
651 bt_adapter_unset_name_changed_cb();
652 bt_adapter_unset_visibility_mode_changed_cb();
653 bt_adapter_unset_device_discovery_state_changed_cb();
654 bt_device_unset_bond_created_cb();
655 bt_device_unset_bond_destroyed_cb();
656 bt_socket_unset_connection_state_changed_cb();
657 bt_socket_unset_data_received_cb();
660 for(int i = 0; i <= DESTROY_BONDING; i++) {
661 mUserDataList[i].reset();
663 mRegisteredUUID.clear();
665 mFoundDevices.clear();
666 mConnectedSocket.clear();
669 void BluetoothAdapter::unloadFrame(JSContextRef context)
673 LoggerD("Clean mUserDataList");
674 for(int i = 0; i <= DESTROY_BONDING; i++) {
675 if(mUserDataList[i]) {
676 MultiCallbackUserDataPtr callback = mUserDataList[i];
677 if(!GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) {
678 LoggerD("reset an userData");
679 mUserDataList[i].reset();
684 LoggerD("Clean mConnReqMap");
685 for(ConnReqMultiMapT::iterator iter = mConnReqMap.begin(); iter != mConnReqMap.end(); ) {
686 ConnReqMultiMapT::iterator temp = iter++;
687 MultiCallbackUserDataPtr callback = temp->second->mUserData;
688 if(!callback && !GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) {
689 LoggerD("erase a connectionRequest");
690 mConnReqMap.erase(temp);
695 void BluetoothAdapter::unregisterUUID(std::string &uuid)
699 mRegisteredUUID.erase(mRegisteredUUID.find(uuid));
700 if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
701 LoggerD("mRegisteredUUID.size()=%d, mConnReqMap.size()=%d, mConnectedSocket.size()=%d",
702 mRegisteredUUID.size(), mConnReqMap.size(), mConnectedSocket.size());
703 bt_socket_unset_connection_state_changed_cb();
707 bool BluetoothAdapter::closeConnectedSocket(int socket)
711 if(mEnabled == true) {
712 ConnectedSocketMapT::iterator iter = mConnectedSocket.find(socket);
713 if(iter == mConnectedSocket.end()) {
714 LoggerW("Already disconnected");
718 mConnectedSocket.erase(iter);
719 if(mConnectedSocket.size() == 0) {
720 bt_socket_unset_data_received_cb();
723 if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
724 LoggerD("mRegisteredUUID.size()=%d, mConnReqMap.size()=%d, mConnectedSocket.size()=%d",
725 mRegisteredUUID.size(), mConnReqMap.size(), mConnectedSocket.size());
726 bt_socket_unset_connection_state_changed_cb();
732 LoggerE("Bluetooth is not powered");
737 void BluetoothAdapter::removeConnReq(std::string &remoteAddress)
741 mConnReqMap.erase(remoteAddress);
743 if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) {
744 LoggerD("mRegisteredUUID.size()=%d, mConnReqMap.size()=%d, mConnectedSocket.size()=%d",
745 mRegisteredUUID.size(), mConnReqMap.size(), mConnectedSocket.size());
746 if(bt_socket_unset_connection_state_changed_cb() != BT_ERROR_NONE) {
747 LoggerW("Unsetting connection event callback failed");
752 BluetoothAdapter* BluetoothAdapter::getInstance()
756 static BluetoothAdapter instance;
760 bool BluetoothAdapter::isBluetoothSupported()
762 bool isSupported = false;
764 if(system_info_get_value_bool(SYSTEM_INFO_KEY_BLUETOOTH_SUPPORTED, &isSupported) != SYSTEM_INFO_ERROR_NONE) {
765 LoggerE("Can't know whether Bluetooth is supported or not");
771 bool BluetoothAdapter::isValidAddress(std::string &address)
775 pcrecpp::RE re("(([0-9a-zA-Z]+):)+([0-9a-zA-Z]+)");
776 std::string compareAddress = "00:12:47:08:9A:A6";
778 if (!re.FullMatch(address)) {
779 LoggerE("Invalid address");
783 if (address.size() != compareAddress.size())
785 LoggerE("Invalid size");
792 bool BluetoothAdapter::isValidUUID(std::string &uuid)
794 pcrecpp::RE re("(([0-9a-zA-Z]+)-)+([0-9a-zA-Z]+)");
795 std::string compareUUID = "00001101-0000-1000-8000-00805F9B34FB";
797 if (!re.FullMatch(uuid))
799 LoggerE("Invalid UUID");
803 if (uuid.size() != compareUUID.size())
805 LoggerE("Invalid size");
812 std::string BluetoothAdapter::getName() const
817 std::string str = "";
819 if(bt_adapter_get_name(&name) == BT_ERROR_NONE) {
824 LoggerD("name" << str);
828 LoggerE("bt_adapter_get_name() failed");
834 void BluetoothAdapter::setName(std::string &name, MultiCallbackUserDataPtr userData)
838 if(mEnabled == true) {
839 std::string adapterName = getName();
840 if(adapterName == name) { // in case of same name
841 LoggerD("same name");
842 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
846 if(mUserDataList[SET_NAME] == NULL) {
847 bt_adapter_set_name_changed_cb(onNameChangedCB, this);
848 mUserDataList[SET_NAME] = userData;
850 LoggerE("Already requested");
851 UnknownException *error = new UnknownException("Already requested");
852 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
856 int ret = bt_adapter_set_name(name.c_str());
861 LoggerD("bt_adapter_set_name() succeeded");
862 mRequestedName = name;
865 case BT_ERROR_INVALID_PARAMETER:
867 LoggerE("Invalid value");
868 InvalidValuesException *error = new InvalidValuesException("Invalid value");
869 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
874 LoggerE("Invalid value");
875 UnknownException *error = new UnknownException("Unknown exception");
876 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
880 bt_adapter_unset_name_changed_cb();
881 mUserDataList[SET_NAME].reset();
882 } else { // Not enabled
883 LoggerE("Bluetooth device is turned off");
884 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
885 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
889 std::string BluetoothAdapter::getAddress() const
893 char* address = NULL;
894 std::string str = "";
896 if (bt_adapter_get_address(&address) == BT_ERROR_NONE) {
897 if (address != NULL) {
900 LoggerD("address: " << str);
903 LoggerW("address is NULL");
907 LoggerE("bt_adapter_get_address() failed");
913 bool BluetoothAdapter::getPowered() const
920 void BluetoothAdapter::setPowered(bool powered, MultiCallbackUserDataPtr userData)
924 if(powered == mEnabled) {
925 LoggerD("same state");
926 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
930 if(mUserDataList[SET_POWERED] == NULL) {
931 mUserDataList[SET_POWERED] = userData;
934 LoggerE("Already requested");
935 ServiceNotAvailableException *error = new ServiceNotAvailableException("Already requested");
936 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
940 mRequestedState = powered;
941 if(powered == true) {
942 int ret = bt_adapter_enable();
947 LoggerD("bt_adapter_enable() succeeded");
950 case BT_ERROR_ALREADY_DONE:
952 // call successCallback
953 LoggerD("BT_ERROR_ALREADY_DONE");
954 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
957 case BT_ERROR_NOW_IN_PROGRESS:
959 LoggerD("BT_ERROR_NOW_IN_PROGRESS");
960 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is busy");
961 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
966 LoggerD("Unknown error");
967 UnknownException *error = new UnknownException("Unknown error");
968 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
972 int ret = bt_adapter_disable();
977 LoggerD("bt_adapter_disable() succeeded");
980 case BT_ERROR_NOT_ENABLED:
982 // call successCallback
983 LoggerD("Already disabled");
984 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
987 case BT_ERROR_NOW_IN_PROGRESS:
989 LoggerD("BT_ERROR_NOW_IN_PROGRESS");
990 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is busy");
991 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
996 LoggerD("Unknown error");
997 UnknownException *error = new UnknownException("Unknown error");
998 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1003 mUserDataList[SET_POWERED].reset();
1006 bool BluetoothAdapter::getVisible() const
1010 bt_adapter_visibility_mode_e mode;
1012 if (bt_adapter_get_visibility(&mode, NULL) == BT_ERROR_NONE) {
1013 if (mode != BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
1021 void BluetoothAdapter::setVisible(bool visible, unsigned int timeout, MultiCallbackUserDataPtr userData)
1025 if(mEnabled == true) {
1026 bt_adapter_visibility_mode_e discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
1027 if(visible == true) {
1029 discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE;
1031 discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
1034 bt_adapter_visibility_mode_e current = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
1036 if(bt_adapter_get_visibility(¤t , &time) != BT_ERROR_NONE) {
1037 LoggerE("bt_adapter_get_visibility() failed");
1038 UnknownException *error = new UnknownException("Can't get current visibility");
1039 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1043 if(discoverable_mode == current) {
1044 if(discoverable_mode != BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE) {
1045 LoggerD("same visibility");
1046 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
1049 else if((unsigned int)time == timeout) {
1050 LoggerD("same visibility");
1051 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
1056 if(mUserDataList[SET_VISIBLE] == NULL) {
1057 bt_adapter_set_visibility_mode_changed_cb(onVisibilityChangedCB, this);
1058 mUserDataList[SET_VISIBLE] = userData;
1060 UnknownException *error = new UnknownException("Already requested");
1061 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1065 mRequestedVisibility = discoverable_mode;
1066 int ret = bt_adapter_set_visibility(discoverable_mode, timeout);
1070 LoggerD("bt_adapter_set_visibility() succeeded");
1073 case BT_ERROR_INVALID_PARAMETER:
1075 InvalidValuesException *error = new InvalidValuesException("Invalid value");
1076 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1081 UnknownException *error = new UnknownException("Unknown error");
1082 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1086 bt_adapter_unset_visibility_mode_changed_cb();
1087 mUserDataList[SET_VISIBLE].reset();
1088 } else { // Not enabled
1089 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1090 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1095 void BluetoothAdapter::discoverDevices(MultiCallbackUserDataPtr userData)
1099 if(mUserDataList[DISCOVER_DEVICES] == NULL) {
1100 mUserDataList[DISCOVER_DEVICES] = userData;
1103 if(mUserDataList[STOP_DISCOVERY] == NULL)
1104 bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this);
1107 LoggerE("Already requested");
1108 UnknownException *error = new UnknownException("Already requested");
1109 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1113 if(mEnabled == true) {
1114 int ret = bt_adapter_start_device_discovery();
1118 LoggerD("bt_adapter_start_device_discovery() succeeded");
1123 LoggerE("Unknown exception");
1124 UnknownException *error = new UnknownException("Unknown error");
1125 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1128 } else { // Not enabled
1129 LoggerE("Bluetooth device is turned off");
1130 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1131 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1134 mUserDataList[DISCOVER_DEVICES].reset();
1136 if(mUserDataList[STOP_DISCOVERY] == NULL) {
1137 bt_adapter_unset_device_discovery_state_changed_cb();
1142 void BluetoothAdapter::stopDiscovery(MultiCallbackUserDataPtr userData)
1146 if(mEnabled == true) {
1148 bool isDiscovering = false;
1149 bt_adapter_is_discovering(&isDiscovering);
1150 if(!isDiscovering) {
1151 BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData);
1155 if(mUserDataList[STOP_DISCOVERY] == NULL) {
1156 mUserDataList[STOP_DISCOVERY] = userData;
1159 if(mUserDataList[DISCOVER_DEVICES] == NULL)
1160 bt_adapter_set_device_discovery_state_changed_cb(onDiscoveryStateChangedCB, this);
1163 LoggerD("Already requested");
1164 UnknownException *error = new UnknownException("Already requested");
1165 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1169 int ret = bt_adapter_stop_device_discovery();
1173 LoggerD("bt_adapter_stop_device_discovery() succeeded");
1178 UnknownException *error = new UnknownException("Unknown error");
1179 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1183 mUserDataList[STOP_DISCOVERY].reset();
1185 if(mUserDataList[DISCOVER_DEVICES] == NULL) {
1186 bt_adapter_unset_device_discovery_state_changed_cb();
1189 } else { // Not enabled
1190 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1191 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1195 void BluetoothAdapter::getKnownDevices(MultiCallbackUserDataPtr userData)
1198 BluetoothCallbackUtil::syncToAsyncDeviceArrayCallback(userData);
1201 void BluetoothAdapter::getDevice(std::string &address, MultiCallbackUserDataPtr userData)
1204 BluetoothCallbackUtil::syncToAsyncDeviceCallback(userData, address);
1207 void BluetoothAdapter::createBonding(std::string &address, MultiCallbackUserDataPtr userData)
1211 if(!isValidAddress(address)) {
1212 LoggerE("Wrong address");
1213 NotFoundException *error = new NotFoundException("Wrong address");
1214 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1218 if(mUserDataList[CREATE_BONDING] == NULL) {
1219 bt_device_set_bond_created_cb(onBondCreatedCB, this);
1220 mCreateBondingAddress = address;
1221 mUserDataList[CREATE_BONDING] = userData;
1223 LoggerE("Already requested");
1224 UnknownException *error = new UnknownException("Already requested");
1225 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1229 if(mEnabled == true) {
1230 int ret = bt_device_create_bond(address.c_str());
1235 LoggerD("bt_device_create_bond() succeeded");
1238 case BT_ERROR_INVALID_PARAMETER:
1240 LoggerE("Not found");
1241 NotFoundException *error = new NotFoundException("Not found");
1242 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1247 LoggerE("Unknown exception");
1248 UnknownException *error = new UnknownException("Unknown error");
1249 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1252 } else { // Not enabled
1253 LoggerE("Bluetooth device is turned off");
1254 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1255 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1258 bt_device_unset_bond_created_cb();
1259 mCreateBondingAddress.clear();
1260 mUserDataList[CREATE_BONDING].reset();
1263 void BluetoothAdapter::destroyBonding(std::string &address, MultiCallbackUserDataPtr userData)
1267 if(!isValidAddress(address)) {
1268 LoggerE("Wrong address");
1269 NotFoundException *error = new NotFoundException("Wrong address");
1270 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1274 if(mUserDataList[DESTROY_BONDING] == NULL) {
1275 bt_device_set_bond_destroyed_cb(onBondDestroyedCB, this);
1276 mDestroyBondingAddress = address;
1277 mUserDataList[DESTROY_BONDING] = userData;
1279 LoggerD("Already requested");
1280 UnknownException *error = new UnknownException("Already requested");
1281 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1285 if(mEnabled == true) {
1286 bt_device_info_s *deviceInfo = NULL;
1287 if(bt_adapter_get_bonded_device_info(address.c_str(), &deviceInfo) != BT_ERROR_NONE || deviceInfo == NULL) {
1288 LoggerD("There is no bonding");
1289 NotFoundException *error = new NotFoundException("Not found");
1290 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1293 bt_adapter_free_device_info(deviceInfo);
1294 int ret = bt_device_destroy_bond(address.c_str());
1299 LoggerD("bt_device_destroy_bond() succeeded");
1302 case BT_ERROR_INVALID_PARAMETER:
1304 NotFoundException *error = new NotFoundException("Not found");
1305 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1310 UnknownException *error = new UnknownException("Unknown error");
1311 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1315 } else { // Not enabled
1316 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1317 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1320 bt_device_unset_bond_destroyed_cb();
1321 mDestroyBondingAddress.clear();
1322 mUserDataList[DESTROY_BONDING].reset();
1325 void BluetoothAdapter::registerRFCOMMServiceByUUID(std::string &uuid, std::string &name, MultiCallbackUserDataPtr userData)
1328 BluetoothCallbackUtil::syncToAsyncServiceCallback(userData, uuid, name);
1331 void BluetoothAdapter::connectToServiceByUUID(std::string &remoteAddress, std::string &uuid, Common::MultiCallbackUserDataPtr userData)
1335 if(!isValidUUID(uuid)) {
1336 LoggerE("Wrong UUID");
1337 InvalidValuesException *error = new InvalidValuesException("Wrong UUID");
1338 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1343 if(mEnabled == true) {
1344 int ret = bt_socket_connect_rfcomm(remoteAddress.c_str(), uuid.c_str());
1349 LoggerD("bt_socket_connect_rfcomm() succeeded");
1350 bt_socket_set_connection_state_changed_cb(onSocketConnected, this);
1352 BluetoothConnReqPtr connReq = new BluetoothConnReq(uuid, userData);
1353 mConnReqMap.insert(std::pair<std::string, BluetoothConnReqPtr>(remoteAddress, connReq));
1356 case BT_ERROR_INVALID_PARAMETER:
1357 case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
1359 InvalidValuesException *error = new InvalidValuesException("Invalid value");
1360 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1365 UnknownException *error = new UnknownException("Unknown error");
1366 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1369 } else { // Not enabled
1370 ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off");
1371 BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error);
1375 void BluetoothAdapter::returnKnownDevices(Common::MultiCallbackUserDataPtr userData)
1379 if(mEnabled == true) {
1380 knownDevices = mFoundDevices;
1381 if(bt_adapter_foreach_bonded_device(foreachBondedDevicesCB, this) == BT_ERROR_NONE) {
1382 if(knownDevices.size() > 0) { // There are found devices
1383 LoggerD("There are found devices");
1384 int num = knownDevices.size();
1385 JSObjectRef devices[num];
1386 for(int i = 0; i < num; i++) {
1387 JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(userData->getContext(), knownDevices[i]);
1388 devices[i] = deviceObj;
1391 LoggerD("invoke successCallback");
1392 userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), num, devices, NULL));
1394 else { // There is no found device
1395 LoggerD("There is no found device");
1396 userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), 0, NULL, NULL) );
1400 LoggerE("Unknown exception");
1401 userData->invokeCallback(
1403 JSWebAPIError::makeJSWebAPIError(userData->getContext(), UnknownException("Unknown exception"))
1406 } else { // Not enabled
1407 LoggerE("Bluetooth device is turned off");
1408 userData->invokeCallback(
1410 JSWebAPIError::makeJSWebAPIError(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1415 void BluetoothAdapter::returnDevice(std::string &address, Common::MultiCallbackUserDataPtr userData)
1419 if(!isValidAddress(address)) {
1420 LoggerE("Wrong address");
1421 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), NotFoundException("Wrong address")));
1425 if(mEnabled == true) {
1426 bt_device_info_s *deviceInfo = NULL;
1427 if(bt_adapter_get_bonded_device_info(address.c_str(), &deviceInfo) == BT_ERROR_NONE &&
1428 deviceInfo != NULL) {
1429 BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo));
1430 bt_adapter_free_device_info(deviceInfo);
1432 LoggerD("invoke successCallback");
1433 userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), device));
1437 std::vector<BluetoothDeviceSharedPtr>::iterator iter;
1438 for(iter = mFoundDevices.begin(); iter != mFoundDevices.end(); ++iter) {
1439 BluetoothDeviceSharedPtr foundDevice = *iter;
1440 if(!strcmp(foundDevice->getAddress().c_str(), address.c_str())) {
1441 LoggerD("Found in mFoundDevices");
1442 userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), foundDevice));
1447 if(iter == mFoundDevices.end()) {
1448 LoggerE("Can't find this device");
1450 userData->invokeCallback(
1452 JSWebAPIError::makeJSWebAPIError(userData->getContext(), NotFoundException("There is no device with the given address"))
1456 } else { // Not enabled
1457 LoggerE("Bluetooth device is turned off");
1458 userData->invokeCallback(
1460 JSWebAPIError::makeJSWebAPIError(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))
1465 void BluetoothAdapter::returnRegisteredService(std::string &uuid, std::string &name, Common::MultiCallbackUserDataPtr userData)
1469 if(!isValidUUID(uuid)) {
1470 LoggerE("Wrong UUID");
1471 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), InvalidValuesException("Wrong UUID")));
1475 if(mEnabled == true) {
1478 if(bt_adapter_is_service_used(uuid.c_str(), &isRegistered) == BT_ERROR_NONE && isRegistered == true) {
1479 LoggerD("Already registered");
1480 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), InvalidValuesException("Already registered")));
1485 int ret = bt_socket_create_rfcomm(uuid.c_str(), &socket);
1490 LoggerD("bt_socket_create_rfcomm() succeeded");
1491 int ret = bt_socket_listen_and_accept_rfcomm(socket, 0);
1495 LoggerD("bt_socket_listen() succeeded");
1496 bt_socket_set_connection_state_changed_cb(onSocketConnected, this);
1498 BluetoothServiceHandlerPtr serviceHandler = new BluetoothServiceHandler(uuid, name, socket);
1499 mRegisteredUUID.insert(std::pair<std::string, BluetoothServiceHandlerPtr>(uuid, serviceHandler));
1501 JSObjectRef serviceObj = JSBluetoothServiceHandler::createJSObject(userData->getContext(), serviceHandler);
1502 userData->invokeCallback("success", serviceObj);
1505 case BT_ERROR_INVALID_PARAMETER:
1507 LoggerD("Invalid value");
1508 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), InvalidValuesException("Invalid value")));
1513 LoggerD("Unknown exception");
1514 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), UnknownException("Unknown exception")));
1520 case BT_ERROR_INVALID_PARAMETER:
1522 LoggerD("Invalid value");
1523 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), InvalidValuesException("Invalid value")));
1528 LoggerD("Unknown exception");
1529 userData->invokeCallback("error", JSWebAPIError::makeJSWebAPIError(userData->getContext(), UnknownException("Unknown exception")));
1532 } else { // Not enabled
1533 LoggerE("Bluetooth device is turned off");
1534 userData->invokeCallback(
1536 JSWebAPIError::makeJSWebAPIError(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off"))