Fix mem leak.
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-emul / bt-service-common.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <glib.h>
21 #include <dlog.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <termios.h>
25 #include <bundle.h>
26 #include <glib.h>
27 #include <dlog.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <termios.h>
31 #include <eventsystem.h>
32
33 #include "bluetooth-api.h"
34 #include "bt-service-common.h"
35
36 static GDBusConnection *system_conn;
37 static GDBusConnection *session_conn;
38 static GDBusConnection *system_gconn = NULL;
39
40 GDBusConnection *_bt_gdbus_init_system_gconn(void)
41 {
42         GError *error = NULL;
43
44         if (system_gconn != NULL)
45                 return system_gconn;
46
47         system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
48
49         if (!system_gconn) {
50                 BT_ERR("Unable to connect to dbus: %s", error->message);
51                 g_clear_error(&error);
52         }
53
54         return system_gconn;
55 }
56
57 GDBusConnection *_bt_gdbus_get_system_gconn(void)
58 {
59         GDBusConnection *local_system_gconn = NULL;
60         GError *error = NULL;
61
62         if (system_gconn == NULL) {
63                 system_gconn = _bt_gdbus_init_system_gconn();
64         } else if (g_dbus_connection_is_closed(system_gconn)) {
65
66                 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
67
68                 if (!local_system_gconn) {
69                         BT_ERR("Unable to connect to dbus: %s", error->message);
70                         g_clear_error(&error);
71                 }
72
73                 system_gconn = local_system_gconn;
74         }
75
76         return system_gconn;
77 }
78
79 GDBusConnection *__bt_init_system_gconn(void)
80 {
81         if (system_conn == NULL)
82                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
83
84         return system_conn;
85 }
86
87 GDBusConnection *__bt_init_session_conn(void)
88 {
89         if (session_conn == NULL)
90                 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
91
92         return session_conn;
93 }
94
95 GDBusConnection *_bt_get_session_gconn(void)
96 {
97         return (session_conn) ? session_conn : __bt_init_session_conn();
98 }
99
100 GDBusConnection *_bt_get_system_gconn(void)
101 {
102         return (system_conn) ? system_conn : __bt_init_system_gconn();
103 }
104
105 GDBusConnection *_bt_get_system_conn(void)
106 {
107         GDBusConnection *g_conn;
108
109         if (system_conn == NULL)
110                 g_conn = __bt_init_system_gconn();
111         else
112                 g_conn = system_conn;
113
114         retv_if(g_conn == NULL, NULL);
115
116         return g_conn;
117 }
118
119 void _bt_deinit_proxys(void)
120 {
121         if (system_conn) {
122                 g_object_unref(system_conn);
123                 system_conn = NULL;
124         }
125
126         if (session_conn) {
127                 g_object_unref(session_conn);
128                 session_conn = NULL;
129         }
130 }
131
132 void _bt_convert_device_path_to_address(const char *device_path,
133                                                 char *device_address)
134 {
135         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
136         char *dev_addr;
137
138         ret_if(device_path == NULL);
139         ret_if(device_address == NULL);
140
141         dev_addr = strstr(device_path, "dev_");
142         if (dev_addr != NULL) {
143                 char *pos = NULL;
144                 dev_addr += 4;
145                 g_strlcpy(address, dev_addr, sizeof(address));
146
147                 while ((pos = strchr(address, '_')) != NULL)
148                         *pos = ':';
149
150                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
151         }
152 }
153
154
155 void _bt_convert_addr_string_to_type(unsigned char *addr,
156                                         const char *address)
157 {
158         int i;
159         char *ptr = NULL;
160
161         ret_if(address == NULL);
162         ret_if(addr == NULL);
163
164         for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
165                 addr[i] = strtol(address, &ptr, 16);
166                 if (ptr[0] != '\0') {
167                         if (ptr[0] != ':')
168                                 return;
169
170                         address = ptr + 1;
171                 }
172         }
173 }
174
175 void _bt_convert_addr_type_to_string(char *address,
176                                 unsigned char *addr)
177 {
178         ret_if(address == NULL);
179         ret_if(addr == NULL);
180
181         snprintf(address, BT_ADDRESS_STRING_SIZE,
182                         "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
183                         addr[0], addr[1], addr[2],
184                         addr[3], addr[4], addr[5]);
185 }
186
187 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
188 {
189         BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
190                                 addr->addr[3], addr->addr[4], addr->addr[5]);
191 }
192
193 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
194                                 unsigned int cod)
195 {
196         ret_if(device_class == NULL);
197
198         device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
199         device_class->minor_class = (unsigned short)((cod & 0x000000FC));
200         device_class->service_class = (unsigned long)((cod & 0x00FF0000));
201
202         if (cod & 0x002000) {
203                 device_class->service_class |=
204                 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
205         }
206 }
207
208 void _bt_free_device_info(bt_remote_dev_info_t *dev_info)
209 {
210         int i;
211
212         ret_if(dev_info == NULL);
213
214         g_free(dev_info->address);
215         g_free(dev_info->name);
216         g_free(dev_info->manufacturer_data);
217
218         if (dev_info->uuids) {
219                 for (i = 0; i < dev_info->uuid_count && dev_info->uuids[i]; i++)
220                         g_free(dev_info->uuids[i]);
221
222                 g_free(dev_info->uuids);
223         }
224
225         g_free(dev_info);
226 }
227
228 void _bt_free_le_device_info(bt_remote_le_dev_info_t *le_dev_info)
229 {
230         ret_if(le_dev_info == NULL);
231
232         g_free(le_dev_info->adv_data);
233         g_free(le_dev_info);
234 }
235
236 int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
237 {
238         int i;
239         const char *p = src;
240         char *next;
241         int count;
242
243         if (dest == NULL || src == NULL)
244                 return BLUETOOTH_ERROR_INVALID_PARAM;
245
246         BT_DBG("+src : %s", src);
247         BT_DBG("+dest : %s", dest);
248
249         i = 0;
250         while (*p != '\0' && i < length) {
251                 next = g_utf8_next_char(p);
252                 count = next - p;
253
254                 while (count > 0 && ((i + count) < length)) {
255                         dest[i++] = *p;
256                         p++;
257                         count--;
258                 }
259                 p = next;
260         }
261         return BLUETOOTH_ERROR_NONE;
262 }
263
264 gboolean _bt_utf8_validate(char *name)
265 {
266         BT_DBG("+");
267         gunichar2 *u16;
268         glong items_written = 0;
269
270         if (FALSE == g_utf8_validate(name, -1, NULL))
271                 return FALSE;
272
273         u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
274         if (u16 == NULL)
275                 return FALSE;
276
277         g_free(u16);
278
279         if (items_written != g_utf8_strlen(name, -1))
280                 return FALSE;
281
282         BT_DBG("-");
283         return TRUE;
284 }
285
286 int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd)
287 {
288         return BLUETOOTH_ERROR_NOT_SUPPORT;
289 }
290
291 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
292 {
293         return BLUETOOTH_ERROR_NOT_SUPPORT;
294 }
295
296 int _bt_set_socket_non_blocking(int socket_fd)
297 {
298         /* Set Nonblocking */
299         long arg;
300
301         arg = fcntl(socket_fd, F_GETFL);
302
303         if (arg < 0)
304                 return -errno;
305
306         if (arg & O_NONBLOCK)
307                 BT_ERR("Already Non-blocking \n");
308
309         arg |= O_NONBLOCK;
310
311         if (fcntl(socket_fd, F_SETFL, arg) < 0)
312                 return -errno;
313
314         return BLUETOOTH_ERROR_NONE;
315 }
316
317 int _bt_set_non_blocking_tty(int sk)
318 {
319         struct termios ti = {0,};
320         int err;
321
322         err = _bt_set_socket_non_blocking(sk);
323
324         if (err < 0) {
325                 BT_ERR("Error in set non blocking!\n");
326                 return err;
327         }
328
329         tcflush(sk, TCIOFLUSH);
330
331         /* Switch tty to RAW mode */
332         cfmakeraw(&ti);
333         tcsetattr(sk, TCSANOW, &ti);
334
335         return BLUETOOTH_ERROR_NONE;
336 }
337
338 char *_bt_get_profile_uuid128(bt_profile_type_t profile_type)
339 {
340         switch (profile_type) {
341         case BT_PROFILE_CONN_RFCOMM:
342                 return strdup(RFCOMM_UUID_STR);
343         case BT_PROFILE_CONN_A2DP:
344                 return strdup(A2DP_SINK_UUID);
345         case BT_PROFILE_CONN_A2DP_SINK:
346                 return strdup(A2DP_SOURCE_UUID);
347         case BT_PROFILE_CONN_HSP:
348                 return strdup(HFP_HS_UUID);
349         case BT_PROFILE_CONN_HID:
350                 return strdup(HID_UUID);
351         case BT_PROFILE_CONN_NAP:
352                 return strdup(NAP_UUID);
353         case BT_PROFILE_CONN_HFG:
354                 return strdup(HFP_AG_UUID);
355         case BT_PROFILE_CONN_GATT:
356         case BT_PROFILE_CONN_ALL: /* NULL UUID will connect to both the audio profiles*/
357         default:
358                 return NULL;
359         };
360 }
361
362 char *_bt_convert_error_to_string(int error)
363 {
364         switch (error) {
365         case BLUETOOTH_ERROR_CANCEL:
366                 return "CANCELLED";
367         case BLUETOOTH_ERROR_INVALID_PARAM:
368                 return "INVALID_PARAMETER";
369         case BLUETOOTH_ERROR_INVALID_DATA:
370                 return "INVALID DATA";
371         case BLUETOOTH_ERROR_MEMORY_ALLOCATION:
372         case BLUETOOTH_ERROR_OUT_OF_MEMORY:
373                 return "OUT_OF_MEMORY";
374         case BLUETOOTH_ERROR_TIMEOUT:
375                 return "TIMEOUT";
376         case BLUETOOTH_ERROR_NO_RESOURCES:
377                 return "NO_RESOURCES";
378         case BLUETOOTH_ERROR_INTERNAL:
379                 return "INTERNAL";
380         case BLUETOOTH_ERROR_NOT_SUPPORT:
381                 return "NOT_SUPPORT";
382         case BLUETOOTH_ERROR_DEVICE_NOT_ENABLED:
383                 return "NOT_ENABLED";
384         case BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED:
385                 return "ALREADY_ENABLED";
386         case BLUETOOTH_ERROR_DEVICE_BUSY:
387                 return "DEVICE_BUSY";
388         case BLUETOOTH_ERROR_ACCESS_DENIED:
389                 return "ACCESS_DENIED";
390         case BLUETOOTH_ERROR_MAX_CLIENT:
391                 return "MAX_CLIENT";
392         case BLUETOOTH_ERROR_NOT_FOUND:
393                 return "NOT_FOUND";
394         case BLUETOOTH_ERROR_SERVICE_SEARCH_ERROR:
395                 return "SERVICE_SEARCH_ERROR";
396         case BLUETOOTH_ERROR_PARING_FAILED:
397                 return "PARING_FAILED";
398         case BLUETOOTH_ERROR_NOT_PAIRED:
399                 return "NOT_PAIRED";
400         case BLUETOOTH_ERROR_SERVICE_NOT_FOUND:
401                 return "SERVICE_NOT_FOUND";
402         case BLUETOOTH_ERROR_NOT_CONNECTED:
403                 return "NOT_CONNECTED";
404         case BLUETOOTH_ERROR_ALREADY_CONNECT:
405                 return "ALREADY_CONNECT";
406         case BLUETOOTH_ERROR_CONNECTION_BUSY:
407                 return "CONNECTION_BUSY";
408         case BLUETOOTH_ERROR_CONNECTION_ERROR:
409                 return "CONNECTION_ERROR";
410         case BLUETOOTH_ERROR_MAX_CONNECTION:
411                 return "MAX_CONNECTION";
412         case BLUETOOTH_ERROR_NOT_IN_OPERATION:
413                 return "NOT_IN_OPERATION";
414         case BLUETOOTH_ERROR_CANCEL_BY_USER:
415                 return "CANCEL_BY_USER";
416         case BLUETOOTH_ERROR_REGISTRATION_FAILED:
417                 return "REGISTRATION_FAILED";
418         case BLUETOOTH_ERROR_IN_PROGRESS:
419                 return "IN_PROGRESS";
420         case BLUETOOTH_ERROR_AUTHENTICATION_FAILED:
421                 return "AUTHENTICATION_FAILED";
422         case BLUETOOTH_ERROR_HOST_DOWN:
423                 return "HOST_DOWN";
424         case BLUETOOTH_ERROR_END_OF_DEVICE_LIST:
425                 return "END_OF_DEVICE_LIST";
426         case BLUETOOTH_ERROR_AGENT_ALREADY_EXIST:
427                 return "AGENT_ALREADY_EXIST";
428         case BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST:
429                 return "AGENT_DOES_NOT_EXIST";
430         case BLUETOOTH_ERROR_ALREADY_INITIALIZED:
431                 return "ALREADY_INITIALIZED";
432         case BLUETOOTH_ERROR_PERMISSION_DEINED:
433                 return "PERMISSION_DEINED";
434         case BLUETOOTH_ERROR_ALREADY_DEACTIVATED:
435                 return "ALREADY_DEACTIVATED";
436         case BLUETOOTH_ERROR_NOT_INITIALIZED:
437                 return "NOT_INITIALIZED";
438         default:
439                 return "UNKNOWN";
440         }
441 }
442
443 char * _bt_convert_disc_reason_to_string(int reason)
444 {
445         switch (reason) {
446         case 1:
447                 return "Link loss";
448         case 2:
449                 return "Connection terminated by local host";
450         case 3:
451                 return "Remote user terminated connection";
452         case 0:
453         default:
454                 return "Unknown";
455         }
456 }
457
458 void _bt_logging_connection(gboolean connect, int addr_type)
459 {
460         static int le_conn = 0;
461         static int le_disc = 0;
462         static int edr_conn = 0;
463         static int edr_disc = 0;
464
465         if (connect) {
466                 if (addr_type)
467                         le_conn++;
468                 else
469                         edr_conn++;
470         } else {
471                 if (addr_type)
472                         le_disc++;
473                 else
474                         edr_disc++;
475         }
476
477         BT_INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
478                         le_conn, le_disc, edr_conn, edr_disc);
479 }
480
481 int _bt_eventsystem_set_value(const char *event, const char *key, const char *value)
482 {
483         int ret;
484         bundle *b = NULL;
485
486         b = bundle_create();
487
488         bundle_add_str(b, key, value);
489
490         ret = eventsystem_send_system_event(event, b);
491
492         BT_DBG("eventsystem_send_system_event result: %d", ret);
493
494         bundle_free(b);
495
496         return ret;
497 }
498
499 void _bt_swap_byte_ordering(char *data, int data_len)
500 {
501         char temp;
502         int i, j;
503
504         ret_if(data == NULL);
505         /* Swap to opposite endian */
506         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
507                 temp = data[i];
508                 data[i] = data[j];
509                 data[j] = temp;
510                 }
511 }
512
513 int _bt_byte_arr_cmp(const char *data1, const char *data2, int data_len)
514 {
515         int i;
516
517         retv_if(data1 == NULL, -1);
518         retv_if(data2 == NULL, -1);
519         for (i = 0; i < data_len; i++) {
520                 if (data1[i] != data2[i])
521                         return data1[i] - data2[i];
522                 }
523         return 0;
524 }
525 int _bt_byte_arr_cmp_with_mask(const char *data1, const char *data2,
526         const char *mask, int data_len)
527 {
528         int i;
529         char a, b;
530
531         retv_if(data1 == NULL, -1);
532         retv_if(data2 == NULL, -1);
533         retv_if(mask == NULL, -1);
534         for (i = 0; i < data_len; i++) {
535                 a = data1[i] & mask[i];
536                 b = data2[i] & mask[i];
537                 if (a != b)
538                         return (int)(a - b);
539                 }
540         return 0;
541 }