[Adapt:Frwk] Implement get bonded device info APIs
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / 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 <stdlib.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <dlog.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <termios.h>
26 #include <net_connection.h>
27 #include <dbus/dbus.h>
28 #include <glib.h>
29 #include <dlog.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include <termios.h>
33 #include <net_connection.h>
34 #include <bundle.h>
35 #include <eventsystem.h>
36 #include <arpa/inet.h>
37
38 #include "bluetooth-api.h"
39 #include "bt-service-common.h"
40
41 #include <oal-manager.h>
42
43 static GDBusConnection *system_conn;
44 static GDBusConnection *session_conn;
45 static GDBusProxy *manager_proxy;
46 static GDBusProxy *adapter_proxy;
47 static void *net_conn;
48
49 static GDBusProxy *adapter_properties_proxy;
50
51 static GDBusConnection *system_gconn = NULL;
52
53 GDBusConnection *_bt_gdbus_init_system_gconn(void)
54 {
55         GError *error = NULL;
56
57         dbus_threads_init_default();
58
59         if (system_gconn != NULL)
60                 return system_gconn;
61
62         system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
63
64         if (!system_gconn) {
65                 BT_ERR("Unable to connect to dbus: %s", error->message);
66                 g_clear_error(&error);
67         }
68
69         return system_gconn;
70 }
71
72 GDBusConnection *_bt_gdbus_get_system_gconn(void)
73 {
74         GDBusConnection *local_system_gconn = NULL;
75         GError *error = NULL;
76
77         if (system_gconn == NULL) {
78                 system_gconn = _bt_gdbus_init_system_gconn();
79         } else if (g_dbus_connection_is_closed(system_gconn)) {
80
81                 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
82
83                 if (!local_system_gconn) {
84                         BT_ERR("Unable to connect to dbus: %s", error->message);
85                         g_clear_error(&error);
86                 }
87
88                 system_gconn = local_system_gconn;
89         }
90
91         return system_gconn;
92 }
93
94 static GDBusProxy *__bt_init_manager_proxy(void)
95 {
96         GDBusProxy *proxy;
97
98         if (system_conn == NULL) {
99                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
100                 retv_if(system_conn == NULL, NULL);
101         }
102
103         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
104                                                                 NULL, BT_BLUEZ_NAME,
105                                                                 BT_MANAGER_PATH, BT_MANAGER_INTERFACE,  NULL, NULL);
106
107         retv_if(proxy == NULL, NULL);
108
109         manager_proxy = proxy;
110
111         return proxy;
112 }
113
114 static GDBusProxy *__bt_init_adapter_proxy(void)
115 {
116         GDBusProxy *manager_proxy;
117         GDBusProxy *proxy;
118         char *adapter_path = NULL;
119
120         if (system_conn == NULL) {
121                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
122                 retv_if(system_conn == NULL, NULL);
123         }
124
125         manager_proxy = _bt_get_manager_proxy();
126         retv_if(manager_proxy == NULL, NULL);
127
128         adapter_path = _bt_get_adapter_path();
129         retv_if(adapter_path == NULL, NULL);
130
131         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
132                                                                 NULL, BT_BLUEZ_NAME,
133                                                                 adapter_path, BT_ADAPTER_INTERFACE,  NULL, NULL);
134
135         g_free(adapter_path);
136
137         retv_if(proxy == NULL, NULL);
138
139         adapter_proxy = proxy;
140
141         return proxy;
142 }
143
144 static GDBusProxy *__bt_init_adapter_properties_proxy(void)
145 {
146         GDBusProxy *manager_proxy;
147         GDBusProxy *proxy;
148         char *adapter_path = NULL;
149
150         if (system_conn == NULL) {
151                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
152                 retv_if(system_conn == NULL, NULL);
153         }
154
155         manager_proxy = _bt_get_manager_proxy();
156         retv_if(manager_proxy == NULL, NULL);
157
158         adapter_path = _bt_get_adapter_path();
159         retv_if(adapter_path == NULL, NULL);
160
161         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
162                                                                         NULL, BT_BLUEZ_NAME,
163                                                                         adapter_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
164
165         g_free(adapter_path);
166
167         retv_if(proxy == NULL, NULL);
168
169         adapter_properties_proxy = proxy;
170
171         return proxy;
172 }
173
174 GDBusConnection *__bt_init_system_gconn(void)
175 {
176         if (system_conn == NULL)
177                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
178
179         return system_conn;
180 }
181
182 GDBusConnection *__bt_init_session_conn(void)
183 {
184         if (session_conn == NULL)
185                 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
186
187         return session_conn;
188 }
189
190 GDBusConnection *_bt_get_session_gconn(void)
191 {
192         return (session_conn) ? session_conn : __bt_init_session_conn();
193 }
194
195 GDBusConnection *_bt_get_system_gconn(void)
196 {
197         return (system_conn) ? system_conn : __bt_init_system_gconn();
198 }
199
200 GDBusConnection *_bt_get_system_conn(void)
201 {
202         GDBusConnection *g_conn;
203
204         if (system_conn == NULL) {
205                 g_conn = __bt_init_system_gconn();
206         } else {
207                 g_conn = system_conn;
208         }
209
210         retv_if(g_conn == NULL, NULL);
211
212         return g_conn;
213 }
214
215 GDBusProxy *_bt_get_manager_proxy(void)
216 {
217         if (manager_proxy) {
218                 const gchar *path =  g_dbus_proxy_get_object_path(manager_proxy);
219                 if (path == NULL) {
220                         BT_ERR("Already proxy released hence creating new proxy");
221                         return  __bt_init_manager_proxy();
222                 }
223                 return manager_proxy;
224         }
225         return  __bt_init_manager_proxy();
226 }
227
228 static void *__bt_init_net_conn(void)
229 {
230         int result;
231         connection_h connection = NULL;
232
233         if (net_conn == NULL) {
234                 result = connection_create(&connection);
235
236         if (result != CONNECTION_ERROR_NONE ||
237                                         connection == NULL) {
238                 BT_DBG("connection_create() failed: %d", result);
239                 net_conn = NULL;
240                 return NULL;
241         }
242                 net_conn = connection;
243         }
244         return net_conn;
245 }
246
247 void *_bt_get_net_conn(void)
248 {
249         return (net_conn) ? net_conn : __bt_init_net_conn();
250 }
251
252 GDBusProxy *_bt_get_adapter_proxy(void)
253 {
254         if (adapter_proxy) {
255                 const char *path =  g_dbus_proxy_get_object_path(adapter_proxy);
256                 if (path == NULL) {
257                         BT_ERR("Already proxy released hence creating new proxy");
258                         return  __bt_init_adapter_proxy();
259                 }
260
261                 return adapter_proxy;
262         }
263         return  __bt_init_adapter_proxy();
264
265 }
266
267 GDBusProxy *_bt_get_adapter_properties_proxy(void)
268 {
269         return (adapter_properties_proxy) ? adapter_properties_proxy :
270                                         __bt_init_adapter_properties_proxy();
271 }
272
273 static char *__bt_extract_adapter_path(GVariantIter *iter)
274 {
275         char *object_path = NULL;
276         GVariantIter *interface_iter;
277         GVariantIter *svc_iter;
278         char *interface_str = NULL;
279
280         /* Parse the signature: oa{sa{sv}}} */
281         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
282                         &interface_iter)) {
283
284                 if (object_path == NULL)
285                         continue;
286
287                 while (g_variant_iter_loop(interface_iter, "{&sa{sv}}",
288                                 &interface_str, &svc_iter)) {
289                         if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
290                                 continue;
291
292                         BT_DBG("Object Path: %s", object_path);
293                         g_variant_iter_free(svc_iter);
294                         g_variant_iter_free(interface_iter);
295                         return g_strdup(object_path);
296                 }
297         }
298         return NULL;
299 }
300
301 char *_bt_get_adapter_path(void)
302 {
303         GDBusConnection *conn;
304         GDBusProxy *manager_proxy;
305         GVariant *result = NULL;
306         GVariantIter *iter = NULL;
307         char *adapter_path = NULL;
308
309         conn = _bt_get_system_conn();
310         retv_if(conn == NULL, NULL);
311
312         manager_proxy = _bt_get_manager_proxy();
313         retv_if(manager_proxy == NULL, NULL);
314
315         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
316                                 NULL,
317                                 G_DBUS_CALL_FLAGS_NONE,
318                                 -1,
319                                 NULL,
320                                 NULL);
321         if (!result) {
322                 BT_ERR("Can't get managed objects");
323                 return NULL;
324         }
325
326         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
327         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
328
329         adapter_path = __bt_extract_adapter_path(iter);
330         g_variant_iter_free(iter);
331         g_variant_unref(result);
332         return adapter_path;
333 }
334
335 void _bt_deinit_bluez_proxy(void)
336 {
337         if (manager_proxy) {
338                 g_object_unref(manager_proxy);
339                 manager_proxy = NULL;
340         }
341
342         if (adapter_proxy) {
343                 g_object_unref(adapter_proxy);
344                 adapter_proxy = NULL;
345         }
346         if (adapter_properties_proxy) {
347                 g_object_unref(adapter_properties_proxy);
348                 adapter_properties_proxy = NULL;
349         }
350 }
351
352 void _bt_deinit_proxys(void)
353 {
354         int ret;
355         _bt_deinit_bluez_proxy();
356
357         if (system_conn) {
358                 g_object_unref(system_conn);
359                 system_conn = NULL;
360         }
361
362         if (session_conn) {
363                 g_object_unref(session_conn);
364                 session_conn = NULL;
365         }
366
367         if (net_conn) {
368                 ret = connection_destroy(net_conn);
369                 net_conn = NULL;
370                 if (ret != 0)
371                         BT_ERR("connection_destroy failed : %d", ret);
372         }
373 }
374
375 void _bt_convert_device_path_to_address(const char *device_path,
376                                                 char *device_address)
377 {
378         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
379         char *dev_addr;
380
381         ret_if(device_path == NULL);
382         ret_if(device_address == NULL);
383
384         dev_addr = strstr(device_path, "dev_");
385         if (dev_addr != NULL) {
386                 char *pos = NULL;
387                 dev_addr += 4;
388                 g_strlcpy(address, dev_addr, sizeof(address));
389
390                 while ((pos = strchr(address, '_')) != NULL) {
391                         *pos = ':';
392                 }
393
394                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
395         }
396 }
397
398
399 void _bt_convert_addr_string_to_type(unsigned char *addr,
400                                         const char *address)
401 {
402         int i;
403         char *ptr = NULL;
404
405         ret_if(address == NULL);
406         ret_if(addr == NULL);
407
408         for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
409                 addr[i] = strtol(address, &ptr, 16);
410                 if (ptr[0] != '\0') {
411                         if (ptr[0] != ':')
412                                 return;
413
414                         address = ptr + 1;
415                 }
416         }
417 }
418
419 void _bt_convert_addr_type_to_string(char *address,
420                                 unsigned char *addr)
421 {
422         ret_if(address == NULL);
423         ret_if(addr == NULL);
424
425         snprintf(address, BT_ADDRESS_STRING_SIZE,
426                         "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
427                         addr[0], addr[1], addr[2],
428                         addr[3], addr[4], addr[5]);
429 }
430
431 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
432 {
433         BT_INFO("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
434                 addr->addr[0], addr->addr[1], addr->addr[2],
435                 addr->addr[3], addr->addr[4], addr->addr[5]);
436 }
437
438 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
439                                 unsigned int cod)
440 {
441         ret_if(device_class == NULL);
442
443         device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
444         device_class->minor_class = (unsigned short)((cod & 0x000000FC));
445         device_class->service_class = (unsigned long)((cod & 0x00FF0000));
446
447         if (cod & 0x002000) {
448                 device_class->service_class |=
449                 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
450         }
451 }
452
453 void _bt_free_device_info(bt_remote_dev_info_t *dev_info)
454 {
455         int i;
456
457         ret_if(dev_info == NULL);
458
459         g_free(dev_info->address);
460         g_free(dev_info->name);
461         g_free(dev_info->manufacturer_data);
462
463         if (dev_info->uuids) {
464                 for (i = 0; i < dev_info->uuid_count && dev_info->uuids[i]; i++)
465                         g_free(dev_info->uuids[i]);
466
467                 g_free(dev_info->uuids);
468         }
469
470         g_free(dev_info);
471 }
472
473 void _bt_free_le_device_info(bt_remote_le_dev_info_t *le_dev_info)
474 {
475         ret_if(le_dev_info == NULL);
476
477         g_free(le_dev_info->adv_data);
478         g_free(le_dev_info);
479 }
480
481 int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
482 {
483         int i;
484         const char *p = src;
485         char *next;
486         int count;
487
488         if (dest == NULL || src == NULL)
489                 return BLUETOOTH_ERROR_INVALID_PARAM;
490
491         BT_DBG("+src : %s", src);
492         BT_DBG("+dest : %s", dest);
493
494         i = 0;
495         while (*p != '\0' && i < length) {
496                 next = g_utf8_next_char(p);
497                 count = next - p;
498
499                 while (count > 0 && ((i + count) < length)) {
500                         dest[i++] = *p;
501                         p++;
502                         count--;
503                 }
504                 p = next;
505         }
506         return BLUETOOTH_ERROR_NONE;
507 }
508
509 gboolean _bt_utf8_validate(char *name)
510 {
511         BT_DBG("+");
512         gunichar2 *u16;
513         glong items_written = 0;
514
515         if (FALSE == g_utf8_validate(name, -1, NULL))
516                 return FALSE;
517
518         u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
519         if (u16 == NULL)
520                 return FALSE;
521
522         g_free(u16);
523
524         if (items_written != g_utf8_strlen(name, -1))
525                 return FALSE;
526
527         BT_DBG("-");
528         return TRUE;
529 }
530
531 int _bt_set_socket_non_blocking(int socket_fd)
532 {
533         /* Set Nonblocking */
534         long arg;
535
536         arg = fcntl(socket_fd, F_GETFL);
537
538         if (arg < 0)
539                 return -errno;
540
541         if (arg & O_NONBLOCK) {
542                 BT_ERR("Already Non-blocking \n");
543         }
544
545         arg |= O_NONBLOCK;
546
547         if (fcntl(socket_fd, F_SETFL, arg) < 0)
548                 return -errno;
549
550         return BLUETOOTH_ERROR_NONE;
551 }
552
553 int _bt_set_non_blocking_tty(int sk)
554 {
555         struct termios ti = {0,};
556         int err;
557
558         err = _bt_set_socket_non_blocking(sk);
559
560         if (err < 0) {
561                 BT_ERR("Error in set non blocking!\n");
562                 return err;
563         }
564
565         tcflush(sk, TCIOFLUSH);
566
567         /* Switch tty to RAW mode */
568         cfmakeraw(&ti);
569         tcsetattr(sk, TCSANOW, &ti);
570
571         return BLUETOOTH_ERROR_NONE;
572 }
573
574 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
575 {
576         char *object_path = NULL;
577         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
578
579         /* Parse the signature: oa{sa{sv}}} */
580         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
581                         NULL)) {
582                 retv_if(object_path == NULL, NULL);
583                 _bt_convert_device_path_to_address(object_path, device_address);
584                 if (g_strcmp0(address, device_address) == 0) {
585                         return g_strdup(object_path);
586                 }
587         }
588         return NULL;
589 }
590
591 char *_bt_get_device_object_path(char *address)
592 {
593         char *object_path = NULL;
594         GDBusConnection *conn;
595         GDBusProxy *manager_proxy;
596         GVariant *result = NULL;
597         GVariantIter *iter = NULL;
598
599         conn = _bt_get_system_conn();
600         retv_if(conn == NULL, NULL);
601
602         manager_proxy = _bt_get_manager_proxy();
603         retv_if(manager_proxy == NULL, NULL);
604
605         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
606                                 NULL,
607                                 G_DBUS_CALL_FLAGS_NONE,
608                                 -1,
609                                 NULL,
610                                 NULL);
611         if (!result) {
612                 BT_ERR("Can't get managed objects");
613                 return NULL;
614         }
615
616         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
617         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
618         object_path = __bt_extract_device_path(iter, address);
619         g_variant_iter_free(iter);
620         g_variant_unref(result);
621         return object_path;
622 }
623
624 char *_bt_get_profile_uuid128(bt_profile_type_t profile_type)
625 {
626         switch (profile_type) {
627         case BT_PROFILE_CONN_RFCOMM:
628                 return strdup(RFCOMM_UUID_STR);
629         case BT_PROFILE_CONN_A2DP:
630                 return strdup(A2DP_SINK_UUID);
631         case BT_PROFILE_CONN_A2DP_SINK:
632                 return strdup(A2DP_SOURCE_UUID);
633         case BT_PROFILE_CONN_HSP:
634                 return strdup(HFP_HS_UUID);
635         case BT_PROFILE_CONN_HID:
636                 return strdup(HID_UUID);
637         case BT_PROFILE_CONN_NAP:
638                 return strdup(NAP_UUID);
639         case BT_PROFILE_CONN_HFG:
640                 return strdup(HFP_AG_UUID);
641         case BT_PROFILE_CONN_GATT:
642         case BT_PROFILE_CONN_ALL: /* NULL UUID will connect to both the audio profiles*/
643         default:
644                 return NULL;
645         };
646 }
647
648 char *_bt_convert_error_to_string(int error)
649 {
650         switch (error) {
651         case BLUETOOTH_ERROR_CANCEL:
652                 return "CANCELLED";
653         case BLUETOOTH_ERROR_INVALID_PARAM:
654                 return "INVALID_PARAMETER";
655         case BLUETOOTH_ERROR_INVALID_DATA:
656                 return "INVALID DATA";
657         case BLUETOOTH_ERROR_MEMORY_ALLOCATION:
658         case BLUETOOTH_ERROR_OUT_OF_MEMORY:
659                 return "OUT_OF_MEMORY";
660         case BLUETOOTH_ERROR_TIMEOUT:
661                 return "TIMEOUT";
662         case BLUETOOTH_ERROR_NO_RESOURCES:
663                 return "NO_RESOURCES";
664         case BLUETOOTH_ERROR_INTERNAL:
665                 return "INTERNAL";
666         case BLUETOOTH_ERROR_NOT_SUPPORT:
667                 return "NOT_SUPPORT";
668         case BLUETOOTH_ERROR_DEVICE_NOT_ENABLED:
669                 return "NOT_ENABLED";
670         case BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED:
671                 return "ALREADY_ENABLED";
672         case BLUETOOTH_ERROR_DEVICE_BUSY:
673                 return "DEVICE_BUSY";
674         case BLUETOOTH_ERROR_ACCESS_DENIED:
675                 return "ACCESS_DENIED";
676         case BLUETOOTH_ERROR_MAX_CLIENT:
677                 return "MAX_CLIENT";
678         case BLUETOOTH_ERROR_NOT_FOUND:
679                 return "NOT_FOUND";
680         case BLUETOOTH_ERROR_SERVICE_SEARCH_ERROR:
681                 return "SERVICE_SEARCH_ERROR";
682         case BLUETOOTH_ERROR_PARING_FAILED:
683                 return "PARING_FAILED";
684         case BLUETOOTH_ERROR_NOT_PAIRED:
685                 return "NOT_PAIRED";
686         case BLUETOOTH_ERROR_SERVICE_NOT_FOUND:
687                 return "SERVICE_NOT_FOUND";
688         case BLUETOOTH_ERROR_NOT_CONNECTED:
689                 return "NOT_CONNECTED";
690         case BLUETOOTH_ERROR_ALREADY_CONNECT:
691                 return "ALREADY_CONNECT";
692         case BLUETOOTH_ERROR_CONNECTION_BUSY:
693                 return "CONNECTION_BUSY";
694         case BLUETOOTH_ERROR_CONNECTION_ERROR:
695                 return "CONNECTION_ERROR";
696         case BLUETOOTH_ERROR_MAX_CONNECTION:
697                 return "MAX_CONNECTION";
698         case BLUETOOTH_ERROR_NOT_IN_OPERATION:
699                 return "NOT_IN_OPERATION";
700         case BLUETOOTH_ERROR_CANCEL_BY_USER:
701                 return "CANCEL_BY_USER";
702         case BLUETOOTH_ERROR_REGISTRATION_FAILED:
703                 return "REGISTRATION_FAILED";
704         case BLUETOOTH_ERROR_IN_PROGRESS:
705                 return "IN_PROGRESS";
706         case BLUETOOTH_ERROR_AUTHENTICATION_FAILED:
707                 return "AUTHENTICATION_FAILED";
708         case BLUETOOTH_ERROR_HOST_DOWN:
709                 return "HOST_DOWN";
710         case BLUETOOTH_ERROR_END_OF_DEVICE_LIST:
711                 return "END_OF_DEVICE_LIST";
712         case BLUETOOTH_ERROR_AGENT_ALREADY_EXIST:
713                 return "AGENT_ALREADY_EXIST";
714         case BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST:
715                 return "AGENT_DOES_NOT_EXIST";
716         case BLUETOOTH_ERROR_ALREADY_INITIALIZED:
717                 return "ALREADY_INITIALIZED";
718         case BLUETOOTH_ERROR_PERMISSION_DEINED:
719                 return "PERMISSION_DEINED";
720         case BLUETOOTH_ERROR_ALREADY_DEACTIVATED:
721                 return "ALREADY_DEACTIVATED";
722         case BLUETOOTH_ERROR_NOT_INITIALIZED:
723                 return "NOT_INITIALIZED";
724         default:
725                 return "UNKNOWN";
726         }
727 }
728
729 char * _bt_convert_disc_reason_to_string(int reason)
730 {
731         switch (reason) {
732         case 1:
733                 return "Link loss";
734         case 2:
735                 return "Connection terminated by local host";
736         case 3:
737                 return "Remote user terminated connection";
738         case 0:
739         default:
740                 return "Unknown";
741         }
742 }
743
744 void _bt_logging_connection(gboolean connect, int addr_type)
745 {
746         static int le_conn = 0;
747         static int le_disc = 0;
748         static int edr_conn = 0;
749         static int edr_disc = 0;
750
751         if (connect) {
752                 if (addr_type)
753                         le_conn++;
754                 else
755                         edr_conn++;
756         } else {
757                 if (addr_type)
758                         le_disc++;
759                 else
760                         edr_disc++;
761         }
762
763         BT_INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
764                         le_conn, le_disc, edr_conn, edr_disc);
765 }
766
767 int _bt_eventsystem_set_value(const char *event, const char *key, const char *value)
768 {
769         int ret;
770         bundle *b = NULL;
771
772         b = bundle_create();
773
774         bundle_add_str(b, key, value);
775
776         ret = eventsystem_send_system_event(event, b);
777
778         BT_DBG("eventsystem_send_system_event result: %d", ret);
779
780         bundle_free(b);
781
782         return ret;
783 }
784
785 void _bt_swap_byte_ordering(char *data, int data_len)
786 {
787         char temp;
788         int i, j;
789
790         ret_if(data == NULL);
791         /* Swap to opposite endian */
792         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
793                 temp = data[i];
794                 data[i] = data[j];
795                 data[j] = temp;
796                 }
797 }
798
799 int _bt_byte_arr_cmp(const char *data1, const char *data2, int data_len)
800 {
801         int i;
802
803         retv_if(data1 == NULL, -1);
804         retv_if(data2 == NULL, -1);
805         for (i = 0; i < data_len; i++) {
806                 if (data1[i] != data2[i])
807                         return data1[i] - data2[i];
808                 }
809         return 0;
810 }
811 int _bt_byte_arr_cmp_with_mask(const char *data1, const char *data2,
812         const char *mask, int data_len)
813 {
814         int i;
815         char a, b;
816
817         retv_if(data1 == NULL, -1);
818         retv_if(data2 == NULL, -1);
819         retv_if(mask == NULL, -1);
820         for (i = 0; i < data_len; i++) {
821                 a = data1[i] & mask[i];
822                 b = data2[i] & mask[i];
823                 if (a != b)
824                         return (int)(a - b);
825                 }
826         return 0;
827 }
828
829 void _bt_copy_remote_dev(bt_remote_dev_info_t * dev_info, remote_device_t * oal_device)
830 {
831         int i;
832         BT_INFO("+");
833
834         dev_info->address = g_new0(char, BT_ADDRESS_STRING_SIZE);
835         _bt_convert_addr_type_to_string(dev_info->address, oal_device->address.addr);
836         BT_INFO("Address [%s]", dev_info->address);
837
838         if(strlen(oal_device->name)== 0)
839                 dev_info->name = NULL;
840         else {
841                 dev_info->name = g_strdup(oal_device->name);
842                 _bt_truncate_non_utf8_chars(dev_info->name);
843                 BT_INFO("Name [%s]", dev_info->name);
844         }
845
846         dev_info->class = oal_device->cod;
847         BT_INFO("COD [%d]", dev_info->class);
848         dev_info->paired = oal_device->is_bonded;
849         BT_INFO("Is Bonded [%d]", dev_info->paired);
850         dev_info->connected = oal_device->is_connected;
851         BT_INFO("iS Connected [%d]", dev_info->connected);
852         dev_info->rssi = oal_device->rssi;
853         BT_INFO("RSSI [%d]", dev_info->rssi);
854         dev_info->addr_type = oal_device->type;
855         dev_info->uuid_count = oal_device->uuid_count;
856         BT_INFO("UUID Count [%d]", dev_info->uuid_count);
857         dev_info->trust = oal_device->is_trusted;
858
859         if (dev_info->uuid_count > 0)
860                 dev_info->uuids = g_new0(char *, dev_info->uuid_count);
861
862         /* Fill Remote Device Service List list */
863         for (i=0; i < dev_info->uuid_count; i++) {
864                 dev_info->uuids[i] = g_malloc0(BLUETOOTH_UUID_STRING_MAX);
865                 _bt_uuid_to_string((service_uuid_t *)&oal_device->uuid[i].uuid, dev_info->uuids[i]);
866                 BT_DBG("UUID size=%d value=%s", sizeof(dev_info->uuids[i]), dev_info->uuids[i]);
867         }
868
869         BT_INFO("-");
870 }
871
872 static void __bt_get_service_list(bt_remote_dev_info_t *info, bluetooth_device_info_t *dev)
873 {
874         int i;
875         char **uuids;
876         char **parts;
877
878         BT_DBG("+");
879
880         ret_if(info == NULL);
881         ret_if(dev == NULL);
882
883         uuids = info->uuids;
884         if(uuids == NULL) {
885                 BT_ERR("No UUID's");
886                 return;
887         }
888
889         dev->service_index = 0;
890         BT_DBG("Total UUID count [%d]", info->uuid_count);
891         for (i = 0; i < info->uuid_count; i++) {
892                 BT_DBG("UUID count [%d]", i);
893                 g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
894
895                 parts = g_strsplit(uuids[i], "-", -1);
896
897                 if (parts == NULL || parts[0] == NULL)
898                         break;
899
900                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
901                 g_strfreev(parts);
902
903                 dev->service_index++;
904         }
905
906         BT_DBG("-");
907 }
908
909 void _bt_copy_remote_device(bt_remote_dev_info_t *rem_dev, bluetooth_device_info_t *dev)
910 {
911         BT_DBG("+");
912
913         memset(dev, 0x00, sizeof(bluetooth_device_info_t));
914         __bt_get_service_list(rem_dev, dev);
915         _bt_convert_addr_string_to_type(dev->device_address.addr, rem_dev->address);
916         _bt_divide_device_class(&dev->device_class, rem_dev->class);
917         g_strlcpy(dev->device_name.name, rem_dev->name,
918                         BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
919         dev->rssi = rem_dev->rssi;
920         dev->trust = rem_dev->trust;
921         dev->paired = rem_dev->paired;
922         dev->connected = rem_dev->connected;
923
924         /* Fill Manufacturer data */
925         if (rem_dev->manufacturer_data_len > 0) {
926                 dev->manufacturer_data.data_len = rem_dev->manufacturer_data_len;
927                 memcpy(dev->manufacturer_data.data,
928                         rem_dev->manufacturer_data, rem_dev->manufacturer_data_len);
929         } else {
930                 dev->manufacturer_data.data_len = 0;
931         }
932         BT_DBG("-");
933 }
934
935 void _bt_service_print_dev_info(bluetooth_device_info_t *dev_info)
936 {
937         int i;
938
939         ret_if(dev_info == NULL);
940
941         _bt_print_device_address_t(&(dev_info->device_address));
942         BT_INFO("Device Name:[%s]", dev_info->device_name.name);
943         BT_INFO("Device Major Class:[0x%X]", dev_info->device_class.major_class);
944         BT_INFO("Device Minor Class:[0x%X]", dev_info->device_class.minor_class);
945         BT_INFO("Device Service Class:[0x%X]", dev_info->device_class.minor_class);
946         BT_INFO("Device Paired:[%s]", (dev_info->paired?"TRUE":"FALSE"));
947         BT_INFO("Device Trusted:[%s]", (dev_info->trust?"TRUE":"FALSE"));
948         BT_INFO("Device Connected:[%d]", dev_info->connected);
949         BT_INFO("Device Service index:[%d]", dev_info->service_index);
950         for (i = 0; i < dev_info->service_index; i++) {
951                 BT_INFO("Device Service List:[%d]", dev_info->service_list_array[i]);
952                 BT_INFO("Device UUID:[%s]", dev_info->uuids[i]);
953         }
954
955         BT_INFO("Device manufacturer data len:[%d]", dev_info->manufacturer_data.data_len);
956         for (i = 0; i < dev_info->manufacturer_data.data_len; i++)
957                 BT_INFO("%2.2X", dev_info->manufacturer_data.data[i]);
958 }
959
960 void _bt_uuid_to_string(service_uuid_t *p_uuid, char *str)
961 {
962     uint32_t uuid0, uuid4;
963     uint16_t uuid1, uuid2, uuid3, uuid5;
964
965     memcpy(&uuid0, &(p_uuid->uuid[0]), 4);
966     memcpy(&uuid1, &(p_uuid->uuid[4]), 2);
967     memcpy(&uuid2, &(p_uuid->uuid[6]), 2);
968     memcpy(&uuid3, &(p_uuid->uuid[8]), 2);
969     memcpy(&uuid4, &(p_uuid->uuid[10]), 4);
970     memcpy(&uuid5, &(p_uuid->uuid[14]), 2);
971
972     snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
973             ntohl(uuid0), ntohs(uuid1),
974             ntohs(uuid2), ntohs(uuid3),
975             ntohl(uuid4), ntohs(uuid5));
976     return;
977 }
978
979 /* Trim string at first non-utf8 char */
980 void _bt_truncate_non_utf8_chars(char * str)
981 {
982         guint i=0;
983         const char *ptr = NULL;
984
985         if (strlen(str) != 0) {
986                 if (!g_utf8_validate(str, -1, &ptr)) {
987                         while(*(str + i) != *ptr)
988                                 i++;
989                         *(str + i) = '\0';
990                 }
991         }
992 }