Fix the coverity issue (Resource leak)
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-oob.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <glib.h>
25 #include <dlog.h>
26 #include <string.h>
27 #include <gio/gio.h>
28
29 #include "bluetooth-api.h"
30 #include "bt-service-common.h"
31 #include "bt-service-oob.h"
32 #include "bt-service-event.h"
33
34 static int __get_oob_data_from_variant(GVariant *variant,
35                 unsigned char *buf, int size)
36 {
37         int i;
38         unsigned char *v;
39
40         i = g_variant_get_size(variant);
41         v = (unsigned char *)g_variant_get_data(variant);
42         if (i && v) {
43                 i = i > size ? size : i;
44                 memcpy(buf, v, i);
45         }
46
47         return i;
48 }
49
50 int _bt_oob_read_local_data(bt_oob_data_t *local_oob_data)
51 {
52         GDBusProxy *proxy;
53         GVariant *reply;
54         GError *err = NULL;
55         char *adapter_path;
56         GDBusConnection *conn;
57         GVariant *hash192 = NULL;
58         GVariant *randomizer192 = NULL;
59         GVariant *hash256 = NULL;
60         GVariant *randomizer256 = NULL;
61
62         BT_CHECK_PARAMETER(local_oob_data, return);
63
64         conn = _bt_gdbus_get_system_gconn();
65         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
66
67         adapter_path = _bt_get_adapter_path();
68         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
69
70         proxy =  g_dbus_proxy_new_sync(conn,
71                         G_DBUS_PROXY_FLAGS_NONE, NULL,
72                         BT_BLUEZ_NAME, adapter_path,
73                         BT_OOB_INTERFACE, NULL, &err);
74         g_free(adapter_path);
75         if (!proxy) {
76                 BT_ERR("Unable to create proxy");
77                 if (err) {
78                         BT_ERR("Error: %s", err->message);
79                         g_clear_error(&err);
80                 }
81                 return BLUETOOTH_ERROR_INTERNAL;
82         }
83
84         reply = g_dbus_proxy_call_sync(proxy, "ReadLocalData",
85                         NULL,
86                         G_DBUS_CALL_FLAGS_NONE, -1,
87                         NULL, &err);
88         g_object_unref(proxy);
89
90         if (reply == NULL) {
91                 BT_ERR("ReadLocalData dBUS-RPC is failed");
92                 if (err != NULL) {
93                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
94                                         err->code, err->message);
95                         g_clear_error(&err);
96                 }
97                 return BLUETOOTH_ERROR_INTERNAL;
98         }
99
100         g_variant_get(reply, "(@ay@ay@ay@ay)", &hash192, &randomizer192,
101                         &hash256, &randomizer256);
102         g_variant_unref(reply);
103
104         if (hash192) {
105                 local_oob_data->hash_len = __get_oob_data_from_variant(hash192,
106                                 local_oob_data->hash,
107                                 sizeof(local_oob_data->hash));
108                 g_variant_unref(hash192);
109         }
110
111         if (randomizer192) {
112                 local_oob_data->randomizer_len = __get_oob_data_from_variant(randomizer192,
113                                 local_oob_data->randomizer,
114                                 sizeof(local_oob_data->randomizer));
115                 g_variant_unref(randomizer192);
116         }
117
118         if (hash256) {
119                 local_oob_data->hash256_len = __get_oob_data_from_variant(hash256,
120                                 local_oob_data->hash256,
121                                 sizeof(local_oob_data->hash256));
122                 g_variant_unref(hash256);
123         }
124
125         if (randomizer256) {
126                 local_oob_data->randomizer256_len = __get_oob_data_from_variant(randomizer256,
127                                 local_oob_data->randomizer256,
128                                 sizeof(local_oob_data->randomizer256));
129                 g_variant_unref(randomizer256);
130         }
131
132         return BLUETOOTH_ERROR_NONE;
133 }
134
135 int _bt_oob_add_remote_data(
136                         bluetooth_device_address_t *remote_device_address,
137                         bt_oob_data_t *remote_oob_data)
138 {
139         int i;
140         GDBusProxy *proxy;
141         GVariant *reply;
142         GError *err = NULL;
143         char *dev_addr;
144         char *adapter_path;
145         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
146         unsigned char *remote_hash;
147         unsigned char *remote_randomizer;
148         GDBusConnection *conn;
149         GVariantBuilder *builder;
150         GVariantBuilder *builder2;
151         GVariant *hash192;
152         GVariant *randomizer192;
153         GVariant *hash256;
154         GVariant *randomizer256;
155
156         BT_CHECK_PARAMETER(remote_device_address, return);
157         BT_CHECK_PARAMETER(remote_oob_data, return);
158
159         conn = _bt_gdbus_get_system_gconn();
160         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
161
162         adapter_path = _bt_get_adapter_path();
163         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
164
165         _bt_convert_addr_type_to_string(address, remote_device_address->addr);
166
167         proxy =  g_dbus_proxy_new_sync(conn,
168                         G_DBUS_PROXY_FLAGS_NONE, NULL,
169                         BT_BLUEZ_NAME, adapter_path,
170                         BT_OOB_INTERFACE, NULL, &err);
171         g_free(adapter_path);
172         if (!proxy) {
173                 BT_ERR("Unable to create proxy");
174                 if (err) {
175                         BT_ERR("Error: %s", err->message);
176                         g_clear_error(&err);
177                 }
178                 return BLUETOOTH_ERROR_INTERNAL;
179         }
180
181         /* Remote address */
182         dev_addr = g_strdup(address);
183
184         /* P-192 */
185         remote_hash = remote_oob_data->hash;
186         remote_randomizer = remote_oob_data->randomizer;
187
188         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
189         builder2 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
190
191         for (i = 0; i < remote_oob_data->hash_len; i++)
192                 g_variant_builder_add(builder, "y", remote_hash[i]);
193
194         for (i = 0; i < remote_oob_data->randomizer_len; i++)
195                 g_variant_builder_add(builder2, "y", remote_randomizer[i]);
196
197         hash192 = g_variant_new("ay", builder);
198         randomizer192 = g_variant_new("ay", builder2);
199
200         g_variant_builder_unref(builder2);
201         g_variant_builder_unref(builder);
202
203         /* P-256 */
204         remote_hash = remote_oob_data->hash256;
205         remote_randomizer = remote_oob_data->randomizer256;
206
207         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
208         builder2 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
209
210         for (i = 0; i < remote_oob_data->hash256_len; i++)
211                 g_variant_builder_add(builder, "y", remote_hash[i]);
212
213         for (i = 0; i < remote_oob_data->randomizer256_len; i++)
214                 g_variant_builder_add(builder2, "y", remote_randomizer[i]);
215
216         hash256 = g_variant_new("ay", builder);
217         randomizer256 = g_variant_new("ay", builder2);
218
219         g_variant_builder_unref(builder2);
220         g_variant_builder_unref(builder);
221
222         /* Call AddRemoteData Method */
223         reply = g_dbus_proxy_call_sync(proxy, "AddRemoteData",
224                         g_variant_new("(s@ay@ay@ay@ay)", dev_addr,
225                                 hash192, randomizer192, hash256, randomizer256),
226                         G_DBUS_CALL_FLAGS_NONE, -1,
227                         NULL, &err);
228         g_object_unref(proxy);
229         g_free(dev_addr);
230
231         /* Check the reply */
232         if (reply == NULL) {
233                 BT_ERR("AddRemoteData dBUS-RPC is failed");
234                 if (err != NULL) {
235                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
236                                         err->code, err->message);
237                         g_clear_error(&err);
238                 }
239                 return BLUETOOTH_ERROR_INTERNAL;
240         }
241         g_variant_unref(reply);
242
243         return BLUETOOTH_ERROR_NONE;
244 }
245
246 int _bt_oob_remove_remote_data(
247                         bluetooth_device_address_t *remote_device_address)
248 {
249         GDBusProxy *proxy;
250         GVariant *reply;
251         GError *err = NULL;
252         char *dev_addr;
253         char *adapter_path;
254         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
255         GDBusConnection *conn;
256
257         BT_CHECK_PARAMETER(remote_device_address, return);
258
259         conn = _bt_gdbus_get_system_gconn();
260         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
261
262         adapter_path = _bt_get_adapter_path();
263         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
264
265         _bt_convert_addr_type_to_string(address,
266                 remote_device_address->addr);
267
268         proxy =  g_dbus_proxy_new_sync(conn,
269                         G_DBUS_PROXY_FLAGS_NONE, NULL,
270                         BT_BLUEZ_NAME, adapter_path,
271                         BT_OOB_INTERFACE, NULL, &err);
272         g_free(adapter_path);
273         if (!proxy) {
274                 BT_ERR("Unable to create proxy");
275                 if (err) {
276                         BT_ERR("Error: %s", err->message);
277                         g_clear_error(&err);
278                 }
279                 return BLUETOOTH_ERROR_INTERNAL;
280         }
281
282         dev_addr = g_strdup(address);
283
284         /* Call RemoveRemoteData Method*/
285         reply = g_dbus_proxy_call_sync(proxy, "RemoveRemoteData",
286                         g_variant_new("(s)", dev_addr),
287                         G_DBUS_CALL_FLAGS_NONE, -1,
288                         NULL, &err);
289         g_object_unref(proxy);
290         g_free(dev_addr);
291
292         /* Check the reply*/
293         if (reply == NULL) {
294                 BT_ERR("RemoveRemoteData dBUS-RPC is failed");
295                 if (err != NULL) {
296                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
297                                         err->code, err->message);
298                         g_clear_error(&err);
299                 }
300                 return BLUETOOTH_ERROR_INTERNAL;
301         }
302
303         g_variant_unref(reply);
304         return BLUETOOTH_ERROR_NONE;
305 }
306
307 int _bt_le_oob_read_local_data(bt_oob_data_t *local_oob_data)
308 {
309         GDBusProxy *proxy;
310         GVariant *reply;
311         GError *err = NULL;
312         char *adapter_path;
313         GDBusConnection *conn;
314         GVariant *eir = NULL;
315
316         BT_CHECK_PARAMETER(local_oob_data, return);
317
318         conn = _bt_gdbus_get_system_gconn();
319         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
320
321         adapter_path = _bt_get_adapter_path();
322         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
323
324         proxy =  g_dbus_proxy_new_sync(conn,
325                         G_DBUS_PROXY_FLAGS_NONE, NULL,
326                         BT_BLUEZ_NAME, adapter_path,
327                         BT_OOB_INTERFACE, NULL, &err);
328         g_free(adapter_path);
329         if (!proxy) {
330                 BT_ERR("Unable to create proxy");
331                 if (err) {
332                         BT_ERR("Error: %s", err->message);
333                         g_clear_error(&err);
334                 }
335                 return BLUETOOTH_ERROR_INTERNAL;
336         }
337
338         if (device_power_request_lock(POWER_LOCK_CPU, 2000) != DEVICE_ERROR_NONE)
339                 BT_ERR("device_power_request_lock() failed");
340         else
341                 BT_ERR("device_power_request_lock() succeed");
342
343         reply = g_dbus_proxy_call_sync(proxy, "LEReadLocalData",
344                         NULL,
345                         G_DBUS_CALL_FLAGS_NONE, -1,
346                         NULL, &err);
347         g_object_unref(proxy);
348
349         if (reply == NULL) {
350                 BT_ERR("LEReadLocalData dBUS-RPC is failed");
351                 if (err != NULL) {
352                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
353                                         err->code, err->message);
354                         g_clear_error(&err);
355                 }
356                 return BLUETOOTH_ERROR_INTERNAL;
357         }
358
359         g_variant_get(reply, "(@ay)", &eir);
360         g_variant_unref(reply);
361
362         if (eir) {
363                 local_oob_data->eir_len = __get_oob_data_from_variant(eir,
364                                 local_oob_data->eir,
365                                 sizeof(local_oob_data->eir));
366                 g_variant_unref(eir);
367         }
368
369         return BLUETOOTH_ERROR_NONE;
370 }
371