Updated this component to use Bluez 5 API calls. This fixes TIVI-2936 65/18665/2 accepted/tizen_ivi accepted/tizen_ivi_panda accepted/tizen_ivi_release tizen_ivi_release accepted/tizen/ivi/20140327.195149 accepted/tizen/ivi/panda/20140327.194411 accepted/tizen/ivi/release/20140404.171137 submit/tizen/20140327.185723 submit/tizen_ivi_release/20140404.164849 submit/tizen_ivi_release/20140404.165114
authorbrianjjones <brian.j.jones@intel.com>
Thu, 27 Mar 2014 18:29:29 +0000 (11:29 -0700)
committerbrianjjones <brian.j.jones@intel.com>
Thu, 27 Mar 2014 18:46:00 +0000 (11:46 -0700)
Change-Id: Ic4d742717a122d9f570d8b7f2b18b3d588262bf2

packaging/wrt-plugins-tizen-bt.changes
src/BluetoothAdapter.cpp
src/BluetoothAdapter.h
src/BluetoothDevice.cpp
src/BluetoothDevice.h

index 56db9d4..6f5d700 100644 (file)
@@ -1,3 +1,7 @@
+* Thu Mar 27 2014 brianjjones <brian.j.jones@intel.com> 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 <brian.j.jones@intel.com> cd7fd57
 - Initial commit for Bluetooth plugin for HTML5 UI
 
index e1a4e8e..72c4e45 100644 (file)
 
 #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                                 \
-    "<node>"                                                \
-    "  <interface name='" BLUEZ_AGENT_IFACE "'>"            \
-    "    <method name='Release'>"                           \
-    "    </method>"                                         \
-    "    <method name='Authorize'>"                         \
-    "      <arg type='o' name='device' direction='in'/>"    \
-    "      <arg type='s' name='uuid' direction='in'/>"      \
-    "    </method>"                                         \
-    "    <method name='RequestPinCode'>"                    \
-    "      <arg type='o' name='device' direction='in'/>"    \
-    "      <arg type='s' name='pincode' direction='out'/>"  \
-    "    </method>"                                         \
-    "    <method name='RequestPasskey'>"                    \
-    "      <arg type='o' name='device' direction='in'/>"    \
-    "      <arg type='u' name='passkey' direction='out'/>"  \
-    "    </method>"                                         \
-    "    <method name='DisplayPasskey'>"                    \
-    "      <arg type='o' name='device' direction='in'/>"    \
-    "      <arg type='u' name='passkey' direction='in'/>"   \
-    "    </method>"                                         \
-    "    <method name='DisplayPinCode'>"                    \
-    "      <arg type='o' name='device' direction='in'/>"    \
-    "      <arg type='s' name='pincode' direction='in'/>"   \
-    "    </method>"                                         \
-    "    <method name='RequestConfirmation'>"               \
-    "      <arg type='o' name='device' direction='in'/>"    \
-    "      <arg type='u' name='passkey' direction='in'/>"   \
-    "    </method>"                                         \
-    "    <method name='ConfirmModeChange'>"                 \
-    "      <arg type='s' name='mode' direction='in'/>"      \
-    "    </method>"                                         \
-    "    <method name='Cancel'>"                            \
-    "    </method>"                                         \
-    "  </interface>"                                        \
-    "</node>"
-
 #define PINCODE        "123456"
 #define PASSKEY         123456
 
 
 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<BluetoothAdapterPtr>(userData);
