Implemented enable and disable Gatt watch notification
[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 #include <vconf.h>
38
39 #include "bluetooth-api.h"
40 #include "bt-service-common.h"
41
42 #include <oal-manager.h>
43
44 #ifdef TIZEN_FEATURE_BT_IPSP
45 static GDBusProxy *ipsp_proxy;
46 #endif
47 static GDBusConnection *system_conn;
48 static GDBusConnection *session_conn;
49 static GDBusProxy *manager_proxy_g;
50 static GDBusProxy *adapter_proxy_g;
51 static void *net_conn;
52
53 static GDBusProxy *adapter_properties_proxy;
54
55 static GDBusConnection *system_gconn = NULL;
56
57 GDBusConnection *_bt_gdbus_init_system_gconn(void)
58 {
59         GError *error = NULL;
60
61         dbus_threads_init_default();
62
63         if (system_gconn != NULL)
64                 return system_gconn;
65
66         system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
67
68         if (!system_gconn) {
69                 BT_ERR("Unable to connect to dbus: %s", error->message);
70                 g_clear_error(&error);
71         }
72
73         return system_gconn;
74 }
75
76 GDBusConnection *_bt_gdbus_get_system_gconn(void)
77 {
78         GDBusConnection *local_system_gconn = NULL;
79         GError *error = NULL;
80
81         if (system_gconn == NULL) {
82                 system_gconn = _bt_gdbus_init_system_gconn();
83         } else if (g_dbus_connection_is_closed(system_gconn)) {
84
85                 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
86
87                 if (!local_system_gconn) {
88                         BT_ERR("Unable to connect to dbus: %s", error->message);
89                         g_clear_error(&error);
90                 }
91
92                 system_gconn = local_system_gconn;
93         }
94
95         return system_gconn;
96 }
97
98 static GDBusProxy *__bt_init_manager_proxy(void)
99 {
100         GDBusProxy *proxy;
101
102         if (system_conn == NULL) {
103                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
104                 retv_if(system_conn == NULL, NULL);
105         }
106
107         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
108                                                                 NULL, BT_BLUEZ_NAME,
109                                                                 BT_MANAGER_PATH, BT_MANAGER_INTERFACE,  NULL, NULL);
110
111         retv_if(proxy == NULL, NULL);
112
113         manager_proxy_g = proxy;
114
115         return proxy;
116 }
117
118 static GDBusProxy *__bt_init_adapter_proxy(void)
119 {
120         GDBusProxy *manager_proxy;
121         GDBusProxy *proxy;
122         char *adapter_path = NULL;
123
124         if (system_conn == NULL) {
125                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
126                 retv_if(system_conn == NULL, NULL);
127         }
128
129         manager_proxy = _bt_get_manager_proxy();
130         retv_if(manager_proxy == NULL, NULL);
131
132         adapter_path = _bt_get_adapter_path();
133         retv_if(adapter_path == NULL, NULL);
134
135         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
136                                                                 NULL, BT_BLUEZ_NAME,
137                                                                 adapter_path, BT_ADAPTER_INTERFACE,  NULL, NULL);
138
139         g_free(adapter_path);
140
141         retv_if(proxy == NULL, NULL);
142
143         adapter_proxy_g = proxy;
144
145         return proxy;
146 }
147 #ifdef TIZEN_FEATURE_BT_IPSP
148 static GDBusProxy *__bt_init_ipsp_proxy(void)
149 {
150         BT_DBG("+");
151
152         GDBusConnection *g_conn;
153         GDBusProxy *proxy;
154         g_conn = _bt_gdbus_get_system_gconn();
155         retv_if(g_conn == NULL, NULL);
156         proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
157                                                                 NULL, BT_IPSP_NAME,
158                                                                 "/org/projectx/bt_ipsp", BT_IPSP_INTERFACE,  NULL, NULL);
159         if (!proxy) {
160                 BT_ERR("Unable to get proxy");
161                 return NULL;
162         }
163         ipsp_proxy = proxy;
164         BT_DBG("-");
165         return proxy;
166 }
167 #endif
168 static GDBusProxy *__bt_init_adapter_properties_proxy(void)
169 {
170         GDBusProxy *manager_proxy;
171         GDBusProxy *proxy;
172         char *adapter_path = NULL;
173
174         if (system_conn == NULL) {
175                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
176                 retv_if(system_conn == NULL, NULL);
177         }
178
179         manager_proxy = _bt_get_manager_proxy();
180         retv_if(manager_proxy == NULL, NULL);
181
182         adapter_path = _bt_get_adapter_path();
183         retv_if(adapter_path == NULL, NULL);
184
185         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
186                                                                         NULL, BT_BLUEZ_NAME,
187                                                                         adapter_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
188
189         g_free(adapter_path);
190
191         retv_if(proxy == NULL, NULL);
192
193         adapter_properties_proxy = proxy;
194
195         return proxy;
196 }
197
198 GDBusConnection *__bt_init_system_gconn(void)
199 {
200         if (system_conn == NULL)
201                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
202
203         return system_conn;
204 }
205
206 GDBusConnection *__bt_init_session_conn(void)
207 {
208         if (session_conn == NULL)
209                 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
210
211         return session_conn;
212 }
213
214 GDBusConnection *_bt_get_session_gconn(void)
215 {
216         return (session_conn) ? session_conn : __bt_init_session_conn();
217 }
218
219 GDBusConnection *_bt_get_system_gconn(void)
220 {
221         return (system_conn) ? system_conn : __bt_init_system_gconn();
222 }
223
224 GDBusConnection *_bt_get_system_conn(void)
225 {
226         GDBusConnection *g_conn;
227
228         if (system_conn == NULL)
229                 g_conn = __bt_init_system_gconn();
230         else
231                 g_conn = system_conn;
232
233         retv_if(g_conn == NULL, NULL);
234
235         return g_conn;
236 }
237
238 GDBusProxy *_bt_get_manager_proxy(void)
239 {
240         if (manager_proxy_g) {
241                 const gchar *path =  g_dbus_proxy_get_object_path(manager_proxy_g);
242                 if (path == NULL) {
243                         BT_ERR("Already proxy released hence creating new proxy");
244                         return  __bt_init_manager_proxy();
245                 }
246                 return manager_proxy_g;
247         }
248         return  __bt_init_manager_proxy();
249 }
250 #ifdef TIZEN_FEATURE_BT_IPSP
251 GDBusProxy *_bt_get_ipsp_proxy(void)
252 {
253         if (ipsp_proxy) {
254                 const char *path =  g_dbus_proxy_get_object_path(ipsp_proxy);
255                 if (path == NULL) {
256                         BT_ERR("Already proxy released hence creating new proxy");
257                         return  __bt_init_ipsp_proxy();
258                 }
259                 return ipsp_proxy;
260         }
261         return  __bt_init_ipsp_proxy();
262 }
263 #endif
264
265 static void *__bt_init_net_conn(void)
266 {
267         int result;
268         connection_h connection = NULL;
269
270         if (net_conn == NULL) {
271                 result = connection_create(&connection);
272
273         if (result != CONNECTION_ERROR_NONE ||
274                                         connection == NULL) {
275                 BT_DBG("connection_create() failed: %d", result);
276                 net_conn = NULL;
277                 return NULL;
278         }
279                 net_conn = connection;
280         }
281         return net_conn;
282 }
283
284 void *_bt_get_net_conn(void)
285 {
286         return (net_conn) ? net_conn : __bt_init_net_conn();
287 }
288
289 GDBusProxy *_bt_get_adapter_proxy(void)
290 {
291         if (adapter_proxy_g) {
292                 const char *path =  g_dbus_proxy_get_object_path(adapter_proxy_g);
293                 if (path == NULL) {
294                         BT_ERR("Already proxy released hence creating new proxy");
295                         return  __bt_init_adapter_proxy();
296                 }
297
298                 return adapter_proxy_g;
299         }
300         return  __bt_init_adapter_proxy();
301
302 }
303
304 GDBusProxy *_bt_get_adapter_properties_proxy(void)
305 {
306         return (adapter_properties_proxy) ? adapter_properties_proxy :
307                                         __bt_init_adapter_properties_proxy();
308 }
309
310 static char *__bt_extract_adapter_path(GVariantIter *iter)
311 {
312         char *object_path = NULL;
313         GVariantIter *interface_iter;
314         GVariantIter *svc_iter;
315         char *interface_str = NULL;
316
317         /* Parse the signature: oa{sa{sv}}} */
318         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
319                         &interface_iter)) {
320
321                 if (object_path == NULL)
322                         continue;
323
324                 while (g_variant_iter_loop(interface_iter, "{&sa{sv}}",
325                                 &interface_str, &svc_iter)) {
326                         if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
327                                 continue;
328
329                         BT_DBG("Object Path: %s", object_path);
330                         g_variant_iter_free(svc_iter);
331                         g_variant_iter_free(interface_iter);
332                         return g_strdup(object_path);
333                 }
334         }
335         return NULL;
336 }
337
338 char *_bt_get_adapter_path(void)
339 {
340         GDBusConnection *conn;
341         GDBusProxy *manager_proxy;
342         GVariant *result = NULL;
343         GVariantIter *iter = NULL;
344         char *adapter_path = NULL;
345
346         conn = _bt_get_system_conn();
347         retv_if(conn == NULL, NULL);
348
349         manager_proxy = _bt_get_manager_proxy();
350         retv_if(manager_proxy == NULL, NULL);
351
352         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
353                                 NULL,
354                                 G_DBUS_CALL_FLAGS_NONE,
355                                 -1,
356                                 NULL,
357                                 NULL);
358         if (!result) {
359                 BT_ERR("Can't get managed objects");
360                 return NULL;
361         }
362
363         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
364         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
365
366         adapter_path = __bt_extract_adapter_path(iter);
367         g_variant_iter_free(iter);
368         g_variant_unref(result);
369         return adapter_path;
370 }
371
372 void _bt_deinit_bluez_proxy(void)
373 {
374         if (manager_proxy_g) {
375                 g_object_unref(manager_proxy_g);
376                 manager_proxy_g = NULL;
377         }
378
379         if (adapter_proxy_g) {
380                 g_object_unref(adapter_proxy_g);
381                 adapter_proxy_g = NULL;
382         }
383         if (adapter_properties_proxy) {
384                 g_object_unref(adapter_properties_proxy);
385                 adapter_properties_proxy = NULL;
386         }
387 }
388
389 void _bt_deinit_proxys(void)
390 {
391         int ret;
392         _bt_deinit_bluez_proxy();
393
394         if (system_conn) {
395                 g_object_unref(system_conn);
396                 system_conn = NULL;
397         }
398
399         if (session_conn) {
400                 g_object_unref(session_conn);
401                 session_conn = NULL;
402         }
403
404         if (net_conn) {
405                 ret = connection_destroy(net_conn);
406                 net_conn = NULL;
407                 if (ret != 0)
408                         BT_ERR("connection_destroy failed : %d", ret);
409         }
410 }
411
412 void _bt_convert_device_path_to_address(const char *device_path,
413                                                 char *device_address)
414 {
415         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
416         char *dev_addr;
417
418         ret_if(device_path == NULL);
419         ret_if(device_address == NULL);
420
421         dev_addr = strstr(device_path, "dev_");
422         if (dev_addr != NULL) {
423                 char *pos = NULL;
424                 dev_addr += 4;
425                 g_strlcpy(address, dev_addr, sizeof(address));
426
427                 while ((pos = strchr(address, '_')) != NULL)
428                         *pos = ':';
429
430                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
431         }
432 }
433
434
435 void _bt_convert_addr_string_to_type(unsigned char *addr,
436                                         const char *address)
437 {
438         int i;
439         char *ptr = NULL;
440
441         ret_if(address == NULL);
442         ret_if(addr == NULL);
443
444         for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
445                 addr[i] = strtol(address, &ptr, 16);
446                 if (ptr[0] != '\0') {
447                         if (ptr[0] != ':')
448                                 return;
449
450                         address = ptr + 1;
451                 }
452         }
453 }
454
455 void _bt_convert_addr_type_to_string(char *address,
456                                 unsigned char *addr)
457 {
458         ret_if(address == NULL);
459         ret_if(addr == NULL);
460
461         snprintf(address, BT_ADDRESS_STRING_SIZE,
462                         "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
463                         addr[0], addr[1], addr[2],
464                         addr[3], addr[4], addr[5]);
465 }
466
467 gboolean _bt_compare_adddress(const bluetooth_device_address_t *addr1,
468                 const bluetooth_device_address_t *addr2)
469 {
470         if (memcmp(&addr1->addr, &addr2->addr, 6) == 0)
471                 return TRUE;
472         else
473                 return FALSE;
474 }
475
476 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
477 {
478         BT_INFO("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
479                 addr->addr[0], addr->addr[1], addr->addr[2],
480                 addr->addr[3], addr->addr[4], addr->addr[5]);
481 }
482
483 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
484                                 unsigned int cod)
485 {
486         ret_if(device_class == NULL);
487
488         device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
489         device_class->minor_class = (unsigned short)((cod & 0x000000FC));
490         device_class->service_class = (unsigned long)((cod & 0x00FF0000));
491
492         if (cod & 0x002000) {
493                 device_class->service_class |=
494                 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
495         }
496 }
497
498 void _bt_free_le_device_info(bt_remote_le_dev_info_t *le_dev_info)
499 {
500         ret_if(le_dev_info == NULL);
501
502         g_free(le_dev_info->adv_data);
503         g_free(le_dev_info);
504 }
505
506 int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
507 {
508         unsigned int i;
509         const char *p = src;
510         char *next;
511         int count;
512
513         if (dest == NULL || src == NULL)
514                 return BLUETOOTH_ERROR_INVALID_PARAM;
515
516         BT_DBG("+src : %s", src);
517         BT_DBG("+dest : %s", dest);
518
519         i = 0;
520         while (*p != '\0' && i < length) {
521                 next = g_utf8_next_char(p);
522                 count = next - p;
523
524                 while (count > 0 && ((i + count) < length)) {
525                         dest[i++] = *p;
526                         p++;
527                         count--;
528                 }
529                 p = next;
530         }
531         return BLUETOOTH_ERROR_NONE;
532 }
533
534 gboolean _bt_utf8_validate(char *name)
535 {
536         BT_DBG("+");
537         gunichar2 *u16;
538         glong items_written = 0;
539
540         if (FALSE == g_utf8_validate(name, -1, NULL))
541                 return FALSE;
542
543         u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
544         if (u16 == NULL)
545                 return FALSE;
546
547         g_free(u16);
548
549         if (items_written != g_utf8_strlen(name, -1))
550                 return FALSE;
551
552         BT_DBG("-");
553         return TRUE;
554 }
555
556 int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd)
557 {
558         BT_DBG("+");
559
560 #if TODO_40 /* Need to add this function */
561         if (!_bt_agent_register_osp_server(type, uuid, path, fd))
562                 return BLUETOOTH_ERROR_INTERNAL;
563 #endif
564         return BLUETOOTH_ERROR_NONE;
565 }
566
567 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
568 {
569         BT_DBG("+");
570
571 #if TODO_40 /* Need to add this function */
572         if (!_bt_agent_unregister_osp_server(type, uuid))
573                 return BLUETOOTH_ERROR_INTERNAL;
574 #endif
575         return BLUETOOTH_ERROR_NONE;
576 }
577
578 int _bt_set_socket_non_blocking(int socket_fd)
579 {
580         /* Set Nonblocking */
581         long arg;
582
583         arg = fcntl(socket_fd, F_GETFL);
584
585         if (arg < 0)
586                 return -errno;
587
588         if (arg & O_NONBLOCK)
589                 BT_ERR("Already Non-blocking \n");
590
591         arg |= O_NONBLOCK;
592
593         if (fcntl(socket_fd, F_SETFL, arg) < 0)
594                 return -errno;
595
596         return BLUETOOTH_ERROR_NONE;
597 }
598
599 int _bt_set_non_blocking_tty(int sk)
600 {
601         struct termios ti = {0,};
602         int err;
603
604         err = _bt_set_socket_non_blocking(sk);
605
606         if (err < 0) {
607                 BT_ERR("Error in set non blocking!\n");
608                 return err;
609         }
610
611         tcflush(sk, TCIOFLUSH);
612
613         /* Switch tty to RAW mode */
614         cfmakeraw(&ti);
615         tcsetattr(sk, TCSANOW, &ti);
616
617         return BLUETOOTH_ERROR_NONE;
618 }
619
620 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
621 {
622         char *object_path = NULL;
623         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
624
625         /* Parse the signature: oa{sa{sv}}} */
626         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
627                         NULL)) {
628                 retv_if(object_path == NULL, NULL);
629                 _bt_convert_device_path_to_address(object_path, device_address);
630                 if (g_strcmp0(address, device_address) == 0)
631                         return g_strdup(object_path);
632         }
633         return NULL;
634 }
635
636 char *_bt_get_device_object_path(char *address)
637 {
638         char *object_path = NULL;
639         GDBusConnection *conn;
640         GDBusProxy *manager_proxy;
641         GVariant *result = NULL;
642         GVariantIter *iter = NULL;
643
644         conn = _bt_get_system_conn();
645         retv_if(conn == NULL, NULL);
646
647         manager_proxy = _bt_get_manager_proxy();
648         retv_if(manager_proxy == NULL, NULL);
649
650         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
651                                 NULL,
652                                 G_DBUS_CALL_FLAGS_NONE,
653                                 -1,
654                                 NULL,
655                                 NULL);
656         if (!result) {
657                 BT_ERR("Can't get managed objects");
658                 return NULL;
659         }
660
661         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
662         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
663         object_path = __bt_extract_device_path(iter, address);
664         g_variant_iter_free(iter);
665         g_variant_unref(result);
666         return object_path;
667 }
668
669 char *_bt_get_profile_uuid128(bt_profile_type_t profile_type)
670 {
671         switch (profile_type) {
672         case BT_PROFILE_CONN_RFCOMM:
673                 return strdup(RFCOMM_UUID_STR);
674         case BT_PROFILE_CONN_A2DP:
675                 return strdup(A2DP_SINK_UUID);
676         case BT_PROFILE_CONN_A2DP_SINK:
677                 return strdup(A2DP_SOURCE_UUID);
678         case BT_PROFILE_CONN_HSP:
679                 return strdup(HFP_HS_UUID);
680         case BT_PROFILE_CONN_HID:
681                 return strdup(HID_UUID);
682         case BT_PROFILE_CONN_NAP:
683                 return strdup(NAP_UUID);
684         case BT_PROFILE_CONN_HFG:
685                 return strdup(HFP_AG_UUID);
686         case BT_PROFILE_CONN_GATT:
687         case BT_PROFILE_CONN_ALL: /* NULL UUID will connect to both the audio profiles*/
688         default:
689                 return NULL;
690         };
691 }
692
693 const char *_bt_convert_error_to_string(int error)
694 {
695         switch (error) {
696         case BLUETOOTH_ERROR_CANCEL:
697                 return "CANCELLED";
698         case BLUETOOTH_ERROR_INVALID_PARAM:
699                 return "INVALID_PARAMETER";
700         case BLUETOOTH_ERROR_INVALID_DATA:
701                 return "INVALID DATA";
702         case BLUETOOTH_ERROR_MEMORY_ALLOCATION:
703         case BLUETOOTH_ERROR_OUT_OF_MEMORY:
704                 return "OUT_OF_MEMORY";
705         case BLUETOOTH_ERROR_TIMEOUT:
706                 return "TIMEOUT";
707         case BLUETOOTH_ERROR_NO_RESOURCES:
708                 return "NO_RESOURCES";
709         case BLUETOOTH_ERROR_INTERNAL:
710                 return "INTERNAL";
711         case BLUETOOTH_ERROR_NOT_SUPPORT:
712                 return "NOT_SUPPORT";
713         case BLUETOOTH_ERROR_DEVICE_NOT_ENABLED:
714                 return "NOT_ENABLED";
715         case BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED:
716                 return "ALREADY_ENABLED";
717         case BLUETOOTH_ERROR_DEVICE_BUSY:
718                 return "DEVICE_BUSY";
719         case BLUETOOTH_ERROR_ACCESS_DENIED:
720                 return "ACCESS_DENIED";
721         case BLUETOOTH_ERROR_MAX_CLIENT:
722                 return "MAX_CLIENT";
723         case BLUETOOTH_ERROR_NOT_FOUND:
724                 return "NOT_FOUND";
725         case BLUETOOTH_ERROR_SERVICE_SEARCH_ERROR:
726                 return "SERVICE_SEARCH_ERROR";
727         case BLUETOOTH_ERROR_PARING_FAILED:
728                 return "PARING_FAILED";
729         case BLUETOOTH_ERROR_NOT_PAIRED:
730                 return "NOT_PAIRED";
731         case BLUETOOTH_ERROR_SERVICE_NOT_FOUND:
732                 return "SERVICE_NOT_FOUND";
733         case BLUETOOTH_ERROR_NOT_CONNECTED:
734                 return "NOT_CONNECTED";
735         case BLUETOOTH_ERROR_ALREADY_CONNECT:
736                 return "ALREADY_CONNECT";
737         case BLUETOOTH_ERROR_CONNECTION_BUSY:
738                 return "CONNECTION_BUSY";
739         case BLUETOOTH_ERROR_CONNECTION_ERROR:
740                 return "CONNECTION_ERROR";
741         case BLUETOOTH_ERROR_MAX_CONNECTION:
742                 return "MAX_CONNECTION";
743         case BLUETOOTH_ERROR_NOT_IN_OPERATION:
744                 return "NOT_IN_OPERATION";
745         case BLUETOOTH_ERROR_CANCEL_BY_USER:
746                 return "CANCEL_BY_USER";
747         case BLUETOOTH_ERROR_REGISTRATION_FAILED:
748                 return "REGISTRATION_FAILED";
749         case BLUETOOTH_ERROR_IN_PROGRESS:
750                 return "IN_PROGRESS";
751         case BLUETOOTH_ERROR_AUTHENTICATION_FAILED:
752                 return "AUTHENTICATION_FAILED";
753         case BLUETOOTH_ERROR_HOST_DOWN:
754                 return "HOST_DOWN";
755         case BLUETOOTH_ERROR_END_OF_DEVICE_LIST:
756                 return "END_OF_DEVICE_LIST";
757         case BLUETOOTH_ERROR_AGENT_ALREADY_EXIST:
758                 return "AGENT_ALREADY_EXIST";
759         case BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST:
760                 return "AGENT_DOES_NOT_EXIST";
761         case BLUETOOTH_ERROR_ALREADY_INITIALIZED:
762                 return "ALREADY_INITIALIZED";
763         case BLUETOOTH_ERROR_PERMISSION_DEINED:
764                 return "PERMISSION_DEINED";
765         case BLUETOOTH_ERROR_ALREADY_DEACTIVATED:
766                 return "ALREADY_DEACTIVATED";
767         case BLUETOOTH_ERROR_NOT_INITIALIZED:
768                 return "NOT_INITIALIZED";
769         default:
770                 return "UNKNOWN";
771         }
772 }
773
774 const char * _bt_convert_disc_reason_to_string(int reason)
775 {
776         switch (reason) {
777         case 1:
778                 return "Link loss";
779         case 2:
780                 return "Connection terminated by local host";
781         case 3:
782                 return "Remote user terminated connection";
783         case 0:
784         default:
785                 return "Unknown";
786         }
787 }
788
789 void _bt_logging_connection(gboolean connect, int addr_type)
790 {
791         static int le_conn = 0;
792         static int le_disc = 0;
793         static int edr_conn = 0;
794         static int edr_disc = 0;
795
796         if (connect) {
797                 if (addr_type)
798                         le_conn++;
799                 else
800                         edr_conn++;
801         } else {
802                 if (addr_type)
803                         le_disc++;
804                 else
805                         edr_disc++;
806         }
807
808         BT_INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
809                         le_conn, le_disc, edr_conn, edr_disc);
810 }
811
812 int _bt_eventsystem_set_value(const char *event, const char *key, const char *value)
813 {
814         int ret;
815         bundle *b = NULL;
816
817         b = bundle_create();
818
819         bundle_add_str(b, key, value);
820
821         ret = eventsystem_send_system_event(event, b);
822
823         BT_DBG("eventsystem_send_system_event result: %d", ret);
824
825         bundle_free(b);
826
827         return ret;
828 }
829
830 void _bt_swap_byte_ordering(char *data, int data_len)
831 {
832         char temp;
833         int i, j;
834
835         ret_if(data == NULL);
836         /* Swap to opposite endian */
837         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
838                 temp = data[i];
839                 data[i] = data[j];
840                 data[j] = temp;
841                 }
842 }
843
844 int _bt_byte_arr_cmp(const char *data1, const char *data2, int data_len)
845 {
846         int i;
847
848         retv_if(data1 == NULL, -1);
849         retv_if(data2 == NULL, -1);
850         for (i = 0; i < data_len; i++) {
851                 if (data1[i] != data2[i])
852                         return data1[i] - data2[i];
853                 }
854         return 0;
855 }
856 int _bt_byte_arr_cmp_with_mask(const char *data1, const char *data2,
857         const char *mask, int data_len)
858 {
859         int i;
860         char a, b;
861
862         retv_if(data1 == NULL, -1);
863         retv_if(data2 == NULL, -1);
864         retv_if(mask == NULL, -1);
865         for (i = 0; i < data_len; i++) {
866                 a = data1[i] & mask[i];
867                 b = data2[i] & mask[i];
868                 if (a != b)
869                         return (int)(a - b);
870                 }
871         return 0;
872 }
873
874 void _bt_copy_remote_dev(bt_remote_dev_info_t *dev_info, remote_device_t *oal_device)
875 {
876         unsigned int i;
877
878         BT_DBG("+");
879
880         dev_info->address = g_new0(char, BT_ADDRESS_STRING_SIZE);
881         _bt_convert_addr_type_to_string(dev_info->address, oal_device->address.addr);
882         BT_INFO("Address [%s]", dev_info->address);
883
884         if (strlen(oal_device->name) == 0)
885                 dev_info->name = NULL;
886         else {
887                 dev_info->name = g_strdup(oal_device->name);
888                 _bt_truncate_non_utf8_chars(dev_info->name);
889                 BT_INFO("Name [%s]", dev_info->name);
890         }
891
892         if (strlen(oal_device->alias) == 0) {
893                 dev_info->alias = NULL;
894         } else {
895                 dev_info->alias = g_strdup(oal_device->alias);
896                 _bt_truncate_non_utf8_chars(dev_info->alias);
897                 BT_INFO("Alias [%s]", dev_info->alias);
898         }
899
900         dev_info->class = oal_device->cod;
901         dev_info->paired = oal_device->is_bonded;
902         BT_INFO("Is Bonded [%d]", dev_info->paired);
903         dev_info->connected = oal_device->is_connected;
904         BT_INFO("iS Connected [%d]", dev_info->connected);
905         dev_info->rssi = oal_device->rssi;
906         dev_info->addr_type = oal_device->type;
907         dev_info->uuid_count = oal_device->uuid_count;
908         BT_INFO("UUID Count [%d]", dev_info->uuid_count);
909         dev_info->trust = ((oal_device->is_trusted == 0) ? FALSE : TRUE);
910
911         if (dev_info->uuid_count > 0)
912                 dev_info->uuids = g_new0(char *, dev_info->uuid_count);
913
914         /* Fill Remote Device Service List list */
915         for (i = 0; i < dev_info->uuid_count; i++) {
916                 dev_info->uuids[i] = g_malloc0(BLUETOOTH_UUID_STRING_MAX);
917                 _bt_uuid_to_string((service_uuid_t *)&oal_device->uuid[i].uuid, dev_info->uuids[i]);
918         }
919
920         dev_info->vid = (unsigned short)oal_device->vid;
921         dev_info->pid = (unsigned short)oal_device->pid;
922         dev_info->device_type = (int)oal_device->type;
923         dev_info->is_alias_set = ((oal_device->is_alias_set == 0) ? FALSE : TRUE);
924
925         BT_DBG("-");
926 }
927
928 void _bt_free_remote_dev(bt_remote_dev_info_t *dev_info)
929 {
930         unsigned int c;
931
932         ret_if(NULL == dev_info);
933
934         BT_INFO("+");
935
936         g_free(dev_info->address);
937         g_free(dev_info->name);
938         g_free(dev_info->alias);
939         g_free(dev_info->manufacturer_data);
940
941         for (c = 0; c < dev_info->uuid_count; c++)
942                 g_free(dev_info->uuids[c]);
943         g_free(dev_info->uuids);
944         g_free(dev_info);
945
946         BT_INFO("-");
947 }
948
949 static void __bt_get_service_list(bt_remote_dev_info_t *info, bluetooth_device_info_t *dev)
950 {
951         unsigned int i;
952         char **uuids;
953         char **parts;
954
955         BT_DBG("+");
956
957         ret_if(info == NULL);
958         ret_if(dev == NULL);
959
960         uuids = info->uuids;
961         if (uuids == NULL) {
962                 BT_ERR("No UUID's");
963                 return;
964         }
965
966         dev->service_index = 0;
967         BT_DBG("Total UUID count [%d]", info->uuid_count);
968         for (i = 0; i < info->uuid_count; i++) {
969                 g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
970
971                 parts = g_strsplit(uuids[i], "-", -1);
972
973                 if (parts == NULL || parts[0] == NULL)
974                         break;
975
976                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
977                 g_strfreev(parts);
978
979                 dev->service_index++;
980         }
981
982         BT_DBG("-");
983 }
984
985 void _bt_copy_remote_device(bt_remote_dev_info_t *rem_dev, bluetooth_device_info_t *dev)
986 {
987         BT_DBG("+");
988
989         memset(dev, 0x00, sizeof(bluetooth_device_info_t));
990         __bt_get_service_list(rem_dev, dev);
991         _bt_convert_addr_string_to_type(dev->device_address.addr, rem_dev->address);
992         _bt_divide_device_class(&dev->device_class, rem_dev->class);
993
994         if (rem_dev->alias) {
995                 g_strlcpy(dev->device_name.name, rem_dev->alias,
996                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
997                 BT_DBG("Name: %s", dev->device_name.name);
998         } else {
999                 g_strlcpy(dev->device_name.name, rem_dev->name,
1000                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1001                 BT_DBG("Name: %s", dev->device_name.name);
1002         }
1003
1004         dev->rssi = rem_dev->rssi;
1005         dev->trust = rem_dev->trust;
1006         dev->paired = rem_dev->paired;
1007         dev->connected = rem_dev->connected;
1008         dev->is_alias_set = rem_dev->is_alias_set;
1009
1010         /* Fill Manufacturer data */
1011         if (rem_dev->manufacturer_data_len > 0) {
1012                 dev->manufacturer_data.data_len = rem_dev->manufacturer_data_len;
1013                 memcpy(dev->manufacturer_data.data,
1014                         rem_dev->manufacturer_data, rem_dev->manufacturer_data_len);
1015         } else {
1016                 dev->manufacturer_data.data_len = 0;
1017         }
1018
1019         BT_DBG("-");
1020 }
1021
1022 void _bt_service_print_dev_info(bluetooth_device_info_t *dev_info)
1023 {
1024         int i;
1025
1026         ret_if(dev_info == NULL);
1027
1028         _bt_print_device_address_t(&(dev_info->device_address));
1029         BT_INFO("Device Name:[%s]", dev_info->device_name.name);
1030         BT_INFO("Device Major Class:[0x%X]", dev_info->device_class.major_class);
1031         BT_INFO("Device Minor Class:[0x%X]", dev_info->device_class.minor_class);
1032         BT_INFO("Device Service Class:[0x%X]", dev_info->device_class.minor_class);
1033         BT_INFO("Device Paired:[%s]", (dev_info->paired ? "TRUE" : "FALSE"));
1034         BT_INFO("Device Trusted:[%s]", (dev_info->trust ? "TRUE" : "FALSE"));
1035         BT_INFO("Device Connected:[%d]", dev_info->connected);
1036         BT_INFO("Device Service index:[%d]", dev_info->service_index);
1037         for (i = 0; i < dev_info->service_index; i++) {
1038                 BT_INFO("Device Service List:[%d]", dev_info->service_list_array[i]);
1039                 BT_INFO("Device UUID:[%s]", dev_info->uuids[i]);
1040         }
1041
1042         BT_INFO("Device manufacturer data len:[%d]", dev_info->manufacturer_data.data_len);
1043         for (i = 0; i < dev_info->manufacturer_data.data_len; i++)
1044                 BT_INFO("%2.2X", dev_info->manufacturer_data.data[i]);
1045 }
1046
1047 void _bt_uuid_to_string(service_uuid_t *p_uuid, char *str)
1048 {
1049         uint32_t uuid0, uuid4;
1050         uint16_t uuid1, uuid2, uuid3, uuid5;
1051
1052         memcpy(&uuid0, &(p_uuid->uuid[0]), 4);
1053         memcpy(&uuid1, &(p_uuid->uuid[4]), 2);
1054         memcpy(&uuid2, &(p_uuid->uuid[6]), 2);
1055         memcpy(&uuid3, &(p_uuid->uuid[8]), 2);
1056         memcpy(&uuid4, &(p_uuid->uuid[10]), 4);
1057         memcpy(&uuid5, &(p_uuid->uuid[14]), 2);
1058
1059         snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
1060                         ntohl(uuid0), ntohs(uuid1),
1061                         ntohs(uuid2), ntohs(uuid3),
1062                         ntohl(uuid4), ntohs(uuid5));
1063         return;
1064 }
1065
1066 void _bt_string_to_uuid(char *str, service_uuid_t *p_uuid)
1067 {
1068         uint32_t uuid0, uuid4;
1069         uint16_t uuid1, uuid2, uuid3, uuid5;
1070
1071         sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
1072                         &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
1073
1074         uuid0 = htonl(uuid0);
1075         uuid1 = htons(uuid1);
1076         uuid2 = htons(uuid2);
1077         uuid3 = htons(uuid3);
1078         uuid4 = htonl(uuid4);
1079         uuid5 = htons(uuid5);
1080
1081         memcpy(&(p_uuid->uuid[0]), &uuid0, 4);
1082         memcpy(&(p_uuid->uuid[4]), &uuid1, 2);
1083         memcpy(&(p_uuid->uuid[6]), &uuid2, 2);
1084         memcpy(&(p_uuid->uuid[8]), &uuid3, 2);
1085         memcpy(&(p_uuid->uuid[10]), &uuid4, 4);
1086         memcpy(&(p_uuid->uuid[14]), &uuid5, 2);
1087
1088         return;
1089 }
1090
1091 void _bt_convert_byte_ordering(char *data, int data_len,
1092                 char *converted_data)
1093 {
1094         int i, j;
1095         char temp[BT_UUID_LEN];
1096
1097         memcpy(&temp, data, data_len);
1098         for (i = 0, j = data_len - 1; i < data_len; i++, j--)
1099                 converted_data[i] = temp[j];
1100
1101 }
1102
1103 /* Trim string at first non-utf8 char */
1104 void _bt_truncate_non_utf8_chars(char * str)
1105 {
1106         guint i = 0;
1107         const char *ptr = NULL;
1108
1109         if (strlen(str) != 0) {
1110                 if (!g_utf8_validate(str, -1, &ptr)) {
1111                         while (*(str + i) != *ptr)
1112                                 i++;
1113                         *(str + i) = '\0';
1114                 }
1115         }
1116 }
1117
1118 invocation_info_t* _bt_get_request_info_data(int service_function, char *address)
1119 {
1120         GSList *l;
1121         invocation_info_t *req_info = NULL;
1122
1123         BT_DBG("+");
1124
1125         retv_if(NULL == address, NULL);
1126
1127         /* Get method invocation context */
1128         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1129                 req_info = l->data;
1130                 if (req_info == NULL || req_info->service_function != service_function)
1131                         continue;
1132
1133                 if (!strncasecmp((char *)req_info->user_data, address, BT_ADDRESS_STRING_SIZE))
1134                         return req_info;
1135         }
1136
1137         BT_DBG("-");
1138         return NULL;
1139 }
1140
1141 #ifdef TIZEN_GATT_CLIENT
1142 invocation_info_t* _bt_get_request_info_data_from_function_name(int service_function)
1143 {
1144         GSList *l;
1145         invocation_info_t *req_info = NULL;
1146
1147         BT_DBG("+");
1148
1149         /* Get method invocation context */
1150         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1151                 req_info = l->data;
1152                 if (req_info == NULL || req_info->service_function != service_function)
1153                         continue;
1154                 return req_info;
1155         }
1156
1157         BT_DBG("-");
1158         return NULL;
1159 }
1160 #endif
1161
1162 void _bt_set_device_values(gboolean connected, int state)
1163 {
1164         int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
1165
1166         if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) != 0)
1167                 BT_ERR("vconf_get_int failed");
1168
1169         if (connected == TRUE)
1170                 bt_device_state |= state;
1171         else if (bt_device_state & state)
1172                 bt_device_state ^= state;
1173
1174         if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0)
1175                 BT_ERR("vconf_set_int failed");
1176 }
1177
1178 int _bt_get_ad_data_by_type(char *in_data, int in_len,
1179                 char in_type, char **data, int *data_len)
1180 {
1181         if (in_data == NULL || data == NULL || data_len == NULL)
1182                 return BLUETOOTH_ERROR_INVALID_PARAM;
1183
1184         if (in_len < 0)
1185                 return BLUETOOTH_ERROR_INVALID_PARAM;
1186
1187         int i;
1188         int len = 0;
1189         int type = 0;
1190
1191         for (i = 0; i < in_len; i++) {
1192                 len = in_data[i];
1193                 if (len <= 0 || i + 1 >= in_len) {
1194                         BT_ERR("Invalid advertising data");
1195                         return BLUETOOTH_ERROR_INVALID_PARAM;
1196                 }
1197
1198                 type = in_data[i + 1];
1199                 if (type == in_type) {
1200                         i = i + 2;
1201                         len--;
1202                         break;
1203                 }
1204
1205                 i += len;
1206                 len = 0;
1207         }
1208
1209         if (i + len > in_len) {
1210                 BT_ERR("Invalid advertising data");
1211                 return BLUETOOTH_ERROR_INVALID_PARAM;
1212         } else if (len == 0) {
1213                 BT_INFO("AD Type 0x%02x data is not set", in_type);
1214                 *data = NULL;
1215                 *data_len = 0;
1216                 return BLUETOOTH_ERROR_NONE;
1217         }
1218
1219         *data = g_memdup(&in_data[i], len);
1220         if (*data == NULL)
1221                 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
1222         *data_len = len;
1223
1224         return BLUETOOTH_ERROR_NONE;
1225 }
1226
1227 void _bt_copy_remote_dev_info(bt_remote_dev_info_t *dest, bt_remote_dev_info_t *src)
1228 {
1229         BT_DBG("+");
1230
1231         ret_if(NULL == src);
1232
1233         if (!dest->address) {
1234                 dest->address = g_strdup(src->address);
1235                 BT_DBG("Address: [%s]", dest->address);
1236         }
1237
1238         if (src->name) {
1239                 g_free(dest->name);
1240                 dest->name = g_strdup(src->name);
1241                 BT_DBG("Name: [%s]", dest->name);
1242         }
1243
1244         if (src->alias) {
1245                 g_free(dest->alias);
1246                 dest->alias = g_strdup(src->alias);
1247                 BT_DBG("Alias: [%s]", dest->alias);
1248         }
1249
1250         if (src->uuid_count > 0 && src->uuids) {
1251                 int i;
1252
1253                 /* Release previously allocated UUIDs */
1254                 if (dest->uuid_count > 0 && dest->uuids)
1255                         for (i = 0; i < dest->uuid_count; i++)
1256                                 g_free(dest->uuids[i]);
1257                 g_free(dest->uuids);
1258
1259                 /* Copy new UUID list */
1260                 dest->uuids = g_malloc0(src->uuid_count * sizeof(char *));
1261                 for (i = 0; i < src->uuid_count; i++)
1262                         dest->uuids[i] = g_strdup(src->uuids[i]);
1263
1264                 dest->uuid_count = src->uuid_count;
1265                 BT_DBG("UUID count: %d", dest->uuid_count);
1266         }
1267
1268         if (src->manufacturer_data_len > 0 && src->manufacturer_data) {
1269                 BT_DBG("Manufacturer data length: %d", dest->manufacturer_data_len);
1270                 if (dest->manufacturer_data)
1271                         g_free(dest->manufacturer_data);
1272
1273                 dest->manufacturer_data_len = src->manufacturer_data_len;
1274                 dest->manufacturer_data = g_memdup(
1275                         src->manufacturer_data, src->manufacturer_data_len);
1276                 BT_DBG("Manufacturer data length: %d", dest->manufacturer_data_len);
1277         }
1278
1279         dest->rssi = src->rssi;
1280         dest->class = src->class;
1281         dest->paired = src->paired;
1282         dest->connected = src->connected;
1283         dest->trust = src->trust;
1284         dest->addr_type = src->addr_type;
1285         dest->vid = src->vid;
1286         dest->pid = src->pid;
1287         dest->device_type = src->device_type;
1288         dest->is_alias_set = src->is_alias_set;
1289
1290         BT_DBG("-");
1291 }