Modify flora license version from 1.0 to 1.1 in the source codes
[apps/native/ug-bluetooth-efl.git] / common / src / libraries / bt-util.c
1 /*
2 * ug-bluetooth-efl
3 *
4 * Copyright 2012 Samsung Electronics Co., Ltd
5 *
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 *           GirishAshok Joshi <girish.joshi@samsung.com>
8 *           DoHyun Pyun <dh79.pyun@samsung.com>
9 *
10 * Licensed under the Flora License, Version 1.1 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.tizenopensource.org/license
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 */
23
24 #include <bluetooth.h>
25 #include <bluetooth_internal.h>
26 #include <vconf.h>
27 #include <aul.h>
28 #include <notification.h>
29 #include <dpm/restriction.h>
30
31 // #ifndef TIZEN_PROFILE_TV
32 #include <contacts.h>
33 #include <dirent.h>
34 #include <fcntl.h>
35 // #endif
36
37 #include <stdlib.h>
38 #include <system_info.h>
39
40 #include "bt-main-ug.h"
41 #include "bt-util.h"
42 #include "bt-debug.h"
43 #include "bt-string-define.h"
44 #include "bt-net-connection.h"
45 #include "bt-widget.h"
46
47 /**********************************************************************
48 *                                                Common Functions
49 ***********************************************************************/
50
51 gboolean _bt_util_update_class_of_device_by_service_list(bt_service_class_t service_list,
52                                                  bt_major_class_t *major_class,
53                                                  bt_minor_class_t *minor_class)
54 {
55         FN_START;
56
57         retvm_if(service_list == BT_SC_NONE, FALSE,
58                  "Invalid argument: service_list is NULL");
59
60         /* set Major class */
61         if (service_list & BT_SC_HFP_SERVICE_MASK ||
62                 service_list & BT_SC_HSP_SERVICE_MASK ||
63 #ifdef TIZEN_BT_A2DP_SINK_ENABLE
64                 service_list & BT_SC_A2DP_SOURCE_SERVICE_MASK ||
65 #endif
66                 service_list & BT_SC_A2DP_SERVICE_MASK) /* Handsfree device */
67                 *major_class = BT_MAJOR_DEV_CLS_AUDIO;
68         else if (service_list & BT_SC_NAP_SERVICE_MASK ||
69                         service_list & BT_SC_PANU_SERVICE_MASK)
70                 *major_class = BT_MAJOR_DEV_CLS_PHONE;
71
72         /* set Minor class */
73         if (service_list & BT_SC_HFP_SERVICE_MASK ||
74                         service_list & BT_SC_HSP_SERVICE_MASK)
75                 *minor_class = BTAPP_MIN_DEV_CLS_HEADSET_PROFILE;
76         else if (service_list & BT_SC_A2DP_SERVICE_MASK)
77                 *minor_class = BTAPP_MIN_DEV_CLS_HEADPHONES;
78         else if (service_list & BT_SC_NAP_SERVICE_MASK ||
79                         service_list & BT_SC_PANU_SERVICE_MASK)
80                 *minor_class = BTAPP_MIN_DEV_CLS_SMART_PHONE;
81
82         BT_DBG("Updated major_class = %x, minor_class = %x", *major_class,
83                *minor_class);
84
85         FN_END;
86         return TRUE;
87 }
88
89 void _bt_util_set_value(const char *req, unsigned int *search_type,
90                         unsigned int *op_mode)
91 {
92         FN_START;
93         ret_if(req == NULL);
94         ret_if(search_type == NULL);
95         ret_if(op_mode == NULL);
96
97         if (!strcasecmp(req, "send") || !strcasecmp(req, "browse")) {
98                 *search_type = BT_COD_SC_OBJECT_TRANSFER;
99                 *op_mode = BT_LAUNCH_SEND_FILE;
100         } else if (!strcasecmp(req, "print")) {
101                 *search_type = BT_DEVICE_MAJOR_MASK_IMAGING;
102                 *op_mode = BT_LAUNCH_PRINT_IMAGE;
103         } else if (!strcasecmp(req, "call") || !strcasecmp(req, "sound")) {
104                 *search_type = BT_DEVICE_MAJOR_MASK_AUDIO;
105                 *op_mode = BT_LAUNCH_CONNECT_HEADSET;
106         } else if (!strcasecmp(req, "connect_source")) {
107                 *search_type = BT_DEVICE_MAJOR_MASK_AUDIO;
108                 *op_mode = BT_LAUNCH_CONNECT_AUDIO_SOURCE;
109         } else if (!strcasecmp(req, "nfc")) {
110                 *search_type = BT_DEVICE_MAJOR_MASK_MISC;
111                 *op_mode = BT_LAUNCH_USE_NFC;
112         } else if (!strcasecmp(req, "pick")) {
113                 *search_type = BT_DEVICE_MAJOR_MASK_MISC;
114                 *op_mode = BT_LAUNCH_PICK;
115         } else if (!strcasecmp(req, "visibility")) {
116                 *search_type = BT_DEVICE_MAJOR_MASK_MISC;
117                 *op_mode = BT_LAUNCH_VISIBILITY;
118         } else if (!strcasecmp(req, "onoff")) {
119                 *search_type = BT_DEVICE_MAJOR_MASK_MISC;
120                 *op_mode = BT_LAUNCH_ONOFF;
121         } else if (!strcasecmp(req, "contact")) {
122                 *search_type = BT_COD_SC_OBJECT_TRANSFER;
123                 *op_mode = BT_LAUNCH_SHARE_CONTACT;
124         } else if (!strcasecmp(req, "help")) {
125                 *search_type = BT_DEVICE_MAJOR_MASK_MISC;
126                 *op_mode = BT_LAUNCH_HELP;
127         } else {
128                 *search_type = BT_DEVICE_MAJOR_MASK_MISC;
129                 *op_mode = BT_LAUNCH_NORMAL;
130         }
131
132         FN_END;
133
134         return;
135 }
136
137 gboolean _bt_util_store_get_value(const char *key, bt_store_type_t store_type,
138                               unsigned int size, void *value)
139 {
140         FN_START;
141         retv_if(value == NULL, FALSE);
142
143         int ret = 0;
144         int int_value = 0;
145         int *intval = NULL;
146         gboolean *boolean = FALSE;
147         char *str = NULL;
148
149         switch (store_type) {
150         case BT_STORE_BOOLEAN:
151                 boolean = (gboolean *)value;
152                 ret = vconf_get_bool(key, &int_value);
153                 if (ret != 0) {
154                         BT_ERR("Get bool is failed");
155                         *boolean = FALSE;
156                         return FALSE;
157                 }
158                 *boolean = (int_value != FALSE);
159                 break;
160         case BT_STORE_INT:
161                 intval = (int *)value;
162                 ret = vconf_get_int(key, intval);
163                 if (ret != 0) {
164                         BT_ERR("Get int is failed");
165                         *intval = 0;
166                         return FALSE;
167                 }
168                 break;
169         case BT_STORE_STRING:
170                 str = vconf_get_str(key);
171                 if (str == NULL) {
172                         BT_ERR("Get string is failed");
173                         return FALSE;
174                 }
175                 if (size > 1)
176                         strncpy((char *)value, str, size - 1);
177
178                 free(str);
179                 break;
180         default:
181                 BT_ERR("Unknown Store Type");
182                 return FALSE;
183         }
184
185         FN_END;
186         return TRUE;
187 }
188
189 void _bt_util_set_phone_name(void)
190 {
191         char *phone_name = NULL;
192         char *ptr = NULL;
193
194         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
195         if (!phone_name)
196                 return;
197
198         if (strlen(phone_name) != 0) {
199                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
200                         *ptr = '\0';
201
202                 bt_adapter_set_name(phone_name);
203         }
204
205         free(phone_name);
206 }
207
208 int _bt_util_get_phone_name(char *phone_name, int size)
209 {
210         FN_START;
211         retv_if(phone_name == NULL, BT_UG_FAIL);
212
213         if (_bt_util_store_get_value(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
214                                  BT_STORE_STRING, size,
215                                  (void *)phone_name) < 0) {
216                 g_strlcpy(phone_name, BT_DEFAULT_PHONE_NAME, size);
217         }
218
219         FN_END;
220         return BT_UG_ERROR_NONE;
221 }
222
223 char * _bt_util_get_timeout_string(int timeout)
224 {
225         FN_START;
226         char *string = NULL;
227         switch (timeout) {
228         case BT_ZERO:
229                 string = g_strdup(BT_STR_OFF);
230                 break;
231         case BT_TWO_MINUTES:
232                 string = g_strdup(BT_STR_TWO_MINUTES);
233                 break;
234         case BT_FIVE_MINUTES:
235                 string = g_strdup(BT_STR_FIVE_MINUTES);
236                 break;
237         case BT_ONE_HOUR:
238                 string = g_strdup(BT_STR_ONE_HOUR);
239                 break;
240         case BT_ALWAYS_ON:
241                 string = g_strdup(BT_STR_ALWAYS_ON);
242                 break;
243         default:
244                 string = g_strdup(BT_STR_OFF);
245                 break;
246         }
247
248         FN_END;
249         return string;
250 }
251
252 int _bt_util_get_timeout_value(int index)
253 {
254         FN_START;
255
256         int timeout;
257
258         switch (index) {
259         case 1:
260                 timeout = BT_ZERO;
261                 break;
262         case 2:
263                 timeout = BT_TWO_MINUTES;
264                 break;
265         case 3:
266                 timeout = BT_FIVE_MINUTES;
267                 break;
268         case 4:
269                 timeout = BT_ONE_HOUR;
270                 break;
271         case 5:
272                 timeout = BT_ALWAYS_ON;
273                 break;
274         default:
275                 timeout = BT_ZERO;
276                 break;
277         }
278
279         FN_END;
280         return timeout;
281 }
282
283 int _bt_util_get_timeout_index(int timeout)
284 {
285         FN_START;
286
287         int index = 0;
288
289         switch (timeout) {
290         case BT_ZERO:
291                 index = 1;
292                 break;
293         case BT_TWO_MINUTES:
294                 index = 2;
295                 break;
296         case BT_FIVE_MINUTES:
297                 index = 3;
298                 break;
299         case BT_ONE_HOUR:
300                 index = 4;
301                 break;
302         case BT_ALWAYS_ON:
303                 index = 5;
304                 break;
305         default:
306                 index = 1;
307                 break;
308         }
309
310         BT_DBG("index: %d", index);
311
312         FN_END;
313         return index;
314 }
315
316 gboolean _bt_util_is_battery_low(void)
317 {
318         FN_START;
319
320         int value = 0;
321         int charging = 0;
322
323         if (TIZEN_COMMON)
324                 return FALSE;
325
326         if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, (void *)&charging))
327                 BT_ERR("Get the battery charging status fail");
328
329         if (charging == 1)
330                 return FALSE;
331
332         BT_DBG("charging: %d", charging);
333
334         if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, (void *)&value)) {
335                 BT_ERR("Get the battery low status fail");
336                 return FALSE;
337         }
338
339         if (value <= VCONFKEY_SYSMAN_BAT_POWER_OFF)
340                 return TRUE;
341
342         FN_END;
343         return FALSE;
344 }
345
346 void _bt_util_addr_type_to_addr_string(char *address,
347                                                unsigned char *addr)
348 {
349         FN_START;
350
351         ret_if(address == NULL);
352         ret_if(addr == NULL);
353
354         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", addr[0],
355                 addr[1], addr[2], addr[3], addr[4], addr[5]);
356
357         FN_END;
358 }
359
360 void _bt_util_addr_type_to_addr_result_string(char *address,
361                                                unsigned char *addr)
362 {
363         FN_START;
364
365         ret_if(address == NULL);
366         ret_if(addr == NULL);
367
368         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X-%2.2X-%2.2X-%2.2X-%2.2X-%2.2X", addr[0],
369                 addr[1], addr[2], addr[3], addr[4], addr[5]);
370
371         FN_END;
372 }
373
374 void _bt_util_addr_type_to_addr_net_string(char *address,
375                                                unsigned char *addr)
376 {
377         FN_START;
378
379         ret_if(address == NULL);
380         ret_if(addr == NULL);
381
382         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
383                 addr[1], addr[2], addr[3], addr[4], addr[5]);
384
385         FN_END;
386 }
387
388 void _bt_util_addr_string_to_addr_type(unsigned char *addr,
389                                                   const char *address)
390 {
391         FN_START
392
393         int i;
394         char *ptr = NULL;
395
396         if (!address || !addr)
397                 return;
398
399         for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
400                 addr[i] = strtol(address, &ptr, 16);
401                 if (ptr[0] != '\0') {
402                         if (ptr[0] != ':') {
403                                 BT_ERR("Unexpected string");
404                                 return;
405                         }
406                         address = ptr + 1;
407                 }
408         }
409
410         FN_END;
411 }
412
413 void _bt_util_convert_time_to_string(unsigned int remain_time,
414                                         char *text_display, char *text_read,
415                                         int size_display, int size_read)
416 {
417         FN_START;
418         int minute;
419         int second;
420
421         ret_if(remain_time > BT_TIMEOUT_MAX);
422
423         /* Get seconds */
424         second = remain_time % 60;
425
426         /* Get minutes */
427         minute = remain_time / 60;
428
429         if (size_display == BT_EXTRA_STR_LEN && text_display != NULL)
430                 snprintf(text_display, size_display, "%d:%02d", minute, second);
431
432         if (size_read == BT_BUFFER_LEN && text_read != NULL) {
433                 char min_part[BT_BUFFER_LEN] = { 0, };
434                 char sec_part[BT_BUFFER_LEN] = { 0, };
435
436                 /*Set minute Text*/
437                 if (minute == 1)
438                         snprintf(min_part, BT_BUFFER_LEN, "%s",
439                                         BT_STR_1_MINUTE);
440                 else if (minute > 1)
441                         snprintf(min_part, BT_BUFFER_LEN, "%d %s",
442                                         minute, BT_STR_MINUTES);
443
444                 /*Set second Text*/
445                 if (second == 1)
446                         snprintf(sec_part, BT_BUFFER_LEN, "%s",
447                                         BT_STR_1_SECOND);
448                 else if (second > 1)
449                         snprintf(sec_part, BT_BUFFER_LEN, "%d %s",
450                                         second, BT_STR_SECONDS);
451
452                 snprintf(text_read, size_read, "%s %s", min_part, sec_part);
453         }
454         FN_END;
455 }
456
457 void _bt_util_launch_no_event(void *data, void *obj, void *event)
458 {
459         FN_START;
460         BT_DBG
461             ("End key is pressed. But there is no action to process in popup");
462         FN_END;
463 }
464
465 void _bt_util_set_list_disabled(Evas_Object *genlist, Eina_Bool disable)
466 {
467         FN_START;
468         Elm_Object_Item *item = NULL;
469         Elm_Object_Item *next = NULL;
470
471         item = elm_genlist_first_item_get(genlist);
472
473         while (item != NULL) {
474                 next = elm_genlist_item_next_get(item);
475                 if (item)
476                         elm_object_item_disabled_set(item, disable);
477
478                 _bt_update_genlist_item(item);
479                 item = next;
480         }
481         FN_END;
482 }
483
484 gboolean _bt_util_is_profile_connected(int connected_type, unsigned char *addr)
485 {
486         FN_START;
487         char addr_str[BT_ADDRESS_STR_LEN + 1] = { 0 };
488         gboolean connected = FALSE;
489         int ret = 0;
490         int connected_profiles = 0x00;
491         bt_profile_e profile;
492
493         retv_if(addr == NULL, FALSE);
494
495         _bt_util_addr_type_to_addr_string(addr_str, addr);
496
497         BT_DBG("connected profiles: %d connected type : %d", connected_profiles,
498                         connected_type);
499
500         switch (connected_type) {
501         case BT_HEADSET_CONNECTED:
502                 profile = BT_PROFILE_HSP;
503                 break;
504         case BT_STEREO_HEADSET_CONNECTED:
505                 profile = BT_PROFILE_A2DP;
506                 break;
507         case BT_MUSIC_PLAYER_CONNECTED:
508                 profile = BT_PROFILE_A2DP_SINK;
509                 break;
510         case BT_HID_CONNECTED:
511                 profile = BT_PROFILE_HID;
512                 break;
513         case BT_LE_HID_CONNECTED:
514                 if (TIZEN_FEATURE_BT_HOG) {
515                         profile = BT_PROFILE_GATT;
516                         break;
517                 } else {
518                         goto _default_;
519                 }
520         case BT_NETWORK_CONNECTED:
521                 profile = BT_PROFILE_NAP;
522                 break;
523         case BT_NETWORK_SERVER_CONNECTED:
524                 profile = BT_PROFILE_NAP_SERVER;
525                 break;
526 _default_:
527         default:
528                 BT_ERR("Unknown type!");
529                 return FALSE;
530         }
531
532         ret = bt_device_is_profile_connected(addr_str, profile,
533                                         (bool *)&connected);
534
535         if (ret < BT_ERROR_NONE) {
536                 BT_ERR("failed with [0x%04x]", ret);
537                 return FALSE;
538         }
539
540         FN_END;
541         return connected;
542 }
543
544 void _bt_util_free_device_uuids(bt_dev_t *item)
545 {
546         int i;
547
548         ret_if(item == NULL);
549
550         if (item->uuids) {
551                 for (i = 0; item->uuids[i] != NULL; i++)
552                         g_free(item->uuids[i]);
553
554                 g_free(item->uuids);
555                 item->uuids = NULL;
556         }
557 }
558
559 void _bt_util_free_device_item(bt_dev_t *item)
560 {
561         ret_if(item == NULL);
562
563         _bt_util_free_device_uuids(item);
564
565         if (item->net_profile) {
566                 _bt_unset_profile_state_changed_cb(item->net_profile);
567                 item->net_profile = NULL;
568         }
569
570         item->ugd = NULL;
571         free(item);
572 }
573
574 gboolean _bt_util_is_space_str(const char *name_str)
575 {
576         retv_if(name_str == NULL, FALSE);
577         retv_if(*name_str == '\0', FALSE);
578
579         while (*name_str) {
580                 if (*name_str != '\0' && *name_str != ' ')
581                         return FALSE;
582
583                 name_str++;
584         }
585
586         return TRUE;
587 }
588
589 void _bt_util_max_len_reached_cb(void *data, Evas_Object *obj,
590                                 void *event_info)
591 {
592         FN_START;
593         int ret;
594         char str[BT_STR_ACCES_INFO_MAX_LEN] = {0, };
595         char *stms_str = NULL;
596
597         stms_str = BT_STR_MAX_CHARACTER_REACHED;
598
599         snprintf(str, sizeof(str), stms_str, DEVICE_NAME_MAX_CHARACTER);
600
601         ret = notification_status_message_post(str);
602         if (ret != NOTIFICATION_ERROR_NONE)
603                 BT_ERR("notification_status_message_post() ERROR [%d]", ret);
604
605         FN_END;
606 }
607
608 void _bt_util_change_discoverable_mode(bt_ug_data *ugd, gboolean discoverable)
609 {
610         FN_START;
611
612         int ret = BT_ERROR_NONE;
613
614         ret_if(!ugd);
615
616         if (ugd->timer) {
617                 ecore_timer_del(ugd->timer);
618                 ugd->timer = NULL;
619         }
620
621         ret_if(ugd->op_status == BT_DEACTIVATED);
622
623         if (discoverable)
624                 ret = bt_adapter_set_visibility(
625                         BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
626         else
627                 ret = bt_adapter_set_visibility(
628                         BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE, 0);
629
630         if (ret != BT_ERROR_NONE)
631                 BT_ERR("bt_adapter_set_visibility fail! ret = %d", ret);
632
633         FN_END;
634         return;
635 }
636
637 Eina_Bool _bt_timer_change_discoverable_mode(void *data)
638 {
639         FN_START;
640
641         bt_ug_data *ugd = data;
642         _bt_util_change_discoverable_mode(ugd, TRUE);
643         ugd->timer = NULL;
644
645         FN_END;
646         return EINA_FALSE;
647 }
648
649 int _bt_util_check_any_profile_connected(bt_dev_t *dev)
650 {
651         FN_START;
652         int connected = 0;
653
654         if (dev->service_list & BT_SC_HFP_SERVICE_MASK ||
655                     dev->service_list & BT_SC_HSP_SERVICE_MASK ||
656                     dev->service_list & BT_SC_A2DP_SERVICE_MASK) {
657                 connected = _bt_util_is_profile_connected(BT_HEADSET_CONNECTED,
658                                                 dev->bd_addr);
659                 if (!connected) {
660                         connected = _bt_util_is_profile_connected(BT_STEREO_HEADSET_CONNECTED,
661                                                         dev->bd_addr);
662                 }
663                 if (connected)
664                         goto done;
665         }
666
667         if (dev->service_list & BT_SC_A2DP_SOURCE_SERVICE_MASK) {
668                 connected = _bt_util_is_profile_connected(BT_MUSIC_PLAYER_CONNECTED,
669                                                 dev->bd_addr);
670                 if (connected)
671                         goto done;
672         }
673
674         if (dev->service_list & BT_SC_PANU_SERVICE_MASK ||
675                 dev->service_list & BT_SC_NAP_SERVICE_MASK ||
676                 dev->service_list & BT_SC_GN_SERVICE_MASK) {
677                 connected = _bt_util_is_profile_connected(BT_NETWORK_CONNECTED,
678                                                 dev->bd_addr);
679                 if (!connected) {
680                         connected = _bt_util_is_profile_connected(BT_NETWORK_SERVER_CONNECTED,
681                                 dev->bd_addr);
682                         }
683                 if (connected)
684                         goto done;
685         }
686
687         if (dev->service_list & BT_SC_HID_SERVICE_MASK) {
688                 connected = _bt_util_is_profile_connected(BT_HID_CONNECTED,
689                                                 dev->bd_addr);
690
691                 if (connected)
692                         goto done;
693         }
694
695         /* TODO : other GATT device scenario should be considered.
696            In this case, only HOG device scenario is considered. */
697         if (TIZEN_FEATURE_BT_HOG && dev->is_le_device) {
698                 connected = _bt_util_is_profile_connected(BT_LE_HID_CONNECTED,
699                                 dev->bd_addr);
700                 if (connected)
701                         goto done;
702         }
703
704         FN_END;
705 done:
706         return connected;
707 }
708
709 static void __bt_util_dpm_policy_changed_cb(const char *name, const char *value, void *user_data)
710 {
711         FN_START;
712
713         bt_ug_data *ugd = NULL;
714
715         ret_if(user_data == NULL);
716         ret_if(name == NULL);
717         ret_if(value == NULL);
718
719         ugd = (bt_ug_data *)user_data;
720
721         BT_DBG("policy name: %s", name);
722         BT_DBG("policy value: %s", value);
723
724         if (strcmp(name, "bluetooth") != 0) {
725                 BT_ERR("Not bluetooth policy");
726                 return;
727         }
728
729         if (!strcmp(value, "disallowed")) {
730                 BT_DBG("BT policy is restricted");
731
732                 if (ugd->onoff_item)
733                         elm_object_item_disabled_set(ugd->onoff_item, EINA_TRUE);
734
735                 if (ugd->onoff_btn)
736                         elm_object_disabled_set(ugd->onoff_btn, EINA_TRUE);
737         } else if (!strcmp(value, "allowed")) {
738                 BT_DBG("BT policy is allowed");
739
740                 if (ugd->onoff_item)
741                         elm_object_item_disabled_set(ugd->onoff_item, EINA_FALSE);
742
743                 if (ugd->onoff_btn)
744                         elm_object_disabled_set(ugd->onoff_btn, EINA_FALSE);
745         } else {
746                 BT_ERR("Unknown string value");
747         }
748
749         FN_END;
750 }
751
752 int _bt_util_create_dpm_context(void *ug_data)
753 {
754         FN_START;
755
756         int ret;
757         device_policy_manager_h handle = NULL;
758         bt_ug_data *ugd = NULL;
759
760         retv_if(ug_data == NULL, BT_UG_FAIL);
761
762         ugd = (bt_ug_data *)ug_data;
763
764         handle = dpm_manager_create();
765
766         if (handle == NULL) {
767                 BT_ERR("Fail to create dpm context");
768                 return BT_UG_FAIL;
769         }
770
771         ret = dpm_add_policy_changed_cb(handle, "bluetooth",
772                                                         __bt_util_dpm_policy_changed_cb,
773                                                         (void *)ugd, &ugd->dpm_callback_id);
774         if (ret != DPM_ERROR_NONE)
775                 BT_ERR("Fail to destroy dpm context [%d]", ret);
776
777         ugd->dpm_handle = (void *)handle;
778
779         FN_END;
780         return BT_UG_ERROR_NONE;
781 }
782
783 void _bt_util_destroy_dpm_context(void *ug_data)
784 {
785         FN_START;
786
787         int ret;
788         bt_ug_data *ugd = NULL;
789
790         ret_if(ug_data == NULL);
791
792         ugd = (bt_ug_data *)ug_data;
793
794         ret = dpm_remove_policy_changed_cb(ugd->dpm_handle, ugd->dpm_callback_id);
795         if (ret != DPM_ERROR_NONE)
796                 BT_ERR("Fail to remove callback [%d]", ret);
797
798         ret = dpm_manager_destroy(ugd->dpm_handle);
799         if (ret != DPM_ERROR_NONE)
800                 BT_ERR("Fail to destroy dpm context [%d]", ret);
801
802         ugd->dpm_handle = NULL;
803         ugd->dpm_callback_id = 0;
804
805         FN_END;
806 }
807
808 gboolean _bt_util_is_dpm_restricted(void *handle)
809 {
810         FN_START;
811
812         int ret;
813         int dpm_state = 1;
814
815         retv_if(handle == NULL, FALSE);
816
817         ret = dpm_restriction_get_bluetooth_mode_change_state((device_policy_manager_h)handle,
818                                                                                 &dpm_state);
819         if (ret != DPM_ERROR_NONE) {
820                 BT_ERR("Fail to destroy dpm context [%d]", ret);
821                 return FALSE;
822         }
823
824         BT_DBG("BT dpm state: %d", dpm_state);
825
826         FN_END;
827         return (dpm_state == 0) ? TRUE : FALSE;
828 }
829
830 static bool __bt_util_file_exists(const char *file)
831 {
832         bool res = false;
833         if (file) {
834                 struct stat st;
835                 res = stat(file, &st) == 0 || strcmp(file, "/") == 0;
836         }
837
838         return res;
839 }
840
841 static bool __bt_util_file_remove(const char *file)
842 {
843         bool res = false;
844
845         if (file)
846                 res = remove(file) == 0;
847
848         return res;
849 }
850
851 static char *__bt_util_make_vcard_file_path(const char *working_dir, const char *display_name)
852 {
853         char file_path[PATH_MAX] = { 0 };
854         int id = 0;
855
856         if (!working_dir)
857                 return NULL;
858
859         if (!display_name)
860                 display_name = "Unknown";
861
862         do {
863                 snprintf(file_path, sizeof(file_path), "%s%s-%u.vcf", working_dir, display_name, id);
864                 ++id;
865         } while (__bt_util_file_exists(file_path));
866
867         BT_DBG("file_path = %s", file_path);
868
869         return strdup(file_path);
870 }
871
872 static bool __bt_util_write_vcard_to_file(int fd, contacts_record_h record, bool my_profile)
873 {
874         char *vcard_buff = NULL;
875         bool ok = false;
876
877         do {
878                 int size_left = 0;
879
880                 if (my_profile)
881                         contacts_vcard_make_from_my_profile(record, &vcard_buff);
882                 else
883                         contacts_vcard_make_from_person(record, &vcard_buff);
884
885                 if (!vcard_buff) {
886                         BT_ERR("vcard_buff is NULL");
887                         break;
888                 }
889
890                 size_left = strlen(vcard_buff);
891                 while (size_left) {
892                         int written = write(fd, vcard_buff, size_left);
893                         if (written == -1) {
894                                 BT_ERR("write() failed: %d", errno);
895                                 break;
896                         }
897                         size_left -= written;
898                 }
899
900                 ok = (size_left == 0);
901         } while (false);
902
903         free(vcard_buff);
904
905         return ok;
906 }
907
908 static bool __bt_util_write_vcard_to_file_from_id(int fd, int person_id)
909 {
910         contacts_record_h record = NULL;
911         bool ok = false;
912
913         do {
914                 int ret = contacts_db_get_record(_contacts_person._uri, person_id, &record);
915                 if (ret != CONTACTS_ERROR_NONE) {
916                         BT_ERR("contacts_db_get_record() failed: %d", ret);
917                         record = NULL;
918                         break;
919                 }
920
921                 if (!__bt_util_write_vcard_to_file(fd, record, false)) {
922                         BT_ERR("_write_vcard_to_file() failed");
923                         break;
924                 }
925
926                 ok = true;
927         } while (false);
928
929         if (record)
930                 contacts_record_destroy(record, true);
931
932         return ok;
933 }
934
935 char *_bt_util_vcard_create_from_id(int id, bool my_profile, const char *working_dir)
936 {
937         FN_START;
938
939         contacts_record_h record = NULL;
940         char *vcard_path = NULL;
941         int fd = -1;
942         bool ok = false;
943         int ret;
944
945         if (TIZEN_PROFILE_TV)
946                 return 0;
947
948         BT_DBG("id = %i my_profile = %d", id, my_profile);
949
950         ret = contacts_connect();
951         if (ret != CONTACTS_ERROR_NONE)
952                 BT_ERR("contacts_connect failed : ct_err = [%d]", ret);
953
954         do {
955                 char *display_name = NULL;
956
957                 int ret = contacts_db_get_record((my_profile ?
958                                 _contacts_my_profile._uri :
959                                 _contacts_person._uri), id, &record);
960                 if (ret != CONTACTS_ERROR_NONE) {
961                         BT_ERR("contacts_db_get_record() failed: %d", ret);
962                         record = NULL;
963                         break;
964                 }
965
966                 if (my_profile)
967                         contacts_record_get_str_p(record, _contacts_my_profile.display_name, &display_name);
968                 else
969                         contacts_record_get_str_p(record, _contacts_person.display_name, &display_name);
970
971                 (void) display_name; /* Ignore unused variable for dummy contacts.h */
972
973                 vcard_path = __bt_util_make_vcard_file_path(working_dir, "Contact");
974                 if (!vcard_path) {
975                         BT_ERR("_make_vcard_file_path() failed");
976                         break;
977                 }
978
979                 fd = open(vcard_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
980                 if (fd == -1) {
981                         BT_ERR("open(%s) Failed(%d)", vcard_path, errno);
982                         break;
983                 }
984
985                 if (!__bt_util_write_vcard_to_file(fd, record, my_profile)) {
986                         BT_ERR("_write_vcard_to_file() failed");
987                         break;
988                 }
989
990                 ok = true;
991         } while (false);
992
993         ret = contacts_disconnect();
994         if (ret != CONTACTS_ERROR_NONE)
995                 BT_ERR("contacts_disconnect failed : ct_err = [%d]", ret);
996
997         if (record)
998                 contacts_record_destroy(record, true);
999
1000         if (fd != -1) {
1001                 close(fd);
1002                 if (!ok)
1003                         __bt_util_file_remove(vcard_path);
1004         }
1005
1006         if (!ok) {
1007                 free(vcard_path);
1008                 vcard_path = NULL;
1009         }
1010
1011         FN_END;
1012
1013         return vcard_path;
1014 }
1015
1016 char *_bt_util_vcard_create_from_id_list(const int *id_list, int count, const char *working_dir, volatile bool *cancel)
1017 {
1018         FN_START;
1019
1020         char *vcard_path = NULL;
1021         int fd = -1;
1022         bool ok = false;
1023         int ret;
1024
1025         if (TIZEN_PROFILE_TV)
1026                 return 0;
1027
1028         if (!id_list || count <= 0)
1029                 return NULL;
1030
1031         ret = contacts_connect();
1032         if (ret != CONTACTS_ERROR_NONE)
1033                 BT_ERR("contacts_connect failed : ct_err = [%d]", ret);
1034
1035         do {
1036                 int i = 0;
1037
1038                 vcard_path = __bt_util_make_vcard_file_path(working_dir, "Contacts");
1039                 if (!vcard_path) {
1040                         BT_ERR("_make_vcard_file_path() failed");
1041                         break;
1042                 }
1043
1044                 fd = open(vcard_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1045                 if (fd == -1) {
1046                         BT_ERR("open(%s) Failed(%d)", vcard_path, errno);
1047                         break;
1048                 }
1049
1050                 for (i = 0; !(*cancel) && (i < count); ++i) {
1051                         if (!__bt_util_write_vcard_to_file_from_id(fd, id_list[i])) {
1052                                 BT_ERR("_composer_write_vcard_to_file() failed");
1053                                 break;
1054                         }
1055                 }
1056
1057                 ok = (i == count);
1058         } while (false);
1059
1060         ret = contacts_disconnect();
1061         if (ret != CONTACTS_ERROR_NONE)
1062                 BT_ERR("contacts_disconnect failed : ct_err = [%d]", ret);
1063
1064         if (fd != -1) {
1065                 close(fd);
1066                 if (!ok)
1067                         __bt_util_file_remove(vcard_path);
1068         }
1069
1070         if (!ok) {
1071                 free(vcard_path);
1072                 vcard_path = NULL;
1073         }
1074
1075         FN_END;
1076
1077         return vcard_path;
1078 }
1079
1080 tizen_profile_t _get_tizen_profile()
1081 {
1082         static tizen_profile_t profile = _PROFILE_UNKNOWN;
1083         char *profileName;
1084
1085         if (__builtin_expect(profile != _PROFILE_UNKNOWN, 1))
1086                 return profile;
1087
1088         system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
1089         switch (*profileName) {
1090                 case 'm':
1091                 case 'M':
1092                         profile = _PROFILE_MOBILE;
1093                         break;
1094                 case 'w':
1095                 case 'W':
1096                         profile = _PROFILE_WEARABLE;
1097                         break;
1098                 case 't':
1099                 case 'T':
1100                         profile = _PROFILE_TV;
1101                         break;
1102                 case 'i':
1103                 case 'I':
1104                         profile = _PROFILE_IVI;
1105                         break;
1106                 default: // common or unknown ==> ALL ARE COMMON.
1107                         profile = _PROFILE_COMMON;
1108         }
1109         free(profileName);
1110
1111         return profile;
1112 }