From: brianjjones Date: Thu, 27 Mar 2014 18:29:29 +0000 (-0700) Subject: Updated this component to use Bluez 5 API calls. This fixes TIVI-2936 X-Git-Tag: accepted/tizen/ivi/20140327.195149^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2ec87e44aea04e3d5d9ab92a0bdba60159106cba;p=profile%2Fivi%2Fwrt-plugins-ivi-bt.git Updated this component to use Bluez 5 API calls. This fixes TIVI-2936 Change-Id: Ic4d742717a122d9f570d8b7f2b18b3d588262bf2 --- diff --git a/packaging/wrt-plugins-tizen-bt.changes b/packaging/wrt-plugins-tizen-bt.changes index 56db9d4..6f5d700 100644 --- a/packaging/wrt-plugins-tizen-bt.changes +++ b/packaging/wrt-plugins-tizen-bt.changes @@ -1,3 +1,7 @@ +* Thu Mar 27 2014 brianjjones submit/tizen/20140321.171938@a09aa36 +- Updated this component to use Bluez 5 API calls. This fixes TIVI-2936 +- Initial commit for Bluetooth plugin for HTML5 UI + * Fri Mar 07 2014 brianjjones cd7fd57 - Initial commit for Bluetooth plugin for HTML5 UI diff --git a/src/BluetoothAdapter.cpp b/src/BluetoothAdapter.cpp index e1a4e8e..72c4e45 100644 --- a/src/BluetoothAdapter.cpp +++ b/src/BluetoothAdapter.cpp @@ -34,51 +34,14 @@ #define BLUEZ_PREFIX "org.bluez" #define BLUEZ_SERVICE BLUEZ_PREFIX -#define BLUEZ_MANAGER_IFACE BLUEZ_PREFIX ".Manager" -#define BLUEZ_ADAPTER_IFACE BLUEZ_PREFIX ".Adapter" -#define BLUEZ_DEVICE_IFACE BLUEZ_PREFIX ".Device" -#define BLUEZ_AGENT_IFACE BLUEZ_PREFIX ".Agent" +#define BLUEZ_ADAPTER_IFACE BLUEZ_PREFIX ".Adapter1" +#define BLUEZ_DEVICE_IFACE BLUEZ_PREFIX ".Device1" +#define BLUEZ_AGENT_IFACE BLUEZ_PREFIX ".Agent1" +#define BLUEZ_OBJECT_IFACE "org.freedesktop.DBus.ObjectManager" #define AGENT_PATH "/org/bluez/agent_pairing" #define AGENT_CAPABILITIES "KeyboardDisplay" -#define AGENT_INTERFACE_XML \ - "" \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - "" - #define PINCODE "123456" #define PASSKEY 123456 @@ -90,2144 +53,2525 @@ using namespace DeviceAPI::Common; -namespace DeviceAPI { -namespace Bluetooth { +namespace DeviceAPI +{ +namespace Bluetooth +{ -bool BluetoothAdapter::foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData) +bool BluetoothAdapter::foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData, char *devicePath) { - BluetoothAdapterPtr adapter = static_cast(userData); - if(!adapter) { - LoggerW("userData is NULL"); - return true; - } - - if(deviceInfo == NULL) { - LoggerW("deviceInfo is NULL"); - return true; - } - - std::vector::iterator iter; - for(iter = adapter->knownDevices.begin(); iter != adapter->knownDevices.end(); ++iter) { - BluetoothDeviceSharedPtr foundDevice = *iter; - - if(!strcmp(foundDevice->getAddress().c_str(), deviceInfo->remote_address)) { - foundDevice->updateInfo(deviceInfo); - break; - } - } - - if(iter == adapter->knownDevices.end()) { - BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo)); - adapter->knownDevices.push_back(device); - } - - return true; + BluetoothAdapterPtr adapter = static_cast(userData); + if(!adapter) + { + LoggerW("userData is NULL"); + return true; + } + + if(deviceInfo == NULL) + { + LoggerW("deviceInfo is NULL"); + return true; + } + + std::vector::iterator iter; + for(iter = adapter->knownDevices.begin(); iter != adapter->knownDevices.end(); ++iter) + { + BluetoothDeviceSharedPtr foundDevice = *iter; + + if(!strcmp(foundDevice->getAddress().c_str(), deviceInfo->remote_address)) + { + foundDevice->updateInfo(deviceInfo); + break; + } + } + + if(iter == adapter->knownDevices.end()) + { + BluetoothDeviceSharedPtr device(new BluetoothDevice(deviceInfo, devicePath)); + adapter->knownDevices.push_back(device); + } + + return true; } void BluetoothAdapter::onSocketConnected(int result, bt_socket_connection_state_e state, bt_socket_connection_s *connection, void *userData) { - BluetoothAdapterPtr object = static_cast(userData); - if(!object) { - LoggerW("userData is NULL"); - return; - } - - if(!connection) { - LoggerW("connection is NULL"); - return; - } - - if(connection->local_role == BT_SOCKET_SERVER) { - RegisteredUUIDMapT::iterator iter = object->mRegisteredUUID.find(connection->service_uuid); - if(iter == object->mRegisteredUUID.end()) { - LoggerW("Connection state is changed unexpectedly"); - return; - } - - if(state == BT_SOCKET_CONNECTED) { // connected when Server - if(result == BT_ERROR_NONE) { - // Update BluetoothServiceHandler - BluetoothServiceHandlerPtr service = iter->second; - service->setConnectionState(true); - - // Call BluetoothServiceHandler.onconnect - BluetoothSocketPtr socket = new BluetoothSocket(connection); - MultiCallbackUserDataPtr callback = service->getOnConnect(); - JSContextRef context = callback->getContext(); - JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket); - if(callback) - callback->invokeCallback("onconnect", socketObj); - - // Update mConnectedSocket - object->mConnectedSocket.insert(std::pair(connection->socket_fd, socket)); - bt_socket_set_data_received_cb(onSocketReceivedCB, userData); - } - else { - LoggerW("Establishing a connection failed"); - } - return; - } - else { // disconnected when Server - if(result == BT_ERROR_NONE) { - // Update BluetoothServiceHandler - BluetoothServiceHandlerPtr service = iter->second; - service->setConnectionState(false); - - // call BluetoothSocket.onclose; - ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd); - if(i == object->mConnectedSocket.end()) { - LoggerW("Unknown connected socket"); - return; - } - //BluetoothSocketSharedPtr socket = i->second; - BluetoothSocketPtr socket = i->second; - socket->setConnectionState(false); - MultiCallbackUserDataPtr callback = socket->getOnClose(); - if(callback) - callback->invokeCallback("onclose"); - - // Update mConnectedSocket - object->mConnectedSocket.erase(i); - } - else { - LoggerW("Disconnecting a connection failed"); - } - } - } - else if(connection->local_role == BT_SOCKET_CLIENT) { - - if(state == BT_SOCKET_CONNECTED) { // connected when Client - std::string remoteAddress(connection->remote_address); - ConnReqMultiMapT::iterator iter; - do { - iter = object->mConnReqMap.find(remoteAddress); - if(iter != object->mConnReqMap.end() && !strcmp(iter->second->mUUID.c_str(), connection->service_uuid)) { - break; - } - } while(iter != object->mConnReqMap.end()); - - if(iter == object->mConnReqMap.end()) { - LoggerW("Connection state is changed unexpectedly"); - return; - } - - MultiCallbackUserDataPtr callback = static_cast(iter->second->mUserData); - - if(result == BT_ERROR_NONE) { - // Update mConnectedSocket - BluetoothSocketPtr socket = new BluetoothSocket(connection); - object->mConnectedSocket.insert(std::pair(connection->socket_fd, socket)); - bt_socket_set_data_received_cb(onSocketReceivedCB, userData); - - // Call successcallback of connectToServiceByUUID - JSContextRef context = callback->getContext(); - JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket); - if(callback) - callback->invokeCallback("success", socketObj); - - // Update mConnReqMap - object->mConnReqMap.erase(iter); - } - else { - // Call errorcallback of connectToServiceByUUID - JSContextRef context = callback->getContext(); - NotFoundException error("Not found"); - if(callback) - callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); - - // Update mConnReqMap - object->mConnReqMap.erase(iter); - } - return; - } - else { // disconnected when Client - if(result == BT_ERROR_NONE) { - // call BluetoothSocket.onclose; - ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd); - if(i == object->mConnectedSocket.end()) { - LoggerW("Unknown connected socket"); - return; - } - - BluetoothSocketPtr socket = i->second; - socket->setConnectionState(false); - MultiCallbackUserDataPtr callback = socket->getOnClose(); - if(callback) - callback->invokeCallback("onclose"); - - // Update mConnectedSocket - object->mConnectedSocket.erase(i); - } - else { - LoggerW("Disconnecting a connection failed"); - } - } - } - else { - LoggerW("Unknown role"); - return; - } - - if(object->mConnectedSocket.size() == 0) { - bt_socket_unset_data_received_cb(); - } - - if(object->mRegisteredUUID.size() == 0 && object->mConnReqMap.size() == 0 && object->mConnectedSocket.size() == 0) { - bt_socket_unset_connection_state_changed_cb(); - } + BluetoothAdapterPtr object = static_cast(userData); + if(!object) + { + LoggerW("userData is NULL"); + return; + } + + if(!connection) + { + LoggerW("connection is NULL"); + return; + } + + if(connection->local_role == BT_SOCKET_SERVER) + { + RegisteredUUIDMapT::iterator iter = object->mRegisteredUUID.find(connection->service_uuid); + + if(iter == object->mRegisteredUUID.end()) + { + LoggerW("Connection state is changed unexpectedly"); + return; + } + + if(state == BT_SOCKET_CONNECTED) // connected when Server + { + if(result == BT_ERROR_NONE) + { + // Update BluetoothServiceHandler + BluetoothServiceHandlerPtr service = iter->second; + service->setConnectionState(true); + + // Call BluetoothServiceHandler.onconnect + BluetoothSocketPtr socket = new BluetoothSocket(connection); + MultiCallbackUserDataPtr callback = service->getOnConnect(); + JSContextRef context = callback->getContext(); + JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket); + if(callback) + callback->invokeCallback("onconnect", socketObj); + + // Update mConnectedSocket + object->mConnectedSocket.insert(std::pair(connection->socket_fd, socket)); + bt_socket_set_data_received_cb(onSocketReceivedCB, userData); + } + else + { + LoggerW("Establishing a connection failed"); + } + return; + } + else // disconnected when Server + { + if(result == BT_ERROR_NONE) + { + // Update BluetoothServiceHandler + BluetoothServiceHandlerPtr service = iter->second; + service->setConnectionState(false); + + // call BluetoothSocket.onclose; + ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd); + if(i == object->mConnectedSocket.end()) + { + LoggerW("Unknown connected socket"); + return; + } + //BluetoothSocketSharedPtr socket = i->second; + BluetoothSocketPtr socket = i->second; + socket->setConnectionState(false); + MultiCallbackUserDataPtr callback = socket->getOnClose(); + if(callback) + callback->invokeCallback("onclose"); + + // Update mConnectedSocket + object->mConnectedSocket.erase(i); + } + else + { + LoggerW("Disconnecting a connection failed"); + } + } + } + else if(connection->local_role == BT_SOCKET_CLIENT) + { + + if(state == BT_SOCKET_CONNECTED) // connected when Client + { + std::string remoteAddress(connection->remote_address); + ConnReqMultiMapT::iterator iter; + do + { + iter = object->mConnReqMap.find(remoteAddress); + if(iter != object->mConnReqMap.end() && !strcmp(iter->second->mUUID.c_str(), connection->service_uuid)) + { + break; + } + } + while(iter != object->mConnReqMap.end()); + + if(iter == object->mConnReqMap.end()) + { + LoggerW("Connection state is changed unexpectedly"); + return; + } + + MultiCallbackUserDataPtr callback = static_cast(iter->second->mUserData); + + if(result == BT_ERROR_NONE) + { + // Update mConnectedSocket + BluetoothSocketPtr socket = new BluetoothSocket(connection); + object->mConnectedSocket.insert(std::pair(connection->socket_fd, socket)); + bt_socket_set_data_received_cb(onSocketReceivedCB, userData); + + // Call successcallback of connectToServiceByUUID + JSContextRef context = callback->getContext(); + JSObjectRef socketObj = JSBluetoothSocket::createJSObject(context, socket); + if(callback) + callback->invokeCallback("success", socketObj); + + // Update mConnReqMap + object->mConnReqMap.erase(iter); + } + else + { + // Call errorcallback of connectToServiceByUUID + JSContextRef context = callback->getContext(); + NotFoundException error("Not found"); + if(callback) + callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); + + // Update mConnReqMap + object->mConnReqMap.erase(iter); + } + return; + } + else // disconnected when Client + { + if(result == BT_ERROR_NONE) + { + // call BluetoothSocket.onclose; + ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(connection->socket_fd); + if(i == object->mConnectedSocket.end()) + { + LoggerW("Unknown connected socket"); + return; + } + + BluetoothSocketPtr socket = i->second; + socket->setConnectionState(false); + MultiCallbackUserDataPtr callback = socket->getOnClose(); + if(callback) + callback->invokeCallback("onclose"); + + // Update mConnectedSocket + object->mConnectedSocket.erase(i); + } + else + { + LoggerW("Disconnecting a connection failed"); + } + } + } + else + { + LoggerW("Unknown role"); + return; + } + + if(object->mConnectedSocket.size() == 0) + { + bt_socket_unset_data_received_cb(); + } + + if(object->mRegisteredUUID.size() == 0 && object->mConnReqMap.size() == 0 && object->mConnectedSocket.size() == 0) + { + bt_socket_unset_connection_state_changed_cb(); + } } void BluetoothAdapter::onSocketReceivedCB(bt_socket_received_data_s *data, void *userData) { - BluetoothAdapterPtr object = static_cast(userData); - if(!object) { - LoggerW("userData is NULL"); - return; - } - - if(!data) { - LoggerW("data is NULL"); - return; - } - - ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(data->socket_fd); - if(i == object->mConnectedSocket.end()) { - LoggerW("Unknown connected socket"); - return; - } - - // Store received data - BluetoothSocketPtr socket = i->second; - socket->storeRecivedData(data->data, static_cast(data->data_size)); - - // Call BluetoothSocket.onmessage - MultiCallbackUserDataPtr callback = socket->getOnMessage(); - if(callback) - callback->invokeCallback("onmessage"); + BluetoothAdapterPtr object = static_cast(userData); + + if(!object) + { + LoggerW("userData is NULL"); + return; + } + + if(!data) + { + LoggerW("data is NULL"); + return; + } + + ConnectedSocketMapT::iterator i = object->mConnectedSocket.find(data->socket_fd); + if(i == object->mConnectedSocket.end()) + { + LoggerW("Unknown connected socket"); + return; + } + + // Store received data + BluetoothSocketPtr socket = i->second; + socket->storeRecivedData(data->data, static_cast(data->data_size)); + + // Call BluetoothSocket.onmessage + MultiCallbackUserDataPtr callback = socket->getOnMessage(); + if(callback) + callback->invokeCallback("onmessage"); } BluetoothAdapter::BluetoothAdapter(): - mAdapterPath(NULL), - mAgentRegistrationId(-1), - mAgentIntrospectionData(NULL), - mBluetoothTechnology(NULL), - mEnabled(false) + mAdapterPath(NULL), + mAgentRegistrationId(-1), + mAgentIntrospectionData(NULL), + mBluetoothTechnology(NULL), + mEnabled(false) { - - mBluetoothTechnology = getBluetoothTechnology(); - if(!mBluetoothTechnology) { - LoggerE("Failed to get BT technology"); - } - - mAdapterPath = getDefaultAdapter(); - if(!mAdapterPath) { - LoggerE("Unable to get default adapter"); - } - Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_MANAGER_IFACE, - "/", "AdapterAdded", BluetoothAdapter::handleSignal, - this); - Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_MANAGER_IFACE, - "/", "AdapterRemoved", BluetoothAdapter::handleSignal, - this); - memset(&mAgentIfaceVTable, 0, sizeof(mAgentIfaceVTable)); - - if(isAdapterPowered()) { - //LoggerD("Adapter is powered"); - mEnabled = true; - } - //else { - // LoggerD("Adapter is not powered"); - //} - - if(mAdapterPath) { - Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_ADAPTER_IFACE, - mAdapterPath, "PropertyChanged", BluetoothAdapter::handleSignal, - this); - } + mBluetoothTechnology = getBluetoothTechnology(); + if(!mBluetoothTechnology) + { + LoggerE("Failed to get BT technology"); + } + + mAdapterPath = getDefaultAdapter(); + if(!mAdapterPath) + { + LoggerE("Unable to get default adapter"); + } + + + Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, "org.freedesktop.DBus.ObjectManager", + "/", "InterfacesAdded", BluetoothAdapter::handleSignal, + this); + Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, "org.freedesktop.DBus.ObjectManager", + "/", "InterfacesRemoved", BluetoothAdapter::handleSignal, + this); + memset(&mAgentIfaceVTable, 0, sizeof(mAgentIfaceVTable)); + + if(isAdapterPowered()) + { + LoggerD("Adapter is powered"); + mEnabled = true; + } + else + { + LoggerD("Adapter is not powered"); + } + + if(mAdapterPath) + { + Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, "org.freedesktop.DBus.ObjectManager", + mAdapterPath, "InterfacesAdded", BluetoothAdapter::handleSignal, + this); + } } BluetoothAdapter::~BluetoothAdapter() { - // unset platform callback - bt_socket_unset_connection_state_changed_cb(); - bt_socket_unset_data_received_cb(); - - for(int i = 0; i <= DESTROY_BONDING; i++) { - mUserDataList[i].reset(); - } - mRegisteredUUID.clear(); - mConnReqMap.clear(); - mFoundDevices.clear(); - mConnectedSocket.clear(); + // unset platform callback + bt_socket_unset_connection_state_changed_cb(); + bt_socket_unset_data_received_cb(); + + for(int i = 0; i <= DESTROY_BONDING; i++) + { + mUserDataList[i].reset(); + } + mRegisteredUUID.clear(); + mConnReqMap.clear(); + mFoundDevices.clear(); + mConnectedSocket.clear(); } void BluetoothAdapter::unloadFrame(JSContextRef context) { - LoggerD("Clean mUserDataList"); - for(int i = 0; i <= DESTROY_BONDING; i++) { - if(mUserDataList[i]) { - MultiCallbackUserDataPtr callback = mUserDataList[i]; - if(!GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) { - mUserDataList[i].reset(); - } - } - } - - LoggerD("Clean mConnReqMap"); - for(ConnReqMultiMapT::iterator iter = mConnReqMap.begin(); iter != mConnReqMap.end(); ) { - ConnReqMultiMapT::iterator temp = iter++; - MultiCallbackUserDataPtr callback = temp->second->mUserData; - if(!callback && !GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) { - mConnReqMap.erase(temp); - } - } + LoggerD("Clean mUserDataList"); + for(int i = 0; i <= DESTROY_BONDING; i++) + { + if(mUserDataList[i]) + { + MultiCallbackUserDataPtr callback = mUserDataList[i]; + if(!GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) + { + mUserDataList[i].reset(); + } + } + } + + LoggerD("Clean mConnReqMap"); + for(ConnReqMultiMapT::iterator iter = mConnReqMap.begin(); iter != mConnReqMap.end(); ) + { + ConnReqMultiMapT::iterator temp = iter++; + MultiCallbackUserDataPtr callback = temp->second->mUserData; + if(!callback && !GlobalContextManager::getInstance()->isAliveGlobalContext(callback->getContext())) + { + mConnReqMap.erase(temp); + } + } } void BluetoothAdapter::unregisterUUID(std::string &uuid) { - mRegisteredUUID.erase(mRegisteredUUID.find(uuid)); - if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) { - bt_socket_unset_connection_state_changed_cb(); - } + mRegisteredUUID.erase(mRegisteredUUID.find(uuid)); + if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) + { + bt_socket_unset_connection_state_changed_cb(); + } } bool BluetoothAdapter::closeConnectedSocket(int socket) { - if(mEnabled == true) { - ConnectedSocketMapT::iterator iter = mConnectedSocket.find(socket); - if(iter == mConnectedSocket.end()) { - LoggerW("Already disconnected"); - return true; - } - - mConnectedSocket.erase(iter); - if(mConnectedSocket.size() == 0) { - bt_socket_unset_data_received_cb(); - } - - if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) { - bt_socket_unset_connection_state_changed_cb(); - } - - return true; - } - else { - LoggerE("Bluetooth is not powered"); - return false; - } + if(mEnabled == true) + { + ConnectedSocketMapT::iterator iter = mConnectedSocket.find(socket); + if(iter == mConnectedSocket.end()) + { + LoggerW("Already disconnected"); + return true; + } + + mConnectedSocket.erase(iter); + if(mConnectedSocket.size() == 0) + { + bt_socket_unset_data_received_cb(); + } + + if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) + { + bt_socket_unset_connection_state_changed_cb(); + } + + return true; + } + else + { + LoggerE("Bluetooth is not powered"); + return false; + } } void BluetoothAdapter::removeConnReq(std::string &remoteAddress) { - mConnReqMap.erase(remoteAddress); - - if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) { - if(bt_socket_unset_connection_state_changed_cb() != BT_ERROR_NONE) { - LoggerW("Unsetting connection event callback failed"); - } - } + mConnReqMap.erase(remoteAddress); + + if(mRegisteredUUID.size() == 0 && mConnReqMap.size() == 0 && mConnectedSocket.size() == 0) + { + if(bt_socket_unset_connection_state_changed_cb() != BT_ERROR_NONE) + { + LoggerW("Unsetting connection event callback failed"); + } + } } BluetoothAdapter* BluetoothAdapter::getInstance() { - static BluetoothAdapter instance; - return &instance; + static BluetoothAdapter instance; + return &instance; } bool BluetoothAdapter::isBluetoothSupported() { - bool isSupported = false; + bool isSupported = true; -/* if(system_info_get_value_bool(SYSTEM_INFO_KEY_BLUETOOTH_SUPPORTED, &isSupported) != SYSTEM_INFO_ERROR_NONE) { - LoggerE("Can't know whether Bluetooth is supported or not"); - } -*/ - return isSupported; + /* if(system_info_get_value_bool(SYSTEM_INFO_KEY_BLUETOOTH_SUPPORTED, &isSupported) != SYSTEM_INFO_ERROR_NONE) { + LoggerE("Can't know whether Bluetooth is supported or not"); + } + */ + return isSupported; } bool BluetoothAdapter::isValidAddress(std::string &address) { - pcrecpp::RE re("(([0-9a-zA-Z]+):)+([0-9a-zA-Z]+)"); - std::string compareAddress = "00:12:47:08:9A:A6"; - - if (!re.FullMatch(address)) { - LoggerE("Invalid address"); - return false; - } - - if (address.size() != compareAddress.size()) - { - LoggerE("Invalid size"); - return false; - } - - return true; + pcrecpp::RE re("(([0-9a-zA-Z]+):)+([0-9a-zA-Z]+)"); + std::string compareAddress = "00:12:47:08:9A:A6"; + + if (!re.FullMatch(address)) + { + LoggerE("Invalid address"); + return false; + } + + if (address.size() != compareAddress.size()) + { + LoggerE("Invalid size"); + return false; + } + + return true; } bool BluetoothAdapter::isValidUUID(std::string &uuid) { - pcrecpp::RE re("(([0-9a-zA-Z]+)-)+([0-9a-zA-Z]+)"); - std::string compareUUID = "00001101-0000-1000-8000-00805F9B34FB"; - - if (!re.FullMatch(uuid)) - { - LoggerE("Invalid UUID"); - return false; - } - - if (uuid.size() != compareUUID.size()) - { - LoggerE("Invalid size"); - return false; - } - - return true; + pcrecpp::RE re("(([0-9a-zA-Z]+)-)+([0-9a-zA-Z]+)"); + std::string compareUUID = "00001101-0000-1000-8000-00805F9B34FB"; + + if (!re.FullMatch(uuid)) + { + LoggerE("Invalid UUID"); + return false; + } + + if (uuid.size() != compareUUID.size()) + { + LoggerE("Invalid size"); + return false; + } + + return true; } std::string BluetoothAdapter::getName() const { - const char* name = NULL; - std::string str = ""; - - if(!mAdapterPath) { - LoggerD("No BT adapter"); - return str; - } - - // get adapter properties and check Name property - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - LoggerE("Failed to get 'Name' property"); - return str; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Name")) { - name = g_variant_get_string(value, NULL); - if(name) - str = name; - break; - } - } - - g_variant_unref(reply); - - return str; + const char* name = NULL; + std::string str = ""; + + if(!mAdapterPath) + { + LoggerD("No BT adapter"); + return str; + } + + // get adapter properties and check Name property + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + mAdapterPath, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Adapter1", "Name"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err || !reply) + { + if(err) + g_error_free(err); + LoggerE("Failed to get 'Name' property"); + return str; + } + + GVariant *value; + g_variant_get(reply, "(v)", &value); + name = g_variant_get_string(value, NULL); + str = name; + + g_variant_unref(reply); + + return str; } void BluetoothAdapter::setName(std::string &name, MultiCallbackUserDataPtr userData) { - if(mEnabled == true) { - std::string adapterName = getName(); - if(adapterName == name) { // in case of same name - LoggerD("same name"); - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - return; - } - - if(mAdapterPath) { - GError *err = NULL; - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "SetProperty", - g_variant_new ("(sv)", // floating parameters are consumed, no cleanup/unref needed - "Name", - g_variant_new("s", name.c_str()) // floating parameters are consumed, no cleanup/unref needed - ), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - - if(err) { - LoggerE("Failed to call \"SetProperty\" DBUS method: " << err->message); - UnknownException *error = new UnknownException(err->message); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - g_error_free(err); - return; - } - - if(userData) - userData->invokeCallback("success"); - } - else { - LoggerE("No BT adapter"); - UnknownException *error = new UnknownException("No BT adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - } + if(mEnabled == true) + { + std::string adapterName = getName(); + if(adapterName == name) // in case of same name + { + LoggerD("same name"); + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + return; + } + + if(mAdapterPath) + { + GError *err = NULL; + + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), + BLUEZ_SERVICE, + mAdapterPath, + "org.freedesktop.DBus.Properties", + "Set", + g_variant_new("(ssv)", "org.bluez.Adapter1", "Name", g_variant_new_string(name.c_str())), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err) + { + LoggerE("Failed to call \"SetProperty\" DBUS method: " << err->message); + UnknownException *error = new UnknownException(err->message); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + g_error_free(err); + return; + } + + if(userData) + userData->invokeCallback("success"); + } + else + { + LoggerE("No BT adapter"); + UnknownException *error = new UnknownException("No BT adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + } } std::string BluetoothAdapter::getAddress() const { - const char* address = NULL; - std::string str = ""; - - if(!mAdapterPath) { - LoggerD("No BT adapter"); - return str; - } - - // get adapter properties and check Address property - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - LoggerE("Failed to get 'Address' property"); - return str; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Address")) { - address = g_variant_get_string(value, NULL); - if(address) - str = address; - break; - } - } - - g_variant_unref(reply); - - return str; + const char* address = NULL; + std::string str = ""; + + if(!mAdapterPath) + { + LoggerD("No BT adapter"); + return str; + } + + // get adapter properties and check Address property + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + mAdapterPath, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Adapter1", "Address"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err || !reply) + { + if(err) + g_error_free(err); + LoggerE("Failed to get 'Address' property"); + return str; + } + + //GVariantIter *iter; + GVariant *value; + g_variant_get(reply, "(v)", &value); + address = g_variant_get_string(value, NULL); + str = address; + //const char *key; + /* + while(g_variant_iter_next(iter, "{sv}", &key, &value)) { + if(!strcmp(key, "Address")) { + address = g_variant_get_string(value, NULL); + if(address) + str = address; + break; + } + } + */ + g_variant_unref(reply); + + return str; } bool BluetoothAdapter::getPowered() const { - return mEnabled; + return mEnabled; } void BluetoothAdapter::setPowered(bool powered, MultiCallbackUserDataPtr userData) { - LoggerD("entered"); - - bool btTechnologyPowered = isBtTechnologyPowered(); - if(!powered) { // Powering OFF BT. It is enough to take down BT technology - it will take down Adapter as well - if(!btTechnologyPowered) { // already powered OFF - LoggerD("BT already powered OFF ... calling success callback."); - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - return; - } - else { - if(setBluetoothPowered(powered)) { // BT powered OFF successfuly - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - } - else { - LoggerD("Failed to Power OFF BT technology - trying to Power OFF the Adapter directly"); - if(setAdapterPowered(powered)) { - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - } - else { - LoggerE("Failed to Power OFF both, BT and adapter as well ... calling error callback"); - UnknownException *error = new UnknownException("Failed to Power OFF BT/Adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - } - } - } - else { // Powering ON BT - if(btTechnologyPowered) { // already Powered ON - if(mEnabled) { // already Powered On - LoggerD("BT/Adapter already powered ON ... calling success callback."); - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - } - else { // BT powered, but Adapter is not - try to power it ON - LoggerD("BT technology is Powered ON, but adapter is not, trying to Power it ON"); - if(setAdapterPowered(powered)) { // successfuly powered ON ... calling success callback - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - } - else { - LoggerE("Failed to Power ON BT adapter ... calling error callback"); - UnknownException *error = new UnknownException("Failed to Power ON BT adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - } - } - else { - if(!setBluetoothPowered(powered)) { - LoggerE("Failed to Power ON BT technology ... calling error callback"); - UnknownException *error = new UnknownException("Failed to Power ON BT technology"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - /* - else { // BT technology powered ON (it should power ON adapter as well, but just in case, call Power ON on adapter as well) - if(setAdapterPowered(powered)) { - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - } - else { - LoggerE("Failed to Power ON BT adapter ... calling error callback"); - UnknownException *error = new UnknownException("Failed to Power ON BT adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - } - */ - else { - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - } - } - } - - mUserDataList[SET_POWERED].reset(); + bool btTechnologyPowered = isBtTechnologyPowered(); + if(!powered) // Powering OFF BT. It is enough to take down BT technology - it will take down Adapter as well + { + if(!btTechnologyPowered) // already powered OFF + { + LoggerE("BT already powered OFF ... calling success callback."); + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + return; + } + else + { + if(setBluetoothPowered(powered)) // BT powered OFF successfuly + { + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + } + else + { + LoggerE("Failed to Power OFF BT technology - trying to Power OFF the Adapter directly"); + if(setAdapterPowered(powered)) + { + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + } + else + { + LoggerE("Failed to Power OFF both, BT and adapter as well ... calling error callback"); + UnknownException *error = new UnknownException("Failed to Power OFF BT/Adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + } + } + } + else // Powering ON BT + { + if(btTechnologyPowered) // already Powered ON + { + if(mEnabled) // already Powered On + { + LoggerD("BT/Adapter already powered ON ... calling success callback."); + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + } + else // BT powered, but Adapter is not - try to power it ON + { + LoggerE("BT technology is Powered ON, but adapter is not, trying to Power it ON"); + if(setAdapterPowered(powered)) // successfuly powered ON ... calling success callback + { + LoggerE("successfull power on.... sending syncToAsyncSuccess"); + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + } + else + { + LoggerE("Failed to Power ON BT adapter ... calling error callback"); + UnknownException *error = new UnknownException("Failed to Power ON BT adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + } + } + else + { + if(!setBluetoothPowered(powered)) + { + LoggerE("Failed to Power ON BT technology ... calling error callback"); + UnknownException *error = new UnknownException("Failed to Power ON BT technology"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + /* + else { // BT technology powered ON (it should power ON adapter as well, but just in case, call Power ON on adapter as well) + if(setAdapterPowered(powered)) { + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + } + else { + LoggerE("Failed to Power ON BT adapter ... calling error callback"); + UnknownException *error = new UnknownException("Failed to Power ON BT adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + } + */ + else + { + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + } + } + } + + mUserDataList[SET_POWERED].reset(); } bool BluetoothAdapter::getVisible() const { - if(!mAdapterPath) { - LoggerD("No BT adapter"); - return false; - } - - // get adapter properties and check Discoverable property - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - LoggerE("Failed to get 'Discoverable' property"); - return false; - } - - bool visible = false; - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Discoverable")) { - visible = g_variant_get_boolean(value); - break; - } - } - - g_variant_unref(reply); - - return visible; + if(!mAdapterPath) + { + LoggerD("No BT adapter"); + return false; + } + + // get adapter properties and check Discoverable property + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + mAdapterPath, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Adapter1", "Discoverable"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err || !reply) + { + if(err) + g_error_free(err); + LoggerE("Failed to get 'Discoverable' property"); + return false; + } + + bool visible = false; + GVariant *value; + g_variant_get(reply, "(v)", &value); + visible = g_variant_get_boolean(value); + + g_variant_unref(reply); + + return visible; } void BluetoothAdapter::setVisible(bool visible, unsigned int timeout, MultiCallbackUserDataPtr userData) { - //TODO: implementation needed - UnknownException *error = new UnknownException("NOT IMPLEMENTED"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - /* - if(mEnabled == true) { - bt_adapter_visibility_mode_e discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; - if(visible == true) { - if(timeout == 0) - discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE; - else - discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE; - } - - bt_adapter_visibility_mode_e current = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; - int time = 0; - if(bt_adapter_get_visibility(¤t , &time) != BT_ERROR_NONE) { - LoggerE("bt_adapter_get_visibility() failed"); - UnknownException *error = new UnknownException("Can't get current visibility"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - if(discoverable_mode == current) { - if(discoverable_mode != BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE) { - LoggerD("same visibility"); - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - return; - } - else if((unsigned int)time == timeout) { - LoggerD("same visibility"); - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - return; - } - } - - if(mUserDataList[SET_VISIBLE] == NULL) { - bt_adapter_set_visibility_mode_changed_cb(onVisibilityChangedCB, this); - mUserDataList[SET_VISIBLE] = userData; - } else { - UnknownException *error = new UnknownException("Already requested"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - mRequestedVisibility = discoverable_mode; - int ret = bt_adapter_set_visibility(discoverable_mode, timeout); - switch(ret) { - case BT_ERROR_NONE: - { - LoggerD("bt_adapter_set_visibility() succeeded"); - return; - } - case BT_ERROR_INVALID_PARAMETER: - { - InvalidValuesException *error = new InvalidValuesException("Invalid value"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - break; - } - default: - { - UnknownException *error = new UnknownException("Unknown error"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - } - - bt_adapter_unset_visibility_mode_changed_cb(); - mUserDataList[SET_VISIBLE].reset(); - } else { // Not enabled - ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } -*/ + UnknownException *error = new UnknownException("NOT IMPLEMENTED"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + /* + if(mEnabled == true) { + bt_adapter_visibility_mode_e discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; + if(visible == true) { + if(timeout == 0) + discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE; + else + discoverable_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE; + } + + bt_adapter_visibility_mode_e current = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; + int time = 0; + if(bt_adapter_get_visibility(¤t , &time) != BT_ERROR_NONE) { + LoggerE("bt_adapter_get_visibility() failed"); + UnknownException *error = new UnknownException("Can't get current visibility"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + if(discoverable_mode == current) { + if(discoverable_mode != BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE) { + LoggerD("same visibility"); + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + return; + } + else if((unsigned int)time == timeout) { + LoggerD("same visibility"); + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + return; + } + } + + if(mUserDataList[SET_VISIBLE] == NULL) { + bt_adapter_set_visibility_mode_changed_cb(onVisibilityChangedCB, this); + mUserDataList[SET_VISIBLE] = userData; + } else { + UnknownException *error = new UnknownException("Already requested"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + mRequestedVisibility = discoverable_mode; + int ret = bt_adapter_set_visibility(discoverable_mode, timeout); + switch(ret) { + case BT_ERROR_NONE: + { + LoggerD("bt_adapter_set_visibility() succeeded"); + return; + } + case BT_ERROR_INVALID_PARAMETER: + { + InvalidValuesException *error = new InvalidValuesException("Invalid value"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + break; + } + default: + { + UnknownException *error = new UnknownException("Unknown error"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + } + + bt_adapter_unset_visibility_mode_changed_cb(); + mUserDataList[SET_VISIBLE].reset(); + } else { // Not enabled + ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + */ } void BluetoothAdapter::setChangeListener(MultiCallbackUserDataPtr userData) { - if(mChangeListener == NULL) - mChangeListener = userData; + if(mChangeListener == NULL) + mChangeListener = userData; } void BluetoothAdapter::unsetChangeListener() { - if(mChangeListener != NULL) - mChangeListener.reset(); + if(mChangeListener != NULL) + mChangeListener.reset(); } void BluetoothAdapter::discoverDevices(MultiCallbackUserDataPtr userData) { - if(!mAdapterPath) { - LoggerE("No BT adapter"); - UnknownException *error = new UnknownException("No BT adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - if(mUserDataList[DISCOVER_DEVICES] == NULL) { - mUserDataList[DISCOVER_DEVICES] = userData; - } else { - LoggerE("Already requested"); - UnknownException *error = new UnknownException("Already requested"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - if(mEnabled == true) { - GError *err = NULL; - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "StartDiscovery", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err) { - LoggerE("Failed to 'StartDiscovery' on adapter " << mAdapterPath << " : " << err->message); - UnknownException *error = new UnknownException(err->message); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - g_error_free(err); - mUserDataList[DISCOVER_DEVICES].reset(); - } - else { - LoggerD("Call to 'StartDiscovery' succeeded"); - - // store MAC address of previously found device into mDisappearedDevices - mDisappearedDevices.clear(); - for(auto iter = mFoundDevices.begin(); - iter != mFoundDevices.end(); iter++) { - BluetoothDeviceSharedPtr foundDevice = *iter; - mDisappearedDevices.push_back(foundDevice->getAddress()); - } - - mFoundDevices.clear(); - - // 'onstarted' callback is called after receiving 'Discovering' property changed to 'true' ... see handleSignal() method - //if(userData) - // userData->invokeCallback("onstarted"); - - Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_ADAPTER_IFACE, - mAdapterPath, "DeviceFound", BluetoothAdapter::handleSignal, - this); - - return; - } - } else { // Not enabled - LoggerE("Bluetooth device is turned off"); - ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - - mUserDataList[DISCOVER_DEVICES].reset(); + if(!mAdapterPath) + { + LoggerE("No BT adapter"); + UnknownException *error = new UnknownException("No BT adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + if(mUserDataList[DISCOVER_DEVICES] == NULL) + { + mUserDataList[DISCOVER_DEVICES] = userData; + } + else + { + LoggerE("Already requested"); + UnknownException *error = new UnknownException("Already requested"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + if(mEnabled == true) + { + GError *err = NULL; + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + mAdapterPath, + BLUEZ_ADAPTER_IFACE, + "StartDiscovery", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err) + { + LoggerE("Failed to 'StartDiscovery' on adapter " << mAdapterPath << " : " << err->message); + UnknownException *error = new UnknownException(err->message); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + g_error_free(err); + mUserDataList[DISCOVER_DEVICES].reset(); + } + else + { + LoggerD("Call to 'StartDiscovery' succeeded"); + + // store MAC address of previously found device into mDisappearedDevices + mDisappearedDevices.clear(); + for(auto iter = mFoundDevices.begin(); + iter != mFoundDevices.end(); iter++) + { + BluetoothDeviceSharedPtr foundDevice = *iter; + mDisappearedDevices.push_back(foundDevice->getAddress()); + } + + mFoundDevices.clear(); + + // 'onstarted' callback is called after receiving 'Discovering' property changed to 'true' ... see handleSignal() method + //if(userData) + // userData->invokeCallback("onstarted"); + + Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, "org.freedesktop.DBus.Properties", + mAdapterPath, "PropertiesChanged", BluetoothAdapter::handleSignal, + this); + + return; + } + } + else // Not enabled + { + LoggerE("Bluetooth device is turned off"); + ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + + mUserDataList[DISCOVER_DEVICES].reset(); } void BluetoothAdapter::stopDiscovery(MultiCallbackUserDataPtr userData) { - if(mUserDataList[DISCOVER_DEVICES] == NULL) { // not doing discovery - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - return; - } - - if(!mAdapterPath) { - LoggerE("No BT adapter"); - UnknownException *error = new UnknownException("No BT adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - else if(mEnabled == true) { - GError *err = NULL; - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "StopDiscovery", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err) { - LoggerE("Failed to 'StopDiscovery': " << err->message); - UnknownException *error = new UnknownException(err->message); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - g_error_free(err); - } else { - BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); - return; - } - } else { // Not enabled - ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - - mUserDataList[DISCOVER_DEVICES].reset(); + if(mUserDataList[DISCOVER_DEVICES] == NULL) // not doing discovery + { + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + return; + } + + if(!mAdapterPath) + { + LoggerE("No BT adapter"); + UnknownException *error = new UnknownException("No BT adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + else if(mEnabled == true) + { + GError *err = NULL; + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + mAdapterPath, + BLUEZ_ADAPTER_IFACE, + "StopDiscovery", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err) + { + LoggerE("Failed to 'StopDiscovery': " << err->message); + UnknownException *error = new UnknownException(err->message); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + g_error_free(err); + } + else + { + BluetoothCallbackUtil::syncToAsyncSuccessCallback(userData); + return; + } + } + else // Not enabled + { + ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + + mUserDataList[DISCOVER_DEVICES].reset(); } void BluetoothAdapter::getKnownDevices(MultiCallbackUserDataPtr userData) { - BluetoothCallbackUtil::syncToAsyncDeviceArrayCallback(userData); + BluetoothCallbackUtil::syncToAsyncDeviceArrayCallback(userData); } void BluetoothAdapter::getDevice(std::string &address, MultiCallbackUserDataPtr userData) { - BluetoothCallbackUtil::syncToAsyncDeviceCallback(userData, address); + BluetoothCallbackUtil::syncToAsyncDeviceCallback(userData, address); } void BluetoothAdapter::createBonding(std::string &address, MultiCallbackUserDataPtr userData) { - if(!isValidAddress(address)) { - LoggerE("Wrong address"); - NotFoundException *error = new NotFoundException("Wrong address"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - if(!mAdapterPath) { - LoggerE("No BT adapter"); - NotFoundException *error = new NotFoundException("No BT adapter"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - if(mUserDataList[CREATE_BONDING] == NULL) { - mCreateBondingAddress = address; - mUserDataList[CREATE_BONDING] = userData; - } else { - LoggerE("Already requested"); - UnknownException *error = new UnknownException("Already requested"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - // remove the device first, so the pairing can be initiated, otherwise pairing will fail - bool ok = removeDevice(address.c_str()); - if(!ok) - LoggerD("Failed to remove device: " << address); - - if(mEnabled == true) { - if(setupAgent(AGENT_PATH)) { - // CreatePairedDevice has to be ASYNC DBUS call - g_dbus_connection_call( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "CreatePairedDevice", - g_variant_new("(sos)", address.c_str(), AGENT_PATH, AGENT_CAPABILITIES), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - BluetoothAdapter::asyncCreatePairedDeviceCallback, - this); - LoggerD("Called 'CreatePairedDevice'"); - } else { - LoggerE("Failed to set-up Bluez Agent for pairing"); - ServiceNotAvailableException *error = new ServiceNotAvailableException("Failed to set-up Bluez Agent for pairing"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - } else { // Not enabled - LoggerE("Bluetooth device is turned off"); - ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } + if(!isValidAddress(address)) + { + LoggerE("Wrong address"); + NotFoundException *error = new NotFoundException("Wrong address"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + if(!mAdapterPath) + { + LoggerE("No BT adapter"); + NotFoundException *error = new NotFoundException("No BT adapter"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + if(mUserDataList[CREATE_BONDING] == NULL) + { + mCreateBondingAddress = address; + mUserDataList[CREATE_BONDING] = userData; + } + else + { + LoggerE("Already requested"); + UnknownException *error = new UnknownException("Already requested"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + char* devicePath = NULL; + + for (int i = 0; i < mFoundDevices.size(); i++) + { + if (mFoundDevices[i]->getAddress() == address) + { + LoggerE("checking mFoundDevices -> " << mFoundDevices[i]->getAddress()); + devicePath = mFoundDevices[i]->getDevicePath(); + break; + } + } + + if (!devicePath) + devicePath = getDeviceFromAddress(address); + + if(mEnabled == true) + { + // if(setupAgent(AGENT_PATH)) { + if (!devicePath) + { + LoggerE("devicePath was null, setting to empty string"); + devicePath = ""; + } + + if (devicePath != NULL) + { + + // CreatePairedDevice has to be ASYNC DBUS call + g_dbus_connection_call( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + devicePath, + BLUEZ_DEVICE_IFACE, + "Pair", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + BluetoothAdapter::asyncCreatePairedDeviceCallback, + this); + + } + else + LoggerE("No bluetooth device path found!"); + // } + /* + else + { + LoggerE("Failed to set-up Bluez Agent for pairing"); + ServiceNotAvailableException *error = new ServiceNotAvailableException("Failed to set-up Bluez Agent for pairing"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + */ + } + + else + { + // Not enabled + LoggerE("BLUEZ Bluetooth device is turned off"); + ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + LoggerD("done with createPairedDevice"); } void BluetoothAdapter::destroyBonding(std::string &address, MultiCallbackUserDataPtr userData) { - if(!isValidAddress(address)) { - LoggerE("Wrong address"); - NotFoundException *error = new NotFoundException("Wrong address"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - // get device info before removing, 'cause after removing you loose access to it ('FindDevice' will not find it) - bt_device_info_s deviceInfo; - bool hasDeviceInfo = getDeviceInfoByAddress(&deviceInfo, address.c_str()); - - if(!removeDevice(address.c_str())) { - if(userData) { - JSContextRef context = userData->getContext(); - UnknownException error("Failed to remove device"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); - } - - return; - } - - if(userData) { - if(hasDeviceInfo) { - BluetoothDeviceSharedPtr device(new BluetoothDevice(&deviceInfo)); - JSContextRef context = userData->getContext(); - JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device); - userData->invokeCallback("success", deviceObj); - } else { - JSContextRef context = userData->getContext(); - UnknownException error("Failed to get device info"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); - } - freeDeviceInfo(&deviceInfo); - } + if(!isValidAddress(address)) + { + LoggerE("Wrong address"); + NotFoundException *error = new NotFoundException("Wrong address"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + // get device info before removing, 'cause after removing you loose access to it ('FindDevice' will not find it) + bt_device_info_s deviceInfo; + bool hasDeviceInfo = getDeviceInfoByAddress(&deviceInfo, address.c_str()); + + if(!removeDevice(address.c_str())) + { + if(userData) + { + JSContextRef context = userData->getContext(); + UnknownException error("Failed to remove device"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); + } + + return; + } + + if(userData) + { + if(hasDeviceInfo) + { + BluetoothDeviceSharedPtr device(new BluetoothDevice(&deviceInfo)); + JSContextRef context = userData->getContext(); + JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device); + userData->invokeCallback("success", deviceObj); + } + else + { + JSContextRef context = userData->getContext(); + UnknownException error("Failed to get device info"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); + } + freeDeviceInfo(&deviceInfo); + } } void BluetoothAdapter::registerRFCOMMServiceByUUID(std::string &uuid, std::string &name, MultiCallbackUserDataPtr userData) { - BluetoothCallbackUtil::syncToAsyncServiceCallback(userData, uuid, name); + BluetoothCallbackUtil::syncToAsyncServiceCallback(userData, uuid, name); } void BluetoothAdapter::connectToServiceByUUID(std::string &remoteAddress, std::string &uuid, Common::MultiCallbackUserDataPtr userData) { - if(!isValidUUID(uuid)) { - LoggerE("Wrong UUID"); - InvalidValuesException *error = new InvalidValuesException("Wrong UUID"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - return; - } - - - if(mEnabled == true) { - int ret = bt_socket_connect_rfcomm(remoteAddress.c_str(), uuid.c_str()); - - switch(ret) { - case BT_ERROR_NONE: - { - LoggerD("bt_socket_connect_rfcomm() succeeded"); - bt_socket_set_connection_state_changed_cb(onSocketConnected, this); - - BluetoothConnReqPtr connReq = new BluetoothConnReq(uuid, userData); - mConnReqMap.insert(std::pair(remoteAddress, connReq)); - break; - } - case BT_ERROR_INVALID_PARAMETER: - case BT_ERROR_REMOTE_DEVICE_NOT_BONDED: - { - InvalidValuesException *error = new InvalidValuesException("Invalid value"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - break; - } - default: - { - UnknownException *error = new UnknownException("Unknown error"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } - } - } else { // Not enabled - ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); - } + if(!isValidUUID(uuid)) + { + LoggerE("Wrong UUID"); + InvalidValuesException *error = new InvalidValuesException("Wrong UUID"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + return; + } + + + if(mEnabled == true) + { + int ret = bt_socket_connect_rfcomm(remoteAddress.c_str(), uuid.c_str()); + + switch(ret) + { + case BT_ERROR_NONE: + { + LoggerD("bt_socket_connect_rfcomm() succeeded"); + bt_socket_set_connection_state_changed_cb(onSocketConnected, this); + + BluetoothConnReqPtr connReq = new BluetoothConnReq(uuid, userData); + mConnReqMap.insert(std::pair(remoteAddress, connReq)); + break; + } + case BT_ERROR_INVALID_PARAMETER: + case BT_ERROR_REMOTE_DEVICE_NOT_BONDED: + { + InvalidValuesException *error = new InvalidValuesException("Invalid value"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + break; + } + default: + { + UnknownException *error = new UnknownException("Unknown error"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } + } + } + else // Not enabled + { + ServiceNotAvailableException *error = new ServiceNotAvailableException("Bluetooth device is turned off"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(userData, error); + } } void BluetoothAdapter::returnKnownDevices(Common::MultiCallbackUserDataPtr userData) { - if(mEnabled == true) { - knownDevices = mFoundDevices; - - // Get a list of paired/bonded devices - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - } else { - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Devices")) { - g_variant_get(value, "ao", &iter); - const char *device = NULL; - while(g_variant_iter_next(iter, "o", &device)) { - if(isDevicePaired(device)) { - bt_device_info_s deviceInfo; - if(getDeviceInfo(&deviceInfo, device)) - foreachBondedDevicesCB(&deviceInfo, this); - freeDeviceInfo(&deviceInfo); - } - } - break; - } - } - - g_variant_unref(reply); - } - - if(knownDevices.size() > 0) { // There are found devices - //LoggerD("There are found devices"); - int num = knownDevices.size(); - JSObjectRef devices[num]; - for(int i = 0; i < num; i++) { - JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(userData->getContext(), knownDevices[i]); - devices[i] = deviceObj; - } - - userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), num, devices, NULL)); - } - else { // There is no found device - userData->invokeCallback("success", JSObjectMakeArray(userData->getContext(), 0, NULL, NULL) ); - } - } else { // Not enabled - LoggerE("Bluetooth device is turned off"); - userData->invokeCallback( - "error", - JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off")) - ); - } + char *result; + bool done = false; + + GError * error = nullptr; + GDBusProxy * managerProxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.bluez", + "/", + "org.freedesktop.DBus.ObjectManager", + nullptr,&error); + if(error) + { + LoggerE("could not create ObjManager proxy"); + // DebugOut(DebugOut::Error)<<"Could not create ObjectManager proxy for Bluez: "<message<message<invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("Wrong address"))); - return; - } - - if(mEnabled == true) { - bt_device_info_s deviceInfo; - bool success = getDeviceInfoByAddress(&deviceInfo, address.c_str()); - - if(success) { - BluetoothDeviceSharedPtr device(new BluetoothDevice(&deviceInfo)); - LoggerD("invoke successCallback"); - userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), device)); - return; - } else { - JSContextRef context = userData->getContext(); - UnknownException error("Failed to get device info"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); - } - freeDeviceInfo(&deviceInfo); - - std::vector::iterator iter; - for(iter = mFoundDevices.begin(); iter != mFoundDevices.end(); ++iter) { - BluetoothDeviceSharedPtr foundDevice = *iter; - if(!strcmp(foundDevice->getAddress().c_str(), address.c_str())) { - LoggerD("Found in mFoundDevices"); - userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), foundDevice)); - break; - } - } - - if(iter == mFoundDevices.end()) { - LoggerE("Can't find this device"); - - userData->invokeCallback( - "error", - JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("There is no device with the given address")) - ); - } - } else { // Not enabled - LoggerE("Bluetooth device is turned off"); - userData->invokeCallback( - "error", - JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off")) - ); - } + if(!isValidAddress(address)) + { + LoggerE("Wrong address"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("Wrong address"))); + return; + } + + if(mEnabled == true) + { + bt_device_info_s deviceInfo; + bool success = getDeviceInfoByAddress(&deviceInfo, address.c_str()); + + if(success) + { + BluetoothDeviceSharedPtr device(new BluetoothDevice(&deviceInfo)); + LoggerD("invoke successCallback"); + userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), device)); + return; + } + else + { + JSContextRef context = userData->getContext(); + UnknownException error("Failed to get device info"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); + } + freeDeviceInfo(&deviceInfo); + + std::vector::iterator iter; + for(iter = mFoundDevices.begin(); iter != mFoundDevices.end(); ++iter) + { + BluetoothDeviceSharedPtr foundDevice = *iter; + if(!strcmp(foundDevice->getAddress().c_str(), address.c_str())) + { + LoggerD("Found in mFoundDevices"); + userData->invokeCallback("success", JSBluetoothDevice::createJSObject(userData->getContext(), foundDevice)); + break; + } + } + + if(iter == mFoundDevices.end()) + { + LoggerE("Can't find this device"); + + userData->invokeCallback( + "error", + JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), NotFoundException("There is no device with the given address")) + ); + } + } + else // Not enabled + { + LoggerE("Bluetooth device is turned off"); + userData->invokeCallback( + "error", + JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off")) + ); + } } void BluetoothAdapter::returnRegisteredService(std::string &uuid, std::string &name, Common::MultiCallbackUserDataPtr userData) { - if(!isValidUUID(uuid)) { - LoggerE("Wrong UUID"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Wrong UUID"))); - return; - } - - if(mEnabled == true) { - - bool isRegistered; - if(bt_adapter_is_service_used(uuid.c_str(), &isRegistered) == BT_ERROR_NONE && isRegistered == true) { - LoggerD("Already registered"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Already registered"))); - return; - } - - int socket = -1; - int ret = bt_socket_create_rfcomm(uuid.c_str(), &socket); - - switch(ret) { - case BT_ERROR_NONE: - { - LoggerD("bt_socket_create_rfcomm() succeeded"); - int ret = bt_socket_listen_and_accept_rfcomm(socket, 0); - switch(ret) { - case BT_ERROR_NONE: - { - LoggerD("bt_socket_listen() succeeded"); - bt_socket_set_connection_state_changed_cb(onSocketConnected, this); - - BluetoothServiceHandlerPtr serviceHandler = new BluetoothServiceHandler(uuid, name, socket); - mRegisteredUUID.insert(std::pair(uuid, serviceHandler)); - - JSObjectRef serviceObj = JSBluetoothServiceHandler::createJSObject(userData->getContext(), serviceHandler); - userData->invokeCallback("success", serviceObj); - break; - } - case BT_ERROR_INVALID_PARAMETER: - { - LoggerD("Invalid value"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value"))); - break; - } - default: - { - LoggerD("Unknown exception"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception"))); - } - } - - break; - } - case BT_ERROR_INVALID_PARAMETER: - { - LoggerD("Invalid value"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value"))); - break; - } - default: - { - LoggerD("Unknown exception"); - userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception"))); - } - } - } else { // Not enabled - LoggerE("Bluetooth device is turned off"); - userData->invokeCallback( - "error", - JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off")) - ); - } + if(!isValidUUID(uuid)) + { + LoggerE("Wrong UUID"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Wrong UUID"))); + return; + } + + if(mEnabled == true) + { + + bool isRegistered; + if(bt_adapter_is_service_used(uuid.c_str(), &isRegistered) == BT_ERROR_NONE && isRegistered == true) + { + LoggerD("Already registered"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Already registered"))); + return; + } + + int socket = -1; + int ret = bt_socket_create_rfcomm(uuid.c_str(), &socket); + + switch(ret) + { + case BT_ERROR_NONE: + { + LoggerD("bt_socket_create_rfcomm() succeeded"); + int ret = bt_socket_listen_and_accept_rfcomm(socket, 0); + switch(ret) + { + case BT_ERROR_NONE: + { + LoggerD("bt_socket_listen() succeeded"); + bt_socket_set_connection_state_changed_cb(onSocketConnected, this); + + BluetoothServiceHandlerPtr serviceHandler = new BluetoothServiceHandler(uuid, name, socket); + mRegisteredUUID.insert(std::pair(uuid, serviceHandler)); + + JSObjectRef serviceObj = JSBluetoothServiceHandler::createJSObject(userData->getContext(), serviceHandler); + userData->invokeCallback("success", serviceObj); + break; + } + case BT_ERROR_INVALID_PARAMETER: + { + LoggerD("Invalid value"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value"))); + break; + } + default: + { + LoggerD("Unknown exception"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception"))); + } + } + + break; + } + case BT_ERROR_INVALID_PARAMETER: + { + LoggerD("Invalid value"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), InvalidValuesException("Invalid value"))); + break; + } + default: + { + LoggerD("Unknown exception"); + userData->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), UnknownException("Unknown exception"))); + } + } + } + else // Not enabled + { + LoggerE("Bluetooth device is turned off"); + userData->invokeCallback( + "error", + JSWebAPIErrorFactory::makeErrorObject(userData->getContext(), ServiceNotAvailableException("Bluetooth device is turned off")) + ); + } } -bool BluetoothAdapter::isBtTechnologyPowered() { - if(!mBluetoothTechnology) { - LoggerE("Invalid BT technology to get 'Powered' state."); - return false; - } - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - CONNMAN_SERVICE, - mBluetoothTechnology, - CONNMAN_TECHNOLOGY_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - return false; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - bool powered = false; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Powered")) { - powered = g_variant_get_boolean(value); - break; - } - } - - g_variant_unref(reply); - - return powered; +bool BluetoothAdapter::isBtTechnologyPowered() +{ + + if(!mBluetoothTechnology) + { + LoggerE("Invalid BT technology to get 'Powered' state."); + return false; + } + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + CONNMAN_SERVICE, + mBluetoothTechnology, + CONNMAN_TECHNOLOGY_IFACE, + "GetProperties", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err || !reply) + { + if(err) + g_error_free(err); + return false; + } + + GVariantIter *iter; + g_variant_get(reply, "(a{sv})", &iter); + const char *key; + GVariant *value; + bool powered = false; + while(g_variant_iter_next(iter, "{sv}", &key, &value)) + { + if(!strcmp(key, "Powered")) + { + powered = g_variant_get_boolean(value); + break; + } + } + + g_variant_unref(reply); + + return powered; } + + gchar* BluetoothAdapter::getDefaultAdapter() const { - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - "/", - BLUEZ_MANAGER_IFACE, - "DefaultAdapter", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) { - LoggerE("Failed to get default adapter: " << err->message); - g_error_free(err); - } - if(!reply) - LoggerE("Reply from 'DefaultAdapter' is null"); - return NULL; - } - - char *adapter = NULL; - g_variant_get(reply, "(o)", &adapter); - LoggerD("DefaultAdapter: " << adapter); - - // make a copy of adapter, 'cause it will be destroyed when 'reply' is un-refed - char *result = adapter?strdup(adapter):NULL; - - g_variant_unref(reply); - - return result; + char *result; + bool done = false; + + GError * error = nullptr; + GDBusProxy * managerProxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.bluez", + "/", + "org.freedesktop.DBus.ObjectManager", + nullptr,&error); + if(error) + { + LoggerE("could not create ObjManager proxy"); + // DebugOut(DebugOut::Error)<<"Could not create ObjectManager proxy for Bluez: "<message<message<message<message< '" << signal_name << "' -> '" << object_path << "'"); - - BluetoothAdapter *ctx = static_cast(user_data); - if(!ctx) { - LoggerD("Failed to cast to BluetoothAdapter"); - return; - } - - - if(!strcmp(interface_name, BLUEZ_MANAGER_IFACE)) { - if(!strcmp(signal_name, "AdapterAdded")) { - const char *adapter = NULL; - g_variant_get(parameters, "(o)", &adapter); - if(adapter) { - LoggerD("Adapter added: " << adapter); - gchar * adapterPath = ctx->getDefaultAdapter(); - free(ctx->mAdapterPath); - ctx->mAdapterPath = adapterPath; - if(adapterPath) { - Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_ADAPTER_IFACE, - adapterPath, "PropertyChanged", BluetoothAdapter::handleSignal, - ctx); - } - } - } - else if(!strcmp(signal_name, "AdapterRemoved")) { - const char *adapter = NULL; - g_variant_get(parameters, "(o)", &adapter); - if(adapter) { - LoggerD("Adapter removed: " << adapter); - } - } - } - else if(!strcmp(interface_name, BLUEZ_ADAPTER_IFACE)) { - if(!strcmp(signal_name, "PropertyChanged")) { - const char *name; - GVariant *var; - g_variant_get(parameters, "(sv)", &name, &var); - LoggerD("\tname=" << name); - if(!strcmp(name, "Name")) { - const char *_name = g_variant_get_string(var, NULL); - ctx->onNameChanged(_name); - } - else if(!strcmp(name, "Powered")) { - bool powered = g_variant_get_boolean(var); - ctx->onPoweredChanged(powered); - } - else if(!strcmp(name, "Discoverable")) { - bool visible = g_variant_get_boolean(var); - ctx->onVisibilityChanged(visible); - } - else if(!strcmp(name, "Discovering")) { - bool discovering = g_variant_get_boolean(var); - if(discovering) { // discovery started - MultiCallbackUserDataPtr callback = static_cast(ctx->mUserDataList[DISCOVER_DEVICES]); - if(callback) { - callback->invokeCallback("onstarted"); - } - } - else { // discovery completed - LoggerD("Discovery completed"); - if(ctx->mUserDataList[DISCOVER_DEVICES] != NULL) { - MultiCallbackUserDataPtr callback = - static_cast(ctx->mUserDataList[DISCOVER_DEVICES]); - - if(callback) { - if(ctx->mDisappearedDevices.size() > 0) { - LoggerD("There are disappeared devices"); - for(auto iter = ctx->mDisappearedDevices.begin(); - iter != ctx->mDisappearedDevices.end(); iter++) { - - callback->invokeCallback("ondevicedisappeared", - JSUtil::toJSValueRef(callback->getContext(), *iter)); - } - } - - if(ctx->mFoundDevices.size() > 0) { // There are found devices - LoggerD("There are found devices"); - int num = ctx->mFoundDevices.size(); - JSObjectRef devices[num]; - for(int i = 0; i < num; i++) { - JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(callback->getContext(), ctx->mFoundDevices[i]); - devices[i] = deviceObj; - } - - ctx->mUserDataList[DISCOVER_DEVICES].reset(); - - callback->invokeCallback( - "onfinished", - JSObjectMakeArray(callback->getContext(), num, devices, NULL) ); - } - else { // There is no found device - LoggerD("There is no found device"); - ctx->mUserDataList[DISCOVER_DEVICES].reset(); - - callback->invokeCallback( - "onfinished", - JSObjectMakeArray(callback->getContext(), 0, NULL, NULL) ); - } - } - - Utils::removeSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_ADAPTER_IFACE, object_path, "DeviceFound"); - - GError *err = NULL; - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - ctx->mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "StopDiscovery", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err) - g_error_free(err); - } - } - } - } - else if(!strcmp(signal_name, "DeviceFound")) { // found remote BT device - bt_adapter_device_discovery_info_s discoveryInfo; - discoveryInfo.remote_name = NULL; - discoveryInfo.remote_address = NULL; - discoveryInfo.service_uuid = NULL; - discoveryInfo.service_count = 0; - - const char *address; - GVariantIter *iter; - g_variant_get(parameters, "(sa{sv})", &address, &iter); - discoveryInfo.remote_address = address?strdup(address):NULL; - const char *key; - GVariant *value; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - //LoggerD("KEY: " << key); - if(!strcmp(key, "Name")) { - const char *name = g_variant_get_string(value, NULL); - discoveryInfo.remote_name = name?strdup(name):NULL; - } - else if(!strcmp(key, "Paired")) { - discoveryInfo.is_bonded = g_variant_get_boolean(value); - } - else if(!strcmp(key, "Class")) { - guint32 _class = g_variant_get_uint32(value); - uint8_t minor = _class & 0xff; - uint8_t major = (_class >> 8) & 0xff; - discoveryInfo.bt_class.minor_device_class = (bt_minor_device_class_e) minor; - discoveryInfo.bt_class.major_device_class = (bt_major_device_class_e) major; - //discoveryInfo.bt_class.major_service_class_mask = - } - else if(!strcmp(key, "UUIDs")) { - GVariantIter *iter; - const char *uuid = NULL; - g_variant_get(value, "as", &iter); - discoveryInfo.service_count = g_variant_iter_n_children(iter); - discoveryInfo.service_uuid = (char**)malloc(discoveryInfo.service_count*sizeof(char*)); - char **uuids = discoveryInfo.service_uuid; // make a copy of ptr, since we will modify the pointer - while(g_variant_iter_next(iter, "s", &uuid)) { - *uuids++ = uuid?strdup(uuid):NULL; - } - } - } - - if(!discoveryInfo.remote_address) { - LoggerD("discovery info ... remote_address is null"); - ctx->freeDiscoveryInfo(&discoveryInfo); - return; - } - - if(!discoveryInfo.remote_name) { - LoggerD("discovery info ... remote_name is null for " << discoveryInfo.remote_address); - discoveryInfo.remote_name = strdup(""); - } - - LoggerD("Found BT device: " << discoveryInfo.remote_address << " ... " << (discoveryInfo.remote_name?discoveryInfo.remote_name:"")); - - if(ctx->mUserDataList[DISCOVER_DEVICES] != NULL) { // requested event - MultiCallbackUserDataPtr callback = - static_cast(ctx->mUserDataList[DISCOVER_DEVICES]); - - if(callback) { - if(!ctx->isDeviceInList(ctx->mFoundDevices, discoveryInfo.remote_address)) { - // create BluetoothDevice - BluetoothDeviceSharedPtr device(new BluetoothDevice(&discoveryInfo)); - JSContextRef context = callback->getContext(); - JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device); - ctx->mFoundDevices.push_back(device); - - // remove MAC address of found device from mDisappearedDevices - for(auto iter = ctx->mDisappearedDevices.begin(); iter != ctx->mDisappearedDevices.end(); iter++) { - if(!strcmp(discoveryInfo.remote_address, (*iter).c_str())) { - ctx->mDisappearedDevices.erase(iter); - break; - } - } - - callback->invokeCallback("ondevicefound", deviceObj); - } - } - } - - ctx->freeDiscoveryInfo(&discoveryInfo); - } - } - /* - else if(!strcmp(interface_name, CONNMAN_TECHNOLOGY_IFACE)) { - if(!strcmp(signal_name, "PropertyChanged")) { - const char *name; - GVariant *value; - g_variant_get(parameters, "(sv)", &name, &value); - if(!strcmp(name, "Powered")) { - bool powered = g_variant_get_boolean(value); - ctx->onPoweredChanged(powered); - } - } - } - */ + LoggerE("signal received: '" << interface_name << "' -> '" << signal_name << "' -> '" << object_path << "'"); + + BluetoothAdapter *ctx = static_cast(user_data); + if(!ctx) + { + LoggerD("Failed to cast to BluetoothAdapter"); + return; + } + + + if(!strcmp(interface_name, "org.freedesktop.DBus.ObjectManager")) + { + if(!strcmp(signal_name, "InterfacesAdded")) + { + + char *objPath = NULL; + GVariantIter* iter; + + g_variant_get(parameters, "(oa{sa{sv}})", &objPath, &iter); + + if(objPath) + { + + GVariantIter* iter2; + char *interface = NULL; + + while(g_variant_iter_next(iter, "{sa{sv}}",&interface, &iter2)) + { + + if(!strcmp(interface, "org.bluez.Adapter1")) + { + gchar * adapterPath = ctx->getDefaultAdapter(); + free(ctx->mAdapterPath); + ctx->mAdapterPath = adapterPath; + + if(adapterPath) + { + Utils::setSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, "org.freedesktop.DBus.Properties", + adapterPath, "PropertiesChanged", BluetoothAdapter::handleSignal, + ctx); + } + } + + else if(!strcmp(interface, "org.bluez.Device1")) + { + bt_adapter_device_discovery_info_s discoveryInfo; + discoveryInfo.remote_name = NULL; + discoveryInfo.remote_address = NULL; + discoveryInfo.service_uuid = NULL; + discoveryInfo.service_count = 0; + + const char *key; + GVariant *value; + + while(g_variant_iter_next(iter2, "{sv}", &key, &value)) + { + if(!strcmp(key, "Address")) + { + const char *address = g_variant_get_string(value, NULL); + discoveryInfo.remote_address = address?strdup(address):NULL; + } + + else if(!strcmp(key, "Name")) + { + const char *name = g_variant_get_string(value, NULL); + discoveryInfo.remote_name = name?strdup(name):NULL; + } + + else if(!strcmp(key, "Paired")) + { + discoveryInfo.is_bonded = g_variant_get_boolean(value); + } + + else if(!strcmp(key, "Class")) + { + guint32 _class = g_variant_get_uint32(value); + uint8_t minor = _class & 0xff; + uint8_t major = (_class >> 8) & 0xff; + discoveryInfo.bt_class.minor_device_class = (bt_minor_device_class_e) minor; + discoveryInfo.bt_class.major_device_class = (bt_major_device_class_e) major; + //discoveryInfo.bt_class.major_service_class_mask = + } + + else if(!strcmp(key, "UUIDs")) + { + GVariantIter *iter; + const char *uuid = NULL; + g_variant_get(value, "as", &iter); + discoveryInfo.service_count = g_variant_iter_n_children(iter); + discoveryInfo.service_uuid = (char**)malloc(discoveryInfo.service_count*sizeof(char*)); + char **uuids = discoveryInfo.service_uuid; // make a copy of ptr, since we will modify the pointer + while(g_variant_iter_next(iter, "s", &uuid)) + { + *uuids++ = uuid?strdup(uuid):NULL; + } + } + } + + if(!discoveryInfo.remote_address) + { + ctx->freeDiscoveryInfo(&discoveryInfo); + return; + } + + if(!discoveryInfo.remote_name) + { + LoggerD("discovery info ... remote_name is null for " << discoveryInfo.remote_address); + discoveryInfo.remote_name = strdup(""); + } + + LoggerD("Found BT device: " << discoveryInfo.remote_address << " ... " << (discoveryInfo.remote_name?discoveryInfo.remote_name:"")); + + if(ctx->mUserDataList[DISCOVER_DEVICES] != NULL) + { + // requested event + MultiCallbackUserDataPtr callback = + static_cast(ctx->mUserDataList[DISCOVER_DEVICES]); + + if(callback) + { + if(!ctx->isDeviceInList(ctx->mFoundDevices, discoveryInfo.remote_address)) + { + // create BluetoothDevice + BluetoothDeviceSharedPtr device(new BluetoothDevice(&discoveryInfo, objPath)); + JSContextRef context = callback->getContext(); + JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device); + ctx->mFoundDevices.push_back(device); + + // remove MAC address of found device from mDisappearedDevices + for(auto iter = ctx->mDisappearedDevices.begin(); iter != ctx->mDisappearedDevices.end(); iter++) + { + if(!strcmp(discoveryInfo.remote_address, (*iter).c_str())) + { + ctx->mDisappearedDevices.erase(iter); + break; + } + } + + callback->invokeCallback("ondevicefound", deviceObj); + } + } + } + + ctx->freeDiscoveryInfo(&discoveryInfo); + } + } + } + } + else if(!strcmp(signal_name, "AdapterRemoved")) + { + const char *adapter = NULL; + g_variant_get(parameters, "(o)", &adapter); + if(adapter) + { + LoggerD("Adapter removed: " << adapter); + } + } + } + else if(!strcmp(interface_name, BLUEZ_ADAPTER_IFACE)) + { + if(!strcmp(signal_name, "PropertyChanged")) + { + const char *name; + GVariant *var; + g_variant_get(parameters, "(sv)", &name, &var); + LoggerD("\tname=" << name); + if(!strcmp(name, "Name")) + { + const char *_name = g_variant_get_string(var, NULL); + ctx->onNameChanged(_name); + } + else if(!strcmp(name, "Powered")) + { + bool powered = g_variant_get_boolean(var); + ctx->onPoweredChanged(powered); + } + else if(!strcmp(name, "Discoverable")) + { + bool visible = g_variant_get_boolean(var); + ctx->onVisibilityChanged(visible); + } + else if(!strcmp(name, "Discovering")) + { + bool discovering = g_variant_get_boolean(var); + if(discovering) // discovery started + { + MultiCallbackUserDataPtr callback = static_cast(ctx->mUserDataList[DISCOVER_DEVICES]); + if(callback) + { + callback->invokeCallback("onstarted"); + } + } + else // discovery completed + { + LoggerD("Discovery completed"); + if(ctx->mUserDataList[DISCOVER_DEVICES] != NULL) + { + MultiCallbackUserDataPtr callback = + static_cast(ctx->mUserDataList[DISCOVER_DEVICES]); + + if(callback) + { + if(ctx->mDisappearedDevices.size() > 0) + { + LoggerD("There are disappeared devices"); + for(auto iter = ctx->mDisappearedDevices.begin(); + iter != ctx->mDisappearedDevices.end(); iter++) + { + + callback->invokeCallback("ondevicedisappeared", + JSUtil::toJSValueRef(callback->getContext(), *iter)); + } + } + + if(ctx->mFoundDevices.size() > 0) // There are found devices + { + LoggerD("There are found devices"); + int num = ctx->mFoundDevices.size(); + JSObjectRef devices[num]; + for(int i = 0; i < num; i++) + { + JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(callback->getContext(), ctx->mFoundDevices[i]); + devices[i] = deviceObj; + } + + ctx->mUserDataList[DISCOVER_DEVICES].reset(); + + callback->invokeCallback( + "onfinished", + JSObjectMakeArray(callback->getContext(), num, devices, NULL) ); + } + else // There is no found device + { + LoggerD("There is no found device"); + ctx->mUserDataList[DISCOVER_DEVICES].reset(); + + callback->invokeCallback( + "onfinished", + JSObjectMakeArray(callback->getContext(), 0, NULL, NULL) ); + } + } + + Utils::removeSignalListener(G_BUS_TYPE_SYSTEM, BLUEZ_SERVICE, BLUEZ_ADAPTER_IFACE, object_path, "DeviceFound"); + + GError *err = NULL; + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + ctx->mAdapterPath, + BLUEZ_ADAPTER_IFACE, + "StopDiscovery", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err) + g_error_free(err); + } + } + } + } + } + /* + else if(!strcmp(interface_name, CONNMAN_TECHNOLOGY_IFACE)) { + if(!strcmp(signal_name, "PropertyChanged")) { + const char *name; + GVariant *value; + g_variant_get(parameters, "(sv)", &name, &value); + if(!strcmp(name, "Powered")) { + bool powered = g_variant_get_boolean(value); + ctx->onPoweredChanged(powered); + } + } + } + */ } -bool BluetoothAdapter::isDeviceInList(std::vector list, const char *address) { - bool exists = false; - for(auto iter = list.begin(); iter != list.end(); iter++) { - if(!strcmp((*iter)->getAddress().c_str(), address)) { - exists = true; - break; - } - } +bool BluetoothAdapter::isDeviceInList(std::vector list, const char *address) +{ - return exists; + bool exists = false; + for(auto iter = list.begin(); iter != list.end(); iter++) + { + if(!strcmp((*iter)->getAddress().c_str(), address)) + { + exists = true; + break; + } + } + + return exists; } bool BluetoothAdapter::setAdapterPowered(bool value) { - LoggerD("entered"); - - if(mAdapterPath) { - GError *err = NULL; - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "SetProperty", - g_variant_new ("(sv)", // floating parameters are consumed, no cleanup/unref needed - "Powered", - //g_variant_new("b", &value) - g_variant_new_boolean(value) - ), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - - if(err) { - LoggerE("Failed to call \"SetProperty\" DBUS method: " << err->message); - g_error_free(err); - return false; - } - - return true; - } - - return false; + if(mAdapterPath) + { + GError *err = NULL; + + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), + BLUEZ_SERVICE, + mAdapterPath, + "org.freedesktop.DBus.Properties", + "Set", + g_variant_new("(ssv)", "org.bluez.Adapter1", "Powered", g_variant_new_boolean(value)), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err) + { + LoggerE("Failed to call \"SetProperty\" DBUS method: " << err->message); + g_error_free(err); + return false; + } + + return true; + } + + return false; } void BluetoothAdapter::onPoweredChanged(bool powered) { - mEnabled = powered; - - if(mChangeListener != NULL) { - MultiCallbackUserDataPtr callback = static_cast(mChangeListener); - if(callback) { - JSContextRef context = callback->getContext(); - JSValueRef value = JSValueMakeBoolean(context, powered); - - callback->invokeCallback("onstatechanged", value); - } - } - - if(!powered && mUserDataList[DISCOVER_DEVICES] != NULL) - mUserDataList[DISCOVER_DEVICES].reset(); + mEnabled = powered; + + if(mChangeListener != NULL) + { + MultiCallbackUserDataPtr callback = static_cast(mChangeListener); + if(callback) + { + JSContextRef context = callback->getContext(); + JSValueRef value = JSValueMakeBoolean(context, powered); + + callback->invokeCallback("onstatechanged", value); + } + } + + if(!powered && mUserDataList[DISCOVER_DEVICES] != NULL) + mUserDataList[DISCOVER_DEVICES].reset(); } void BluetoothAdapter::onNameChanged(const char *name) { - if(mUserDataList[SET_NAME] != NULL) { // requested event - MultiCallbackUserDataPtr callback = static_cast(mUserDataList[SET_NAME]); - mUserDataList[SET_NAME].reset(); - if(callback) - callback->invokeCallback("success"); - } - else { // unexpected event - LoggerW("Bluetooth name is changed unexpectedly"); - } - - if(mChangeListener != NULL) { - MultiCallbackUserDataPtr callback = static_cast(mChangeListener); - if(callback) { - JSContextRef context = callback->getContext(); - JSStringRef nameRef = JSStringCreateWithUTF8CString(name); - JSValueRef value = JSValueMakeString(context, nameRef); - - callback->invokeCallback("onnamechanged", value); - } - } + if(mUserDataList[SET_NAME] != NULL) // requested event + { + MultiCallbackUserDataPtr callback = static_cast(mUserDataList[SET_NAME]); + mUserDataList[SET_NAME].reset(); + if(callback) + callback->invokeCallback("success"); + } + else // unexpected event + { + LoggerW("Bluetooth name is changed unexpectedly"); + } + + if(mChangeListener != NULL) + { + MultiCallbackUserDataPtr callback = static_cast(mChangeListener); + if(callback) + { + JSContextRef context = callback->getContext(); + JSStringRef nameRef = JSStringCreateWithUTF8CString(name); + JSValueRef value = JSValueMakeString(context, nameRef); + + callback->invokeCallback("onnamechanged", value); + } + } } void BluetoothAdapter::onVisibilityChanged(bool visible) { - if(mChangeListener != NULL) { - MultiCallbackUserDataPtr callback = static_cast(mChangeListener); - if(callback) { - JSContextRef context = callback->getContext(); - JSValueRef value = JSValueMakeBoolean(context, visible); - - callback->invokeCallback("onvisibilitychanged", value); - } - } + if(mChangeListener != NULL) + { + MultiCallbackUserDataPtr callback = static_cast(mChangeListener); + if(callback) + { + JSContextRef context = callback->getContext(); + JSValueRef value = JSValueMakeBoolean(context, visible); + + callback->invokeCallback("onvisibilitychanged", value); + } + } } -void BluetoothAdapter::asyncCreatePairedDeviceCallback(GObject *source, GAsyncResult *result, gpointer user_data) { - BluetoothAdapter *ctx = static_cast(user_data); - if(!ctx) { - LoggerE("Failed to cast to BluetoothAdapter"); - return; - } - - GError *err = NULL; - GVariant *reply; - reply = g_dbus_connection_call_finish(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), result, &err); - if(err || !reply) { - LoggerD("Failed to CreatePairedDevice: " << (err?err->message:"Invalid reply")); - if(ctx->mUserDataList[CREATE_BONDING] != NULL) { - MultiCallbackUserDataPtr callback = static_cast(ctx->mUserDataList[CREATE_BONDING]); - if(callback) { - NotFoundException *error = new NotFoundException("Failed to CreatePairedDevice"); - BluetoothCallbackUtil::syncToAsyncErrorCallback(callback, error); - } - } - if(err) - g_error_free(err); - } else { - LoggerD("Got reply from CreatePairedDevice"); - if(ctx->mUserDataList[CREATE_BONDING] != NULL) { - MultiCallbackUserDataPtr callback = static_cast(ctx->mUserDataList[CREATE_BONDING]); - if(callback) { - bt_device_info_s deviceInfo; - if(ctx->getDeviceInfoByAddress(&deviceInfo, ctx->mCreateBondingAddress.c_str())) { - BluetoothDeviceSharedPtr device(new BluetoothDevice(&deviceInfo)); - JSContextRef context = callback->getContext(); - JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device); - callback->invokeCallback("success", deviceObj); - } else { - JSContextRef context = callback->getContext(); - UnknownException error("Failed to get device info"); - callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); - } - ctx->freeDeviceInfo(&deviceInfo); - } - } - } - - ctx->mCreateBondingAddress.clear(); - ctx->mUserDataList[CREATE_BONDING].reset(); - - g_variant_unref(reply); +void BluetoothAdapter::asyncCreatePairedDeviceCallback(GObject *source, GAsyncResult *result, gpointer user_data) +{ + + BluetoothAdapter *ctx = static_cast(user_data); + if(!ctx) + { + LoggerE("Failed to cast to BluetoothAdapter"); + return; + } + + GError *err = NULL; + GVariant *reply; + reply = g_dbus_connection_call_finish(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), result, &err); + if(err || !reply) + { + LoggerE("Failed to CreatePairedDevice: " << (err?err->message:"Invalid reply")); + if(ctx->mUserDataList[CREATE_BONDING] != NULL) + { + MultiCallbackUserDataPtr callback = static_cast(ctx->mUserDataList[CREATE_BONDING]); + if(callback) + { + NotFoundException *error = new NotFoundException("Failed to CreatePairedDevice"); + BluetoothCallbackUtil::syncToAsyncErrorCallback(callback, error); + } + } + if(err) + g_error_free(err); + } + + else + { + LoggerE("Got reply from CreatePairedDevice"); + if(ctx->mUserDataList[CREATE_BONDING] != NULL) + { + MultiCallbackUserDataPtr callback = static_cast(ctx->mUserDataList[CREATE_BONDING]); + if(callback) + { + bt_device_info_s deviceInfo; + if(ctx->getDeviceInfoByAddress(&deviceInfo, ctx->mCreateBondingAddress.c_str())) + { + BluetoothDeviceSharedPtr device(new BluetoothDevice(&deviceInfo)); + JSContextRef context = callback->getContext(); + JSObjectRef deviceObj = JSBluetoothDevice::createJSObject(context, device); + callback->invokeCallback("success", deviceObj); + } + else + { + LoggerE("CreatePairedDevice failed to get device info"); + JSContextRef context = callback->getContext(); + UnknownException error("Failed to get device info"); + callback->invokeCallback("error", JSWebAPIErrorFactory::makeErrorObject(context, error)); + } + ctx->freeDeviceInfo(&deviceInfo); + } + } + } + + ctx->mCreateBondingAddress.clear(); + ctx->mUserDataList[CREATE_BONDING].reset(); + + g_variant_unref(reply); } bool BluetoothAdapter::setupAgent(const char *agent) { - if(!agent) { - LoggerE("Invalid agent path"); - return false; - } - - LoggerD("entered: registering agent " << agent); - - GError *err = NULL; - - mAgentIfaceVTable.method_call = BluetoothAdapter::agentHandleMethodCall; - mAgentIntrospectionData = g_dbus_node_info_new_for_xml(AGENT_INTERFACE_XML, NULL); - - if (mAgentIntrospectionData == NULL) { - LoggerD("failed to create introspection data."); - return false; - } - LoggerD("introspection data parsed OK"); - - if(mAgentRegistrationId > 0) { // already registered - LoggerD("Bluez agent for pairing already registered ... possibly not Released after previous pairing"); - - // unregister Agent - bool unregistered = g_dbus_connection_unregister_object(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), mAgentRegistrationId); - if(unregistered) - mAgentRegistrationId = -1; - } - - mAgentRegistrationId = g_dbus_connection_register_object( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - agent, - mAgentIntrospectionData->interfaces[0], - &mAgentIfaceVTable, //const GDBusInterfaceVTable *vtable, - this, //user_data - NULL, //GDestroyNotify - &err); - - if(err) { - LoggerD("Failed to register object: " << agent << " : " << err->message); - g_error_free(err); - return false; - } - LoggerD("object registered with id=" << mAgentRegistrationId); - - return true; + GVariant *reply; + + if(!agent) + { + LoggerE("Invalid agent path"); + return false; + } + + GError *err = NULL; + + if(mAgentRegistrationId > 0) // already registered + { + LoggerE("Bluez agent for pairing already registered ... possibly not Released after previous pairing"); + + // unregister Agent + bool unregistered = g_dbus_connection_unregister_object(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), mAgentRegistrationId); + if(unregistered) + mAgentRegistrationId = -1; + } + + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), + BLUEZ_SERVICE, + "/org/bluez", + "org.bluez.AgentManager1", + "RegisterAgent", + g_variant_new("(ss)", agent, ""), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err) + { + LoggerE("Failed to register object: " << agent << " : " << err->message); + g_error_free(err); + return false; + } + + + GVariant *value; + g_variant_get(reply, "(i)", &value); + mAgentRegistrationId = g_variant_get_int16(value); + + LoggerE("object registered with id=" << mAgentRegistrationId); + + return true; } void BluetoothAdapter::agentHandleMethodCall( GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - LoggerD("entered\n\tsender=" << sender << "\n\tobject_path=" << object_path << "\n\tinterface_name=" << interface_name << "\n\tmethod_name=" << method_name); - - BluetoothAdapter *ctx = static_cast(user_data); - if(!ctx) { - LoggerD("Failed to cast to BluetoothAdapter"); - g_dbus_method_invocation_return_value(invocation, NULL); - return; - } - - if(!strcmp(method_name, "Authorize")) { - g_dbus_method_invocation_return_value(invocation, NULL); - } - else if(!strcmp(method_name, "RequestPinCode")) { - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", PINCODE)); - } - else if(!strcmp(method_name, "RequestPasskey")) { - g_dbus_method_invocation_return_value(invocation, g_variant_new("(u)", PASSKEY)); - } - else if (!strcmp(method_name, "Release")) { - if(!strcmp(object_path, AGENT_PATH)) { // released agent for pairing - bool unregistered = g_dbus_connection_unregister_object(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), ctx->mAgentRegistrationId); - if(unregistered) - ctx->mAgentRegistrationId = -1; - } - g_dbus_method_invocation_return_value(invocation, NULL); - } - else { - // DisplayPasskey, DisplayPinCode, RequestConfirmation, ConfirmModeChange, Cancel - g_dbus_method_invocation_return_value(invocation, NULL); - } + + LoggerD("entered\n\tsender=" << sender << "\n\tobject_path=" << object_path << "\n\tinterface_name=" << interface_name << "\n\tmethod_name=" << method_name); + + BluetoothAdapter *ctx = static_cast(user_data); + if(!ctx) + { + LoggerD("Failed to cast to BluetoothAdapter"); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + + if(!strcmp(method_name, "Authorize")) + { + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if(!strcmp(method_name, "RequestPinCode")) + { + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", PINCODE)); + } + else if(!strcmp(method_name, "RequestPasskey")) + { + g_dbus_method_invocation_return_value(invocation, g_variant_new("(u)", PASSKEY)); + } + else if (!strcmp(method_name, "Release")) + { + if(!strcmp(object_path, AGENT_PATH)) // released agent for pairing + { + bool unregistered = g_dbus_connection_unregister_object(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), ctx->mAgentRegistrationId); + if(unregistered) + ctx->mAgentRegistrationId = -1; + } + g_dbus_method_invocation_return_value(invocation, NULL); + } + else + { + // DisplayPasskey, DisplayPinCode, RequestConfirmation, ConfirmModeChange, Cancel + g_dbus_method_invocation_return_value(invocation, NULL); + } } -bool BluetoothAdapter::isDevicePaired(const char *device) { - if(!device) - return false; - - // get device properties and check if it's Paired - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - device, - BLUEZ_DEVICE_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - return false; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - bool paired = false; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Paired")) { - paired = g_variant_get_boolean(value); - break; - } - } - - g_variant_unref(reply); - - return paired; +bool BluetoothAdapter::isDevicePaired(const char *device) +{ + + if(!device) + return false; + + // get device properties and check if it's Paired + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + device, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Device1", "Paired"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) + { + if(err) + g_error_free(err); + return false; + } + + bool paired = false; + GVariant *value; + g_variant_get(reply, "(v)", &value); + paired = g_variant_get_boolean(value); + + g_variant_unref(reply); + + return paired; } -bool BluetoothAdapter::getDeviceInfoByAddress(bt_device_info_s *deviceInfo, const char *address) { - - // to assure that when leaving the method, these fields - // will be either set/allocated, or NULL - deviceInfo->remote_name = NULL; - deviceInfo->remote_address = NULL; - deviceInfo->service_uuid = NULL; - deviceInfo->service_count = 0; - - if(!deviceInfo || !address) - return false; - - if(!mAdapterPath) - return false; - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "FindDevice", - g_variant_new("(s)", address), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - - if(err || !reply) { - LoggerE("Failed to find " << address << " device: " << (err?err->message:"Invalid reply")); - if(err) - g_error_free(err); - return false; - } - - bool success = false; - const char *device = NULL; - g_variant_get(reply, "(o)", &device); - if(device) { - success = getDeviceInfo(deviceInfo, device); - } - - g_variant_unref(reply); - - return success; +bool BluetoothAdapter::getDeviceInfoByAddress(bt_device_info_s *deviceInfo, const char *address) +{ + + // to assure that when leaving the method, these fields + // will be either set/allocated, or NULL + deviceInfo->remote_name = NULL; + deviceInfo->remote_address = NULL; + deviceInfo->service_uuid = NULL; + deviceInfo->service_count = 0; + + if(!deviceInfo || !address) + return false; + + if(!mAdapterPath) + return false; + + std::string addressStr = std::string(address); + char* device = getDeviceFromAddress(addressStr); + + if(!device) + { + LoggerE("Failed to find " << address << " device: trying again"); + return false; + } + + bool success = false; + + if(device) + { + success = getDeviceInfo(deviceInfo, device); + } + + return success; } // don't forget to free memory of remote_name and remote_address -bool BluetoothAdapter::getDeviceInfo(bt_device_info_s *deviceInfo, const char *device) { - - // to assure that when leaving the method, these fields - // will be either set/allocated, or NULL - deviceInfo->remote_name = NULL; - deviceInfo->remote_address = NULL; - deviceInfo->service_uuid = NULL; - deviceInfo->service_count = 0; - - if(!deviceInfo || !device) - return false; - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - device, - BLUEZ_DEVICE_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - LoggerE("Failed to 'GetProperties': " << err->message); - if(err) - g_error_free(err); - return false; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - //LoggerD("KEY: " << key); - if(!strcmp(key, "Name")) { - const char *name = g_variant_get_string(value, NULL); - deviceInfo->remote_name = strdup(name); - } - else if(!strcmp(key, "Address")) { - const char *address = g_variant_get_string(value, NULL); - deviceInfo->remote_address = strdup(address); - } - else if(!strcmp(key, "Paired")) { - deviceInfo->is_bonded = g_variant_get_boolean(value); - } - else if(!strcmp(key, "Connected")) { - deviceInfo->is_connected = g_variant_get_boolean(value); - } - else if(!strcmp(key, "Trusted")) { - deviceInfo->is_authorized = g_variant_get_boolean(value); - } - else if(!strcmp(key, "Class")) { - guint32 _class = g_variant_get_uint32(value); - uint8_t minor = _class & 0xff; - uint8_t major = (_class >> 8) & 0xff; - deviceInfo->bt_class.minor_device_class = (bt_minor_device_class_e) minor; - deviceInfo->bt_class.major_device_class = (bt_major_device_class_e) major; - //deviceInfo->bt_class.major_service_class_mask = - } - else if(!strcmp(key, "UUIDs")) { - GVariantIter *iter; - const char *uuid = NULL; - g_variant_get(value, "as", &iter); - deviceInfo->service_count = g_variant_iter_n_children(iter); - deviceInfo->service_uuid = (char**)malloc(deviceInfo->service_count*sizeof(char*)); - char **uuids = deviceInfo->service_uuid; // make a copy of ptr, since we will modify the pointer - while(g_variant_iter_next(iter, "s", &uuid)) { - *uuids++ = uuid?strdup(uuid):NULL; - } - } - } - - g_variant_unref(reply); - - return true; +bool BluetoothAdapter::getDeviceInfo(bt_device_info_s *deviceInfo, const char *device) +{ + + // to assure that when leaving the method, these fields + // will be either set/allocated, or NULL + deviceInfo->remote_name = NULL; + deviceInfo->remote_address = NULL; + deviceInfo->service_uuid = NULL; + deviceInfo->service_count = 0; + + if(!deviceInfo || !device) + return false; + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + device, + "org.freedesktop.DBus.Properties", + "GetAll", + g_variant_new("(s)", "org.bluez.Device1"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) + { + LoggerE("Failed to 'GetAll': " << err->message); + if(err) + g_error_free(err); + return false; + } + + GVariantIter *iter; + g_variant_get(reply, "(a{sv})", &iter); + const char *key; + GVariant *value; + while(g_variant_iter_next(iter, "{sv}", &key, &value)) + { + //LoggerD("KEY: " << key); + if(!strcmp(key, "Name")) + { + const char *name = g_variant_get_string(value, NULL); + deviceInfo->remote_name = strdup(name); + } + else if(!strcmp(key, "Address")) + { + const char *address = g_variant_get_string(value, NULL); + deviceInfo->remote_address = strdup(address); + } + else if(!strcmp(key, "Paired")) + { + deviceInfo->is_bonded = g_variant_get_boolean(value); + } + else if(!strcmp(key, "Connected")) + { + deviceInfo->is_connected = g_variant_get_boolean(value); + } + else if(!strcmp(key, "Trusted")) + { + deviceInfo->is_authorized = g_variant_get_boolean(value); + } + else if(!strcmp(key, "Class")) + { + guint32 _class = g_variant_get_uint32(value); + uint8_t minor = _class & 0xff; + uint8_t major = (_class >> 8) & 0xff; + deviceInfo->bt_class.minor_device_class = (bt_minor_device_class_e) minor; + deviceInfo->bt_class.major_device_class = (bt_major_device_class_e) major; + //deviceInfo->bt_class.major_service_class_mask = + } + else if(!strcmp(key, "UUIDs")) + { + GVariantIter *iter; + const char *uuid = NULL; + g_variant_get(value, "as", &iter); + deviceInfo->service_count = g_variant_iter_n_children(iter); + deviceInfo->service_uuid = (char**)malloc(deviceInfo->service_count*sizeof(char*)); + char **uuids = deviceInfo->service_uuid; // make a copy of ptr, since we will modify the pointer + while(g_variant_iter_next(iter, "s", &uuid)) + { + *uuids++ = uuid?strdup(uuid):NULL; + } + } + } + + g_variant_unref(reply); + + return true; } // frees allocated memory by its members // Doesn't free/delete deviceInfo itself -void BluetoothAdapter::freeDeviceInfo(bt_device_info_s *deviceInfo) { - if(!deviceInfo) - return; - - free(deviceInfo->remote_address); - free(deviceInfo->remote_name); - for(int i=0; iservice_count; i++) { - free(deviceInfo->service_uuid[i]); - } - free(deviceInfo->service_uuid); +void BluetoothAdapter::freeDeviceInfo(bt_device_info_s *deviceInfo) +{ + + if(!deviceInfo) + return; + + free(deviceInfo->remote_address); + free(deviceInfo->remote_name); + for(int i=0; iservice_count; i++) + { + free(deviceInfo->service_uuid[i]); + } + free(deviceInfo->service_uuid); } // frees allocated memory by its members // Doesn't free/delete discoveryInfo itself -void BluetoothAdapter::freeDiscoveryInfo(bt_adapter_device_discovery_info_s *discoveryInfo) { - if(!discoveryInfo) - return; - - free(discoveryInfo->remote_address); - free(discoveryInfo->remote_name); - for(int i=0; iservice_count; i++) { - free(discoveryInfo->service_uuid[i]); - } - free(discoveryInfo->service_uuid); +void BluetoothAdapter::freeDiscoveryInfo(bt_adapter_device_discovery_info_s *discoveryInfo) +{ + + if(!discoveryInfo) + return; + + free(discoveryInfo->remote_address); + free(discoveryInfo->remote_name); + for(int i=0; iservice_count; i++) + { + free(discoveryInfo->service_uuid[i]); + } + free(discoveryInfo->service_uuid); } -bool BluetoothAdapter::removeDevice(const char *address) { - if(!address) - return false; - - if(!mAdapterPath) - return false; - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "FindDevice", - g_variant_new("(s)", address), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - LoggerE("Failed to find " << address << " device: " << err->message); - if(err) - g_error_free(err); - - return false; - } - - const char *device = NULL; - g_variant_get(reply, "(o)", &device); - - // now we can remove the device - bool success = true; - if(device) { - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - mAdapterPath, - BLUEZ_ADAPTER_IFACE, - "RemoveDevice", - g_variant_new("(o)", device), // floating variants are consumed - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err) { - LoggerE("Failed to 'RemoveDevice': " << err->message); - g_error_free(err); - success = false; - } - } - - g_variant_unref(reply); - - return success; +bool BluetoothAdapter::removeDevice(const char *address) +{ + + if(!address) + return false; + + if(!mAdapterPath) + return false; + + std::string addressStr = std::string(address); + char* device = getDeviceFromAddress(addressStr); + + if(!device) + { + LoggerE("Failed to find " << address << " device:"); + return false; + } + + // now we can remove the device + + GError *err = NULL; + bool success = true; + if(device) + { + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + mAdapterPath, + BLUEZ_ADAPTER_IFACE, + "RemoveDevice", + g_variant_new("(o)", device), // floating variants are consumed + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + if(err) + { + LoggerE("Failed to 'RemoveDevice': " << err->message); + g_error_free(err); + success = false; + } + } + + LoggerD("removed device : " << device); + + return success; } // CONNMAN -char *BluetoothAdapter::getBluetoothTechnology() { - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), - CONNMAN_SERVICE, - "/", - CONNMAN_MANAGER_IFACE, - "GetTechnologies", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - - if(err || !reply) { - LoggerE("Failed to call 'GetTechnologies' DBUS method: " << (err?err->message:"reply is null")); - if(err) - g_error_free(err); - return NULL; - } - - char *technology = NULL, *result = NULL; - GVariantIter *props = NULL; - GVariantIter *technologies = NULL; - g_variant_get(reply, "(a(oa{sv}))", &technologies); - while(g_variant_iter_next(technologies, "(oa{sv})", &technology, &props)) { - if(technology && strstr(technology, "bluetooth")) { - result = strdup(technology); - /* - // get the current Powered state - const char *key; - GVariant *value; - while(g_variant_iter_next(props, "{sv}", &key, &value)) { - if(!strcmp(key, "Powered")) { - bool powered = g_variant_get_boolean(value); - mEnabled = powered; - LoggerD("Bluetooth is initially Powered " << (powered?"ON":"OFF")); - break; - } - } - */ - break; - } - } - - g_variant_unref(reply); - return result; +char *BluetoothAdapter::getBluetoothTechnology() +{ + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), + CONNMAN_SERVICE, + "/", + CONNMAN_MANAGER_IFACE, + "GetTechnologies", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) + { + LoggerE("Failed to call 'GetTechnologies' DBUS method: " << (err?err->message:"reply is null")); + if(err) + g_error_free(err); + return NULL; + } + + char *technology = NULL, *result = NULL; + GVariantIter *props = NULL; + GVariantIter *technologies = NULL; + g_variant_get(reply, "(a(oa{sv}))", &technologies); + while(g_variant_iter_next(technologies, "(oa{sv})", &technology, &props)) + { + if(technology && strstr(technology, "bluetooth")) + { + result = strdup(technology); + /* + // get the current Powered state + const char *key; + GVariant *value; + while(g_variant_iter_next(props, "{sv}", &key, &value)) { + if(!strcmp(key, "Powered")) { + bool powered = g_variant_get_boolean(value); + mEnabled = powered; + LoggerD("Bluetooth is initially Powered " << (powered?"ON":"OFF")); + break; + } + } + */ + break; + } + } + + g_variant_unref(reply); + LoggerD("getTech result = " << result); + return result; } -bool BluetoothAdapter::setBluetoothPowered(bool value) { - if(mBluetoothTechnology) { - GError *err = NULL; - g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), - CONNMAN_SERVICE, - mBluetoothTechnology, - CONNMAN_TECHNOLOGY_IFACE, - "SetProperty", - g_variant_new ("(sv)", // floating parameters are consumed, no cleanup/unref needed - "Powered", - g_variant_new_boolean(value) - ), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - - if(err) { - if((value && strstr(err->message, "Already enabled")) || // it's not an error, 'casue the BT is already Powered ON - (!value && strstr(err->message, "Already disabled"))) // it's not an error, 'cause the BT is already Powered OFF - { - g_error_free(err); - return true; - } - LoggerE("Failed to call \"SetProperty\" DBUS method: " << err->message); - g_error_free(err); - return false; - } - - return true; - } - - return false; +bool BluetoothAdapter::setBluetoothPowered(bool value) +{ + + if(mBluetoothTechnology) + { + GError *err = NULL; + g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), + CONNMAN_SERVICE, + mBluetoothTechnology, + CONNMAN_TECHNOLOGY_IFACE, + "SetProperty", + g_variant_new ("(sv)", // floating parameters are consumed, no cleanup/unref needed + "Powered", + g_variant_new_boolean(value) + ), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err) + { + if((value && strstr(err->message, "Already enabled")) || // it's not an error, 'casue the BT is already Powered ON + (!value && strstr(err->message, "Already disabled"))) // it's not an error, 'cause the BT is already Powered OFF + { + g_error_free(err); + return true; + } + LoggerE("Failed to call \"SetProperty\" DBUS method: " << err->message); + g_error_free(err); + return false; + } + + return true; + } + + return false; } } // Bluetooth diff --git a/src/BluetoothAdapter.h b/src/BluetoothAdapter.h index 2c11d30..3e5d0c1 100644 --- a/src/BluetoothAdapter.h +++ b/src/BluetoothAdapter.h @@ -106,6 +106,7 @@ private: // BLUEZ gchar* getDefaultAdapter() const; + gchar* getDeviceFromAddress(std::string &address) const; bool isAdapterPowered(); bool isDevicePaired(const char *device); bool setAdapterPowered(bool value); @@ -144,14 +145,8 @@ private: // checks whther a device given by its MAC address is in the list, or not bool isDeviceInList(std::vector list, const char *address); - //static void onStateChangedCB(int result, bt_adapter_state_e adapterState, void *userData); - //static void onNameChangedCB(char *name, void *userData); - //static void onVisibilityChangedCB(int result, bt_adapter_visibility_mode_e visibilityMode, void *userData); - //static void onDiscoveryStateChangedCB(int result, bt_adapter_device_discovery_state_e discoveryState, - // bt_adapter_device_discovery_info_s *discoveryInfo, void *userData); - static bool foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData); - //static void onBondCreatedCB(int result, bt_device_info_s *deviceInfo, void *userData); - //static void onBondDestroyedCB(int result, char *remoteAddress, void *userData); + static bool foreachBondedDevicesCB(bt_device_info_s *deviceInfo, void *userData, char *devicePath); + static void onSocketConnected(int result, bt_socket_connection_state_e state, bt_socket_connection_s *connection, void *userData); static void onSocketReceivedCB(bt_socket_received_data_s *data, void *userData); @@ -171,7 +166,6 @@ private: ConnReqMultiMapT mConnReqMap; RegisteredUUIDMapT mRegisteredUUID; ConnectedSocketMapT mConnectedSocket; - //bool mRequestedState; std::string mRequestedName; bt_adapter_visibility_mode_e mRequestedVisibility; std::string mCreateBondingAddress; diff --git a/src/BluetoothDevice.cpp b/src/BluetoothDevice.cpp index 4f97bbb..830c13f 100644 --- a/src/BluetoothDevice.cpp +++ b/src/BluetoothDevice.cpp @@ -28,295 +28,402 @@ //BLUEZ #define BLUEZ_PREFIX "org.bluez" #define BLUEZ_SERVICE BLUEZ_PREFIX -#define BLUEZ_MANAGER_IFACE BLUEZ_PREFIX ".Manager" -#define BLUEZ_ADAPTER_IFACE BLUEZ_PREFIX ".Adapter" -#define BLUEZ_DEVICE_IFACE BLUEZ_PREFIX ".Device" +#define BLUEZ_ADAPTER_IFACE BLUEZ_PREFIX ".Adapter1" +#define BLUEZ_DEVICE_IFACE BLUEZ_PREFIX ".Device1" //BLUEZ using namespace DeviceAPI::Common; -namespace DeviceAPI { -namespace Bluetooth { +namespace DeviceAPI +{ +namespace Bluetooth +{ -BluetoothDevice::BluetoothDevice(bt_adapter_device_discovery_info_s *discoveryInfo) +BluetoothDevice::BluetoothDevice(bt_adapter_device_discovery_info_s *discoveryInfo, char *devicePath) { - mName = std::string(discoveryInfo->remote_name); - mAddress = std::string(discoveryInfo->remote_address); - mDeviceClass = BluetoothClassSharedPtr(new BluetoothClass(discoveryInfo->bt_class)); - for(int i = 0; i < discoveryInfo->service_count; i++) { - mUUIDs.push_back(std::string(discoveryInfo->service_uuid[i])); - } - isUpdated = true; + mName = std::string(discoveryInfo->remote_name); + mAddress = std::string(discoveryInfo->remote_address); + mDevicePath = devicePath?strdup(devicePath):NULL; + mDeviceClass = BluetoothClassSharedPtr(new BluetoothClass(discoveryInfo->bt_class)); + for(int i = 0; i < discoveryInfo->service_count; i++) + { + mUUIDs.push_back(std::string(discoveryInfo->service_uuid[i])); + } + isUpdated = true; } -BluetoothDevice::BluetoothDevice(bt_device_info_s *deviceInfo) +BluetoothDevice::BluetoothDevice(bt_device_info_s *deviceInfo, char *devicePath) { - mName = std::string(deviceInfo->remote_name); - mAddress = std::string(deviceInfo->remote_address); - mDeviceClass = BluetoothClassSharedPtr(new BluetoothClass(deviceInfo->bt_class)); - for(int i = 0; i < deviceInfo->service_count; i++) { - mUUIDs.push_back(std::string(deviceInfo->service_uuid[i])); - } - isUpdated = true; + mName = std::string(deviceInfo->remote_name); + mAddress = std::string(deviceInfo->remote_address); + mDevicePath = devicePath?strdup(devicePath):NULL; + mDeviceClass = BluetoothClassSharedPtr(new BluetoothClass(deviceInfo->bt_class)); + for(int i = 0; i < deviceInfo->service_count; i++) + { + mUUIDs.push_back(std::string(deviceInfo->service_uuid[i])); + } + isUpdated = true; } BluetoothDevice::~BluetoothDevice() { - BluetoothAdapter::getInstance()->removeConnReq(mAddress); + BluetoothAdapter::getInstance()->removeConnReq(mAddress); + delete mDevicePath; } void BluetoothDevice::updateInfo(bt_device_info_s *deviceInfo) { - mName = std::string(deviceInfo->remote_name); - mUUIDs.clear(); - for(int i = 0; i < deviceInfo->service_count; i++) { - mUUIDs.push_back(std::string(deviceInfo->service_uuid[i])); - } - isUpdated = true; + mName = std::string(deviceInfo->remote_name); + mUUIDs.clear(); + for(int i = 0; i < deviceInfo->service_count; i++) + { + mUUIDs.push_back(std::string(deviceInfo->service_uuid[i])); + } + isUpdated = true; } std::string BluetoothDevice::getName() const { - return mName; + return mName; } std::string BluetoothDevice::getAddress() const { - return mAddress; + return mAddress; } JSValueRef BluetoothDevice::getDeviceClass(JSContextRef context) { - return JSBluetoothClass::createJSObject(context, mDeviceClass); + return JSBluetoothClass::createJSObject(context, mDeviceClass); } gchar* BluetoothDevice::getDefaultAdapter() const { - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - "/", - BLUEZ_MANAGER_IFACE, - "DefaultAdapter", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) { - LoggerE("Failed to get default adapter: " << err->message); - g_error_free(err); - } - if(!reply) - LoggerE("Reply from 'DefaultAdapter' is null"); - return NULL; - } - - char *adapter = NULL; - g_variant_get(reply, "(o)", &adapter); - - // make a copy of adapter, 'cause it will be destroyed when 'reply' is un-refed - char *result = adapter?strdup(adapter):NULL; - - g_variant_unref(reply); - - return result; + char *result; + bool done = false; + + GError * error = nullptr; + GDBusProxy * managerProxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.bluez", + "/", + "org.freedesktop.DBus.ObjectManager", + nullptr,&error); + if(error) + { + LoggerE("could not create ObjManager proxy"); + // DebugOut(DebugOut::Error)<<"Could not create ObjectManager proxy for Bluez: "<message<message<message<message<message:"Invalid reply")); - if(err) - g_error_free(err); - free(adapter); - return NULL; - } - - char *device = NULL; - g_variant_get(reply, "(o)", &device); - - // make a copy of adapter, 'cause it will be destroyed when 'reply' is un-refed - char *result = device?strdup(device):NULL; - - g_variant_unref(reply); - free(adapter); - - return result; + if(!strcmp(mAddress.c_str(), "")) + { + LoggerE("Invalid address"); + return NULL; + } + + char *device = deviceFromAddress(); + char *result = device?strdup(device):NULL; + /* + char *adapter = getDefaultAdapter(); + if(!adapter) { + LoggerE("Failed to get default adapter"); + return NULL; + } + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + adapter, + BLUEZ_ADAPTER_IFACE, + "FindDevice", + g_variant_new("(s)", mAddress.c_str()), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) { + //LoggerE("Failed to find " << mAddress << " device: " << (err?err->message:"Invalid reply")); + if(err) + g_error_free(err); + free(adapter); + return NULL; + } + + char *device = NULL; + g_variant_get(reply, "(o)", &device); + + // make a copy of adapter, 'cause it will be destroyed when 'reply' is un-refed + char *result = device?strdup(device):NULL; + + g_variant_unref(reply); + free(adapter); + */ + return result; } bool BluetoothDevice::isBonded() const { - char *device = getDevice(); - if(!device) { - //LoggerE("Failed to get device object"); - return false; - } - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - device, - BLUEZ_DEVICE_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - - free(device); - return false; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - bool paired = false; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Paired")) { - paired = g_variant_get_boolean(value); - break; - } - } - - g_variant_unref(reply); - free(device); - - return paired; + char *device = getDevice(); + if(!device) + { + return false; + } + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + device, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Device1", "Paired"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) + { + if(err) + g_error_free(err); + return false; + } + + bool paired = false; + GVariant *value; + g_variant_get(reply, "(v)", &value); + paired = g_variant_get_boolean(value); + + g_variant_unref(reply); + + return paired; } bool BluetoothDevice::isTrusted() const { - char *device = getDevice(); - if(!device) { - //LoggerE("Failed to get device object"); - return false; - } - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - device, - BLUEZ_DEVICE_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - - free(device); - return false; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - bool trusted = false; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Trusted")) { - trusted = g_variant_get_boolean(value); - break; - } - } - - g_variant_unref(reply); - free(device); - - return trusted; + char *device = getDevice(); + if(!device) + { + //LoggerE("Failed to get device object"); + return false; + } + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + device, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Device1", "Trusted"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) + { + if(err) + g_error_free(err); + return false; + } + + bool trusted = false; + GVariant *value; + g_variant_get(reply, "(v)", &value); + trusted = g_variant_get_boolean(value); + + g_variant_unref(reply); + + free(device); + + return trusted; } bool BluetoothDevice::isConnected() const { - char *device = getDevice(); - if(!device) { - //LoggerE("Failed to get device object"); - return false; - } - - GError *err = NULL; - GVariant *reply = NULL; - reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), - BLUEZ_SERVICE, - device, - BLUEZ_DEVICE_IFACE, - "GetProperties", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - if(err || !reply) { - if(err) - g_error_free(err); - - free(device); - return false; - } - - GVariantIter *iter; - g_variant_get(reply, "(a{sv})", &iter); - const char *key; - GVariant *value; - bool connected = false; - while(g_variant_iter_next(iter, "{sv}", &key, &value)) { - if(!strcmp(key, "Connected")) { - connected = g_variant_get_boolean(value); - break; - } - } - - g_variant_unref(reply); - free(device); - - return connected; + char *device = getDevice(); + if(!device) + { + return false; + } + + GError *err = NULL; + GVariant *reply = NULL; + reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL), + BLUEZ_SERVICE, + device, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "org.bluez.Device1", "Connected"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if(err || !reply) + { + if(err) + g_error_free(err); + return false; + } + + bool connected = false; + GVariant *value; + g_variant_get(reply, "(v)", &value); + connected = g_variant_get_boolean(value); + + g_variant_unref(reply); + free(device); + + return connected; } JSValueRef BluetoothDevice::getUUIDs(JSContextRef context) { - return JSUtil::toJSValueRef(context, mUUIDs); + return JSUtil::toJSValueRef(context, mUUIDs); } } // Bluetooth diff --git a/src/BluetoothDevice.h b/src/BluetoothDevice.h index 86429ac..92670b4 100644 --- a/src/BluetoothDevice.h +++ b/src/BluetoothDevice.h @@ -34,13 +34,14 @@ namespace Bluetooth { class BluetoothDevice { public: - BluetoothDevice(bt_adapter_device_discovery_info_s *discoveryInfo); - BluetoothDevice(bt_device_info_s *deviceInfo); + BluetoothDevice(bt_adapter_device_discovery_info_s *discoveryInfo, char *devicePath = NULL); + BluetoothDevice(bt_device_info_s *deviceInfo, char *devicePath = NULL); virtual ~BluetoothDevice(); void updateInfo(bt_device_info_s *deviceInfo); std::string getName() const; std::string getAddress() const; + char* getDevicePath() const {return mDevicePath;} JSValueRef getDeviceClass(JSContextRef context); bool isBonded() const; bool isTrusted() const; @@ -49,14 +50,15 @@ public: private: char *getDefaultAdapter() const; + char *deviceFromAddress() const; char *getDevice() const; private: std::string mName; std::string mAddress; + char *mDevicePath; BluetoothClassSharedPtr mDeviceClass; std::vector mUUIDs; - //Common::PropertyBag mLocalProperty; bool isUpdated; };