-    if(!adapter) {
-        LoggerW("userData is NULL");
-        return true;
-    }
-
-    if(deviceInfo == NULL) {
-        LoggerW("deviceInfo is NULL");
-        return true;
-    }
-
-    std::vector<BluetoothDeviceSharedPtr>::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<BluetoothAdapterPtr>(userData);
+       if(!adapter)
+       {
+               LoggerW("userData is NULL");
+               return true;
+       }
+
+       if(deviceInfo == NULL)
+       {
+               LoggerW("deviceInfo is NULL");
+               return true;
+       }
+
+       std::vector<BluetoothDeviceSharedPtr>::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<BluetoothAdapterPtr>(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<int, BluetoothSocketPtr>(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<MultiCallbackUserDataPtr>(iter->second->mUserData);
-
-            if(result == BT_ERROR_NONE) {
-                // Update mConnectedSocket
-                BluetoothSocketPtr socket = new BluetoothSocket(connection);
-                object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(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<BluetoothAdapterPtr>(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<int, BluetoothSocketPtr>(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<MultiCallbackUserDataPtr>(iter->second->mUserData);
+
+                       if(result == BT_ERROR_NONE)
+                       {
+                               // Update mConnectedSocket
+                               BluetoothSocketPtr socket = new BluetoothSocket(connection);
+                               object->mConnectedSocket.insert(std::pair<int, BluetoothSocketPtr>(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<BluetoothAdapterPtr>(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<unsigned long>(data->data_size));
-
-    // Call BluetoothSocket.onmessage
-    MultiCallbackUserDataPtr callback = socket->getOnMessage();
-    if(callback)
-        callback->invokeCallback("onmessage");
+       BluetoothAdapterPtr object = static_cast<BluetoothAdapterPtr>(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<unsigned long>(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(&current , &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(&current , &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<std::string, BluetoothConnReqPtr>(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<std::string, BluetoothConnReqPtr>(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: "<<error->message<<endl;
+               g_error_free(error);
+       }
+
+       GVariant * objectMap = g_dbus_proxy_call_sync(managerProxy, "GetManagedObjects",nullptr, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+       if(error)
+       {
+               LoggerE("failed to get GetManagedObj");
+               //DebugOut(DebugOut::Error)<<"Failed call to GetManagedObjects: "<<error->message<<endl;
+               g_object_unref(managerProxy);
+               g_error_free(error);
+       }
+
+       GVariantIter* iter;
+       char* objPath;
+       GVariantIter* level2Dict;
+
+       g_variant_get(objectMap, "(a{oa{sa{sv}}})",&iter);
+
+       while(g_variant_iter_next(iter, "{oa{sa{sv}}}",&objPath, &level2Dict))
+       {
+               char * interfaceName;
+               GVariantIter* innerDict;
+
+               while(g_variant_iter_next(level2Dict, "{sa{sv}}", &interfaceName, &innerDict))
+               {
+                       if(!strcmp(interfaceName, "org.bluez.Device1"))
+                       {
+                               char* propertyName;
+                               GVariant* value;
+
+                               while(done == false && g_variant_iter_next(innerDict,"{sv}", &propertyName, &value))
+                               {
+
+                                       if(!strcmp(propertyName, "Paired"))
+                                       {
+                                               bool paired = false;
+
+                                               g_variant_get(value,"b",&paired);
+
+                                               if (paired)
+                                               {
+                                                       bt_device_info_s deviceInfo;
+
+                                                       if(getDeviceInfo(&deviceInfo, objPath))
+                                                               foreachBondedDevicesCB(&deviceInfo, this, objPath);
+
+                                                       freeDeviceInfo(&deviceInfo);
+                                               }
+                                       }
+                                       g_free(propertyName);
+                                       g_variant_unref(value);
+                               }
+                       }
+                       g_free(interfaceName);
+                       g_variant_iter_free(innerDict);
+               }
+               g_free(objPath);
+               g_variant_iter_free(level2Dict);
+       }
+       g_variant_iter_free(iter);
+
 }
 
 void BluetoothAdapter::returnDevice(std::string &address, Common::MultiCallbackUserDataPtr userData)
 {
-    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<BluetoothDeviceSharedPtr>::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<BluetoothDeviceSharedPtr>::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<std::string, BluetoothServiceHandlerPtr>(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<std::string, BluetoothServiceHandlerPtr>(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: "<<error->message<<endl;
+               g_error_free(error);
+               return "";
+       }
+
+       GVariant * objectMap = g_dbus_proxy_call_sync(managerProxy, "GetManagedObjects",nullptr, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+       if(error)
+       {
+               LoggerE("failed to get GetManagedObj");
+               //DebugOut(DebugOut::Error)<<"Failed call to GetManagedObjects: "<<error->message<<endl;
+               g_object_unref(managerProxy);
+               g_error_free(error);
+               return "";
+       }
+
+       GVariantIter* iter;
+       char* objPath;
+       GVariantIter* level2Dict;
+
+       g_variant_get(objectMap, "(a{oa{sa{sv}}})",&iter);
+
+       while(g_variant_iter_next(iter, "{oa{sa{sv}}}",&objPath, &level2Dict))
+       {
+               char * interfaceName;
+               GVariantIter* innerDict;
+               while(g_variant_iter_next(level2Dict, "{sa{sv}}", &interfaceName, &innerDict))
+               {
+                       if(!strcmp(interfaceName, "org.bluez.Adapter1"))
+                       {
+                               char* propertyName;
+                               GVariant* value;
+
+                               while(done == false && g_variant_iter_next(innerDict,"{sv}", &propertyName, &value))
+                               {
+                                       if(!strcmp(propertyName, "Address"))
+                                       {
+                                               char* addr;
+                                               g_variant_get(value,"s",&addr);
+
+                                               result = objPath?strdup(objPath):NULL;
+                                               done = true;
+
+                                               g_free(addr);
+                                       }
+                                       g_free(propertyName);
+                                       g_variant_unref(value);
+                               }
+                       }
+                       g_free(interfaceName);
+                       g_variant_iter_free(innerDict);
+               }
+               g_free(objPath);
+               g_variant_iter_free(level2Dict);
+       }
+       g_variant_iter_free(iter);
+
+       return result;
 }
 
-bool BluetoothAdapter::isAdapterPowered() {
-    if(!mAdapterPath)
-        return false;
-
-    // get adapter properties and check if it's Powered
-    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);
-        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::getDeviceFromAddress(std::string &address) const
+{
+       char *result = NULL;
+       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: "<<error->message<<endl;
+               g_error_free(error);
+               return "";
+       }
+
+       GVariant * objectMap = g_dbus_proxy_call_sync(managerProxy, "GetManagedObjects",nullptr, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+       if(error)
+       {
+               LoggerE("failed to get GetManagedObj");
+               //DebugOut(DebugOut::Error)<<"Failed call to GetManagedObjects: "<<error->message<<endl;
+               g_object_unref(managerProxy);
+               g_error_free(error);
+               return "";
+       }
+
+       GVariantIter* iter;
+       char* objPath;
+       GVariantIter* level2Dict;
+
+       g_variant_get(objectMap, "(a{oa{sa{sv}}})",&iter);
+
+       while(g_variant_iter_next(iter, "{oa{sa{sv}}}",&objPath, &level2Dict))
+       {
+               char * interfaceName;
+               GVariantIter* innerDict;
+               while(g_variant_iter_next(level2Dict, "{sa{sv}}", &interfaceName, &innerDict))
+               {
+                       if(!strcmp(interfaceName, "org.bluez.Device1"))
+                       {
+                               char* propertyName;
+                               GVariant* value;
+
+                               while(done == false && g_variant_iter_next(innerDict,"{sv}", &propertyName, &value))
+                               {
+                                       if(!strcmp(propertyName, "Address"))
+                                       {
+                                               char* addr;
+                                               g_variant_get(value,"s",&addr);
+                                               if(addr && std::string(addr) == address)
+                                               {
+
+                                                       result = objPath?strdup(objPath):NULL;
+                                                       done = true;
+                                                       LoggerD("getDeviceFromAddress found : " << result);
+                                               }
+
+                                               g_free(addr);
+                                       }
+                                       g_free(propertyName);
+                                       g_variant_unref(value);
+                               }
+                       }
+                       g_free(interfaceName);
+                       g_variant_iter_free(innerDict);
+               }
+               g_free(objPath);
+               g_variant_iter_free(level2Dict);
+       }
+       g_variant_iter_free(iter);
+
+       return result;
+}
+
+bool BluetoothAdapter::isAdapterPowered()
+{
+
+       if(!mAdapterPath)
+               return false;
+
+       // get adapter properties and check if it's Powered
+       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", "Powered"),
+                                            NULL,
+                                            G_DBUS_CALL_FLAGS_NONE,
+                                            -1,
+                                            NULL,
+                                            &err);
+
+       if(err || !reply)
+       {
+               if(err)
+                       g_error_free(err);
+               return false;
+       }
+
+       bool powered = false;
+       GVariant *value;
+       g_variant_get(reply, "(v)", &value);
+       powered = g_variant_get_boolean(value);
+
+       g_variant_unref(reply);
+
+       return powered;
 }
 
 void BluetoothAdapter::handleSignal(GDBusConnection  *connection,
-                         const gchar      *sender,
-                         const gchar      *object_path,
-                         const gchar      *interface_name,
-                         const gchar      *signal_name,
-                         GVariant         *parameters,
-                         gpointer          user_data)
+                                    const gchar      *sender,
+                                    const gchar      *object_path,
+                                    const gchar      *interface_name,
+                                    const gchar      *signal_name,
+                                    GVariant         *parameters,
+                                    gpointer          user_data)
 {
-    LoggerD("signal received: '" << interface_name << "' -> '" << signal_name << "' -> '" << object_path << "'");
-
-    BluetoothAdapter *ctx = static_cast<BluetoothAdapter*>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<BluetoothAdapter*>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<BluetoothDeviceSharedPtr> 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<BluetoothDeviceSharedPtr> 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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(mChangeListener);
-        if(callback) {
-            JSContextRef context = callback->getContext();
-            JSValueRef value =  JSValueMakeBoolean(context, visible);
-
-            callback->invokeCallback("onvisibilitychanged", value);
-        }
-    }
+       if(mChangeListener != NULL)
+       {
+               MultiCallbackUserDataPtr callback = static_cast<MultiCallbackUserDataPtr>(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<BluetoothAdapter*>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<BluetoothAdapter*>(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<MultiCallbackUserDataPtr>(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<MultiCallbackUserDataPtr>(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<BluetoothAdapter*>(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<BluetoothAdapter*>(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; i<deviceInfo->service_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; i<deviceInfo->service_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; i<discoveryInfo->service_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; i<discoveryInfo->service_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
index 2c11d30..3e5d0c1 100644 (file)
@@ -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<BluetoothDeviceSharedPtr> 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;
index 4f97bbb..830c13f 100644 (file)
 //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: "<<error->message<<endl;
+               g_error_free(error);
+               return "";
+       }
+
+       GVariant * objectMap = g_dbus_proxy_call_sync(managerProxy, "GetManagedObjects",nullptr, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+       if(error)
+       {
+               LoggerE("failed to get GetManagedObj");
+               //DebugOut(DebugOut::Error)<<"Failed call to GetManagedObjects: "<<error->message<<endl;
+               g_object_unref(managerProxy);
+               g_error_free(error);
+               return "";
+       }
+
+       GVariantIter* iter;
+       char* objPath;
+       GVariantIter* level2Dict;
+
+       g_variant_get(objectMap, "(a{oa{sa{sv}}})",&iter);
+
+       while(g_variant_iter_next(iter, "{oa{sa{sv}}}",&objPath, &level2Dict))
+       {
+               char * interfaceName;
+               GVariantIter* innerDict;
+               while(g_variant_iter_next(level2Dict, "{sa{sv}}", &interfaceName, &innerDict))
+               {
+                       if(!strcmp(interfaceName, "org.bluez.Adapter1"))
+                       {
+                               char* propertyName;
+                               GVariant* value;
+
+                               while(done == false && g_variant_iter_next(innerDict,"{sv}", &propertyName, &value))
+                               {
+                                       if(!strcmp(propertyName, "Address"))
+                                       {
+                                               char* addr;
+                                               g_variant_get(value,"s",&addr);
+
+                                               result = objPath?strdup(objPath):NULL;
+                                               done = true;
+
+                                               g_free(addr);
+                                       }
+                                       g_free(propertyName);
+                                       g_variant_unref(value);
+                               }
+                       }
+                       g_free(interfaceName);
+                       g_variant_iter_free(innerDict);
+               }
+               g_free(objPath);
+               g_variant_iter_free(level2Dict);
+       }
+       g_variant_iter_free(iter);
+
+       return result;
+}
+
+char* BluetoothDevice::deviceFromAddress() const
+{
+       char *result = NULL;
+       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: "<<error->message<<endl;
+               g_error_free(error);
+               return "";
+       }
+
+       GVariant * objectMap = g_dbus_proxy_call_sync(managerProxy, "GetManagedObjects",nullptr, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+       if(error)
+       {
+               LoggerE("failed to get GetManagedObj");
+               //DebugOut(DebugOut::Error)<<"Failed call to GetManagedObjects: "<<error->message<<endl;
+               g_object_unref(managerProxy);
+               g_error_free(error);
+               return "";
+       }
+
+       GVariantIter* iter;
+       char* objPath;
+       GVariantIter* level2Dict;
+
+       g_variant_get(objectMap, "(a{oa{sa{sv}}})",&iter);
+
+       while(g_variant_iter_next(iter, "{oa{sa{sv}}}",&objPath, &level2Dict))
+       {
+               char * interfaceName;
+               GVariantIter* innerDict;
+               while(g_variant_iter_next(level2Dict, "{sa{sv}}", &interfaceName, &innerDict))
+               {
+                       if(!strcmp(interfaceName, "org.bluez.Device1"))
+                       {
+                               char* propertyName;
+                               GVariant* value;
+
+                               while(done == false && g_variant_iter_next(innerDict,"{sv}", &propertyName, &value))
+                               {
+                                       if(!strcmp(propertyName, "Address"))
+                                       {
+                                               char* addr;
+                                               g_variant_get(value,"s",&addr);
+
+                                               if(addr && std::string(addr) == mAddress)
+                                               {
+                                                       result = objPath?strdup(objPath):NULL;
+                                                       done = true;
+                                               }
+
+                                               g_free(addr);
+                                       }
+                                       g_free(propertyName);
+                                       g_variant_unref(value);
+                               }
+                       }
+                       g_free(interfaceName);
+                       g_variant_iter_free(innerDict);
+               }
+               g_free(objPath);
+               g_variant_iter_free(level2Dict);
+       }
+       g_variant_iter_free(iter);
+
+       return result;
 }
 
+
 char *BluetoothDevice::getDevice() const
 {
-    if(!strcmp(mAddress.c_str(), "")) {
-        LoggerE("Invalid address");
-        return 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;
+       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
index 86429ac..92670b4 100644 (file)
@@ -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<std::string> mUUIDs;
-    //Common::PropertyBag mLocalProperty;
     bool isUpdated;
 };