4f97bbbe34f87b828d89498eff9d6fe9dfe12ec8
[profile/ivi/wrt-plugins-ivi-bt.git] / src / BluetoothDevice.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <PlatformException.h>
19 #include <JSUtil.h>
20
21 #include "plugin_config.h"
22 #include "BluetoothDevice.h"
23 #include "BluetoothAdapter.h"
24 #include "JSBluetoothClass.h"
25
26 #include <Logger.h>
27
28 //BLUEZ
29 #define BLUEZ_PREFIX            "org.bluez"
30 #define BLUEZ_SERVICE           BLUEZ_PREFIX
31 #define BLUEZ_MANAGER_IFACE     BLUEZ_PREFIX ".Manager"
32 #define BLUEZ_ADAPTER_IFACE     BLUEZ_PREFIX ".Adapter"
33 #define BLUEZ_DEVICE_IFACE      BLUEZ_PREFIX ".Device"
34 //BLUEZ
35
36 using namespace DeviceAPI::Common;
37
38 namespace DeviceAPI {
39 namespace Bluetooth {
40
41 BluetoothDevice::BluetoothDevice(bt_adapter_device_discovery_info_s *discoveryInfo)
42 {
43     mName = std::string(discoveryInfo->remote_name);
44     mAddress = std::string(discoveryInfo->remote_address);
45     mDeviceClass = BluetoothClassSharedPtr(new BluetoothClass(discoveryInfo->bt_class));
46     for(int i = 0; i < discoveryInfo->service_count; i++) {
47         mUUIDs.push_back(std::string(discoveryInfo->service_uuid[i]));
48     }
49     isUpdated = true;
50 }
51
52 BluetoothDevice::BluetoothDevice(bt_device_info_s *deviceInfo)
53 {
54     mName = std::string(deviceInfo->remote_name);
55     mAddress = std::string(deviceInfo->remote_address);
56     mDeviceClass = BluetoothClassSharedPtr(new BluetoothClass(deviceInfo->bt_class));
57     for(int i = 0; i < deviceInfo->service_count; i++) {
58         mUUIDs.push_back(std::string(deviceInfo->service_uuid[i]));
59     }
60     isUpdated = true;
61 }
62
63 BluetoothDevice::~BluetoothDevice()
64 {
65     BluetoothAdapter::getInstance()->removeConnReq(mAddress);
66 }
67
68 void BluetoothDevice::updateInfo(bt_device_info_s *deviceInfo)
69 {
70     mName = std::string(deviceInfo->remote_name);
71     mUUIDs.clear();
72     for(int i = 0; i < deviceInfo->service_count; i++) {
73         mUUIDs.push_back(std::string(deviceInfo->service_uuid[i]));
74     }
75     isUpdated = true;
76 }
77
78 std::string BluetoothDevice::getName() const
79 {
80     return mName;
81 }
82
83 std::string BluetoothDevice::getAddress() const
84 {
85     return mAddress;
86 }
87
88 JSValueRef BluetoothDevice::getDeviceClass(JSContextRef context)
89 {
90     return JSBluetoothClass::createJSObject(context, mDeviceClass);
91 }
92
93 gchar* BluetoothDevice::getDefaultAdapter() const
94 {
95     GError *err = NULL;
96     GVariant *reply = NULL;
97     reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL),
98                                          BLUEZ_SERVICE,
99                                          "/",
100                                          BLUEZ_MANAGER_IFACE,
101                                          "DefaultAdapter",
102                                          NULL,
103                                          NULL,
104                                          G_DBUS_CALL_FLAGS_NONE,
105                                          -1,
106                                          NULL,
107                                          &err);
108     if(err || !reply) {
109         if(err) {
110             LoggerE("Failed to get default adapter: " << err->message);
111             g_error_free(err);
112         }
113         if(!reply)
114             LoggerE("Reply from 'DefaultAdapter' is null");
115         return NULL;
116     }
117
118     char *adapter = NULL;
119     g_variant_get(reply, "(o)", &adapter);
120
121     // make a copy of adapter, 'cause it will be destroyed when 'reply' is un-refed
122     char *result = adapter?strdup(adapter):NULL;
123
124     g_variant_unref(reply);
125
126     return result;
127 }
128
129 char *BluetoothDevice::getDevice() const
130 {
131     if(!strcmp(mAddress.c_str(), "")) {
132         LoggerE("Invalid address");
133         return NULL;
134     }
135
136     char *adapter = getDefaultAdapter();
137     if(!adapter) {
138         LoggerE("Failed to get default adapter");
139         return NULL;
140     }
141
142     GError *err = NULL;
143     GVariant *reply = NULL;
144     reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL),
145             BLUEZ_SERVICE,
146             adapter,
147             BLUEZ_ADAPTER_IFACE,
148             "FindDevice",
149             g_variant_new("(s)", mAddress.c_str()),
150             NULL,
151             G_DBUS_CALL_FLAGS_NONE,
152             -1,
153             NULL,
154             &err);
155
156     if(err || !reply) {
157         //LoggerE("Failed to find " << mAddress << " device: " << (err?err->message:"Invalid reply"));
158         if(err)
159             g_error_free(err);
160         free(adapter);
161         return NULL;
162     }
163
164     char *device = NULL;
165     g_variant_get(reply, "(o)", &device);
166
167     // make a copy of adapter, 'cause it will be destroyed when 'reply' is un-refed
168     char *result = device?strdup(device):NULL;
169
170     g_variant_unref(reply);
171     free(adapter);
172
173     return result;
174 }
175
176 bool BluetoothDevice::isBonded() const
177 {
178     char *device = getDevice();
179     if(!device) {
180         //LoggerE("Failed to get device object");
181         return false;
182     }
183
184     GError *err = NULL;
185     GVariant *reply = NULL;
186     reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL),
187                                          BLUEZ_SERVICE,
188                                          device,
189                                          BLUEZ_DEVICE_IFACE,
190                                          "GetProperties",
191                                          NULL,
192                                          NULL,
193                                          G_DBUS_CALL_FLAGS_NONE,
194                                          -1,
195                                          NULL,
196                                          &err);
197     if(err || !reply) {
198         if(err)
199             g_error_free(err);
200
201         free(device);
202         return false;
203     }
204
205     GVariantIter *iter;
206     g_variant_get(reply, "(a{sv})", &iter);
207     const char *key;
208     GVariant *value;
209     bool paired = false;
210     while(g_variant_iter_next(iter, "{sv}", &key, &value)) {
211         if(!strcmp(key, "Paired")) {
212             paired = g_variant_get_boolean(value);
213             break;
214         }
215     }
216
217     g_variant_unref(reply);
218     free(device);
219
220     return paired;
221 }
222
223 bool BluetoothDevice::isTrusted() const
224 {
225     char *device = getDevice();
226     if(!device) {
227         //LoggerE("Failed to get device object");
228         return false;
229     }
230
231     GError *err = NULL;
232     GVariant *reply = NULL;
233     reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL),
234                                          BLUEZ_SERVICE,
235                                          device,
236                                          BLUEZ_DEVICE_IFACE,
237                                          "GetProperties",
238                                          NULL,
239                                          NULL,
240                                          G_DBUS_CALL_FLAGS_NONE,
241                                          -1,
242                                          NULL,
243                                          &err);
244     if(err || !reply) {
245         if(err)
246             g_error_free(err);
247
248         free(device);
249         return false;
250     }
251
252     GVariantIter *iter;
253     g_variant_get(reply, "(a{sv})", &iter);
254     const char *key;
255     GVariant *value;
256     bool trusted = false;
257     while(g_variant_iter_next(iter, "{sv}", &key, &value)) {
258         if(!strcmp(key, "Trusted")) {
259             trusted = g_variant_get_boolean(value);
260             break;
261         }
262     }
263
264     g_variant_unref(reply);
265     free(device);
266
267     return trusted;
268 }
269
270 bool BluetoothDevice::isConnected() const
271 {
272     char *device = getDevice();
273     if(!device) {
274         //LoggerE("Failed to get device object");
275         return false;
276     }
277
278     GError *err = NULL;
279     GVariant *reply = NULL;
280     reply = g_dbus_connection_call_sync( g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL),
281                                          BLUEZ_SERVICE,
282                                          device,
283                                          BLUEZ_DEVICE_IFACE,
284                                          "GetProperties",
285                                          NULL,
286                                          NULL,
287                                          G_DBUS_CALL_FLAGS_NONE,
288                                          -1,
289                                          NULL,
290                                          &err);
291     if(err || !reply) {
292         if(err)
293             g_error_free(err);
294
295         free(device);
296         return false;
297     }
298
299     GVariantIter *iter;
300     g_variant_get(reply, "(a{sv})", &iter);
301     const char *key;
302     GVariant *value;
303     bool connected = false;
304     while(g_variant_iter_next(iter, "{sv}", &key, &value)) {
305         if(!strcmp(key, "Connected")) {
306             connected = g_variant_get_boolean(value);
307             break;
308         }
309     }
310
311     g_variant_unref(reply);
312     free(device);
313
314     return connected;
315 }
316
317 JSValueRef BluetoothDevice::getUUIDs(JSContextRef context)
318 {
319     return JSUtil::toJSValueRef(context, mUUIDs);
320 }
321
322 } // Bluetooth
323 } // DeviceAPI
324