1 /******************************************************************************
3 * Copyright (C) 2012 Broadcom Corporation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
19 /************************************************************************************
21 * Filename: bt_utils.c
23 * Description: Miscellaneous helper functions
26 ***********************************************************************************/
28 #define LOG_TAG "bt_utils"
36 #include <sys/resource.h>
39 #include <utils/ThreadDefs.h>
40 #include <cutils/sched_policy.h>
43 #include "btcore/include/module.h"
44 #include "osi/include/compat.h"
45 #include "osi/include/allocator.h"
46 #include "osi/include/log.h"
47 #include "osi/include/properties.h"
48 #include "osi/include/list.h"
51 /*******************************************************************************
52 ** Local type definitions
53 *******************************************************************************/
55 char header_name[MAX_NAME_LEN]; // name of header in iot_devlist_conf file
56 list_t *devlist; // list of BD addresses
57 tBLACKLIST_METHOD method_type;
61 char dev_bd[3]; // BD address of blacklisted device
62 } iot_devlist_bd_node_t;
65 char dev_name[MAX_NAME_LEN]; // Name of blacklisted device
66 } iot_devlist_name_node_t;
69 char *header; // header name
70 unsigned char *dev_details; // details of blacklisted device
79 static soc_type_node soc_type_entries[] = {
80 { BT_SOC_SMD , "smd" },
81 { BT_SOC_AR3K , "ath3k" },
82 { BT_SOC_ROME , "rome" },
83 { BT_SOC_CHEROKEE , "cherokee" },
84 { BT_SOC_RESERVED , "" }
87 static list_t *iot_header_queue = NULL;
89 #define MAX_ADDR_STR_LEN 9
90 static pthread_mutex_t iot_mutex_lock;
91 /*******************************************************************************
92 ** Type definitions for callback functions
93 ********************************************************************************/
94 static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX];
95 static BOOLEAN g_DoSchedulingGroup[TASK_HIGH_MAX];
96 static pthread_mutex_t gIdxLock;
98 static int g_TaskIDs[TASK_HIGH_MAX];
99 static bt_soc_type soc_type;
100 #define INVALID_TASK_ID (-1)
102 static void init_soc_type();
104 static future_t *init(void) {
106 pthread_mutexattr_t lock_attr;
108 for(i = 0; i < TASK_HIGH_MAX; i++) {
109 g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT;
110 g_DoSchedulingGroup[i] = TRUE;
111 g_TaskIDs[i] = INVALID_TASK_ID;
114 pthread_mutexattr_init(&lock_attr);
115 pthread_mutex_init(&gIdxLock, &lock_attr);
116 pthread_mutex_init(&iot_mutex_lock, NULL);
121 static future_t *clean_up(void) {
122 pthread_mutex_destroy(&gIdxLock);
123 pthread_mutex_destroy(&iot_mutex_lock);
127 EXPORT_SYMBOL const module_t bt_utils_module = {
128 .name = BT_UTILS_MODULE,
132 .clean_up = clean_up,
138 /*****************************************************************************
140 ** Function check_do_scheduling_group
142 ** Description check if it is ok to change schedule group
146 *******************************************************************************/
147 static void check_do_scheduling_group(void) {
148 char buf[PROPERTY_VALUE_MAX];
149 int len = osi_property_get("debug.sys.noschedgroups", buf, "");
152 if (sscanf(buf, "%d", &temp) == 1) {
153 g_DoSchedulingGroup[g_TaskIdx] = temp == 0;
158 /*****************************************************************************
160 ** Function raise_priority_a2dp
162 ** Description Raise task priority for A2DP streaming
166 *******************************************************************************/
167 void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
170 int priority = ANDROID_PRIORITY_AUDIO;
172 pthread_mutex_lock(&gIdxLock);
173 g_TaskIdx = high_task;
175 // TODO(armansito): Remove this conditional check once we find a solution
176 // for system/core on non-Android platforms.
177 #if defined(OS_GENERIC)
179 #else // !defined(OS_GENERIC)
180 pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group);
181 if (g_TaskIdx < TASK_HIGH_MAX && g_DoSchedulingGroup[g_TaskIdx]) {
182 // set_sched_policy does not support tid == 0
183 rc = set_sched_policy(tid, SP_AUDIO_SYS);
185 #endif // defined(OS_GENERIC)
187 g_TaskIDs[high_task] = tid;
188 pthread_mutex_unlock(&gIdxLock);
191 LOG_WARN(LOG_TAG, "failed to change sched policy, tid %d, err: %d", tid, errno);
194 // always use urgent priority for HCI worker thread until we can adjust
195 // its prio individually. All other threads can be dynamically adjusted voa
196 // adjust_priority_a2dp()
198 priority = ANDROID_PRIORITY_URGENT_AUDIO;
200 if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
201 LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
205 /*****************************************************************************
207 ** Function adjust_priority_a2dp
209 ** Description increase the a2dp consumer task priority temporarily when start
210 ** audio playing, to avoid overflow the audio packet queue, restore
211 ** the a2dp consumer task priority when stop audio playing.
215 *******************************************************************************/
216 void adjust_priority_a2dp(int start) {
217 int priority = start ? ANDROID_PRIORITY_URGENT_AUDIO : ANDROID_PRIORITY_AUDIO;
221 for (i = 0; i < TASK_HIGH_MAX; i++)
224 if (tid != INVALID_TASK_ID)
226 if (setpriority(PRIO_PROCESS, tid, priority) < 0)
228 LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
234 /*****************************************************************************
236 ** Function check_bd_cb
238 ** Description Compares the BD address.
240 ** Returns returns true if the BD address matches otherwise false
242 *******************************************************************************/
243 static bool check_bd_cb(void* node, void* cb_data)
245 iot_devlist_bd_node_t *bd_node = (iot_devlist_bd_node_t*)node;
246 iot_input_param *input_param = (iot_input_param*)cb_data;
248 if (input_param->device_found == true)
251 if ((bd_node->dev_bd[0] == input_param->dev_details[0]) &&
252 (bd_node->dev_bd[1] == input_param->dev_details[1]) &&
253 (bd_node->dev_bd[2] == input_param->dev_details[2])) {
254 input_param->device_found = true;
260 /*****************************************************************************
262 ** Function check_name_cb
264 ** Description Compares the Device name.
266 ** Returns returns true if the name matches otherwise false
268 *******************************************************************************/
269 static bool check_name_cb(void* node, void* cb_data)
271 iot_devlist_name_node_t *name_node = (iot_devlist_name_node_t*)node;
272 iot_input_param *input_param = (iot_input_param*)cb_data;
274 if (input_param->device_found == true)
277 if (!strncmp(name_node->dev_name, (const char*)input_param->dev_details,
278 strlen((char *)input_param->dev_details))) {
279 input_param->device_found = true;
285 /*****************************************************************************
287 ** Function check_header_cb
289 ** Description Iterates through the each entry in the header list and
290 ** calls the callback associated to each entry.
294 *******************************************************************************/
295 static bool check_header_cb(void* node, void* cb_data)
297 iot_header_node_t *header_node = (iot_header_node_t*)node;
298 iot_input_param *input_param = (iot_input_param*)cb_data;
299 if (!strcmp(header_node->header_name, input_param->header)) {
300 if(header_node->devlist) {
301 if (header_node->method_type == METHOD_BD)
302 list_foreach_ext(header_node->devlist, check_bd_cb, cb_data);
303 else if (header_node->method_type == METHOD_NAME)
304 list_foreach_ext(header_node->devlist, check_name_cb, cb_data);
310 /*****************************************************************************
312 ** Function is_device_present
314 ** Description Checks if the device is already present in the blacklisted
315 ** device list or not.The input can be address based or name
318 ** Returns true incase device is present false otherwise.
320 *******************************************************************************/
321 bool is_device_present(char* header, unsigned char* device_details)
323 iot_input_param input_param;
324 input_param.dev_details = device_details;
325 input_param.header = header;
326 input_param.device_found = false;
328 pthread_mutex_lock(&iot_mutex_lock);
329 if (!iot_header_queue) {
330 pthread_mutex_unlock(&iot_mutex_lock);
333 list_foreach_ext(iot_header_queue, check_header_cb, &input_param);
334 pthread_mutex_unlock(&iot_mutex_lock);
336 if (input_param.device_found)
342 /*****************************************************************************
346 ** Description It will read 3 bytes and copy them into node. It also
347 ** increments header pointer.
351 *******************************************************************************/
352 static void parse_bd(char **start_ptr, iot_devlist_bd_node_t *bd)
355 bd->dev_bd[0] = (unsigned char)strtol(*start_ptr, &p_end, 16);
356 (*start_ptr) = p_end + 1;
357 bd->dev_bd[1] = (unsigned char)strtol(*start_ptr, &p_end, 16);
358 (*start_ptr) = p_end + 1;
359 bd->dev_bd[2] = (unsigned char)strtol(*start_ptr, &p_end, 16);
360 (*start_ptr) = p_end;
363 /*****************************************************************************
365 ** Function parse_name
367 ** Description It will read name and copy them into node. It also
368 ** increments header pointer.
372 *******************************************************************************/
373 static void parse_name(char **start_ptr, iot_devlist_name_node_t *name)
375 char *split = strchr(*start_ptr, ','); // split point to first occurrence of ,
378 // check once for end of line, for the last name in list
379 split = strchr(*start_ptr, '\n');
383 len = (((split - (*start_ptr)) >= MAX_NAME_LEN) ? MAX_NAME_LEN - 1 :
384 (split - (*start_ptr)));
385 memcpy(name->dev_name, *start_ptr, len);
386 name->dev_name[len] = '\0';
390 /*****************************************************************************
392 ** Function is_device_node_exist
394 ** Description Checks if the device node is already present in the queue
395 ** or not.The input can be address based or name based.
397 ** Returns true if the entry found else false.
399 *******************************************************************************/
400 static bool is_device_node_exist(iot_header_node_t *header_entry, char* device_details,
401 tBLACKLIST_METHOD method_type)
403 if(!header_entry || !header_entry->devlist)
406 for (const list_node_t *device_node = list_begin(header_entry->devlist);
407 device_node != list_end(header_entry->devlist);
408 device_node = list_next(device_node)) {
409 if(method_type == METHOD_BD) {
410 iot_devlist_bd_node_t *bd_addr_entry = list_node(device_node);
411 if(!memcmp(device_details, bd_addr_entry->dev_bd, 3)) {
415 else if(method_type == METHOD_NAME) {
416 iot_devlist_name_node_t *bd_name_entry = list_node(device_node);
417 if(!strcmp((char *)device_details, bd_name_entry->dev_name)) {
425 /*****************************************************************************
427 ** Function populate_list
429 ** Description It goes through the input buffer and add device node to the
430 ** header list if the valid entry is found.It ignores the
431 ** duplicated entries.
435 *******************************************************************************/
436 static void populate_list(char *header_end, iot_header_node_t *node)
438 if(node->devlist == NULL)
439 node->devlist = list_new(osi_free);
440 while(header_end && (*header_end != '\n')&&(*header_end != '\0')) // till end of line reached
442 // read from line buffer and copy to list
443 if (node->method_type == METHOD_BD) {
444 iot_devlist_bd_node_t *bd = (iot_devlist_bd_node_t *)osi_malloc(sizeof(iot_devlist_bd_node_t));
446 ALOGE(" Unable to allocate memory for addr entry");
450 parse_bd(&header_end, bd);
451 if(is_device_node_exist(node, (char *) bd, node->method_type)) {
455 list_append(node->devlist, bd);
458 else if (node->method_type == METHOD_NAME) {
459 iot_devlist_name_node_t *name = (iot_devlist_name_node_t *)osi_malloc(sizeof(iot_devlist_name_node_t));
461 ALOGE(" Unable to allocate memory for name entry");
465 parse_name(&header_end, name);
466 if(is_device_node_exist(node, (char *)name, node->method_type)) {
470 list_append(node->devlist, name);
476 /*****************************************************************************
478 ** Function create_header_node
480 ** Description This function is used to create the header node.
482 ** Returns valid pointer incase the node is created otherwise NULL.
484 *******************************************************************************/
485 static iot_header_node_t *create_header_node(char* name, unsigned int len,
486 tBLACKLIST_METHOD method_type)
488 iot_header_node_t *node = NULL;
489 if(len >= MAX_NAME_LEN) {
492 node =(iot_header_node_t *) osi_malloc(sizeof(iot_header_node_t));
494 ALOGE(" Not enough memory to create the header node");
497 memcpy(node->header_name, name, len);
498 node->header_name[len] = '\0'; // header copied
499 node->method_type = method_type;
500 node->devlist = NULL;
504 /*****************************************************************************
506 ** Function get_existing_header_node
508 ** Description This function is used to get exisiting header node if present.
510 ** Returns valid pointer incase the node is already prsent otherwise NULL.
512 *******************************************************************************/
513 static iot_header_node_t *get_existing_header_node(char* name, unsigned int len)
515 for (const list_node_t *node = list_begin(iot_header_queue);
516 node != list_end(iot_header_queue); node = list_next(node)) {
517 iot_header_node_t *entry = list_node(node);
518 if (!strncmp(entry->header_name, name, len)) {
525 /*****************************************************************************
527 ** Function populate_header
529 ** Description It goes through the input buffer and add header node to the
530 ** main queue if the valid entry is found.It ignores the
531 ** duplicated entries.
535 *******************************************************************************/
536 static void populate_header(char* line_start, char *header_end)
538 tBLACKLIST_METHOD method_type;
539 iot_header_node_t *node = NULL;
541 if (*(header_end + 3) == ':')
542 method_type = METHOD_BD;
544 method_type = METHOD_NAME;
546 if (!iot_header_queue) {
547 iot_header_queue = list_new(osi_free);
548 if (iot_header_queue == NULL) {
549 ALOGE(" Not enough memory to create the queue");
554 if( (node = get_existing_header_node(line_start, header_end - line_start)) == NULL) {
555 node = create_header_node(line_start, header_end - line_start, method_type);
557 list_append(iot_header_queue, node);
560 populate_list(header_end, node);
563 /*****************************************************************************
565 ** Function free_header_list
567 ** Description This function is used to free all entries under blacklist
572 *******************************************************************************/
573 static bool free_header_list(void* node, void *context)
575 iot_header_node_t *header_node = (iot_header_node_t*)node;
576 list_free(header_node->devlist);
580 /*****************************************************************************
582 ** Function unload_iot_devlist
584 ** Description This function is used to free the IOT blacklist queue.
588 *******************************************************************************/
589 void unload_iot_devlist()
591 pthread_mutex_lock(&iot_mutex_lock);
592 if (!iot_header_queue) {
593 ALOGV(" Blacklist queue is not initialized ");
594 pthread_mutex_unlock(&iot_mutex_lock);
597 list_foreach(iot_header_queue, free_header_list, NULL);
598 list_free(iot_header_queue);
599 iot_header_queue = NULL;
600 pthread_mutex_unlock(&iot_mutex_lock);
603 /*****************************************************************************
605 ** Function copy_file
607 ** Description This function is used to copy one file to other.
609 ** Returns true incase copy is successful otherwise false.
611 *******************************************************************************/
612 static bool copy_file(const char *src, const char *dst)
614 FILE *src_fp = NULL, *dst_fp = NULL;
620 src_fp = fopen(src, "rt");
622 dst_fp = fopen(dst, "wt");
623 if(src_fp && dst_fp) {
624 while( ( ch = fgetc(src_fp) ) != EOF ) {
640 /*****************************************************************************
642 ** Function dump_all_iot_devices
644 ** Description This function is used to print all blacklisted devices
645 ** which are loaded from iot_devlist.conf file..
649 *******************************************************************************/
650 static void dump_all_iot_devices(void)
652 tBLACKLIST_METHOD method_type;
654 if(!iot_header_queue)
657 for (const list_node_t *header_node = list_begin(iot_header_queue);
658 header_node != list_end(iot_header_queue);
659 header_node = list_next(header_node)) {
660 iot_header_node_t *header_entry = list_node(header_node);
661 method_type = header_entry->method_type;
663 if(!header_entry->devlist)
666 ALOGW(" ########### Blacklisted Device summary ##############");
667 for (const list_node_t *device_node = list_begin(header_entry->devlist);
668 device_node != list_end(header_entry->devlist);
669 device_node = list_next(device_node)) {
670 if(method_type == METHOD_BD) {
671 iot_devlist_bd_node_t *bd_addr_entry = list_node(device_node);
672 ALOGW(" Device %02X:%02X:%02X Blacklisted under %s",
673 bd_addr_entry->dev_bd[0], bd_addr_entry->dev_bd[1],
674 bd_addr_entry->dev_bd[2], header_entry->header_name);
676 else if(method_type == METHOD_NAME) {
677 iot_devlist_name_node_t *bd_name_entry = list_node(device_node);
678 ALOGW(" Device %s Blacklisted under %s", bd_name_entry->dev_name,
679 header_entry->header_name);
685 /*****************************************************************************
687 ** Function load_iot_devlist_from_file
689 ** Description This function is used to initialize the queue and load the
690 ** load the devices from file.
694 *******************************************************************************/
695 void load_iot_devlist_from_file(const char *filename)
698 ALOGE(" Invalid IOT blacklist filename");
701 char line_start[MAX_LINE];
703 char *header_end = NULL;
704 FILE *iot_devlist_fp = fopen(filename, "rt");
705 if (iot_devlist_fp == NULL) {
706 if(!strcmp(filename, IOT_DEV_CONF_FILE)) {
707 //load it from system partition
708 if(copy_file(IOT_DEV_BASE_CONF_FILE, IOT_DEV_CONF_FILE) == false) {
709 ALOGE(" Can't copy it from Base file %s", IOT_DEV_BASE_CONF_FILE);
713 if((iot_devlist_fp = fopen(filename, "rt")) == NULL)
718 ALOGE(" File %s does not exist ",filename);
722 while(fgets(line_start, MAX_LINE, iot_devlist_fp)) {
724 if((*line_start == '\n') ||(*line_start == '#')) {
725 ALOGV("line %d is empty",line_number);
728 header_end = strchr(line_start, '=');
729 if (header_end == NULL) {
730 ALOGV(" NOT A valid line %d", line_number);
733 populate_header(line_start, header_end);
735 dump_all_iot_devices();
736 fclose(iot_devlist_fp);
739 /*****************************************************************************
741 ** Function load_iot_devlist
743 ** Description This function is used to initialize the queue.
747 *******************************************************************************/
748 void load_iot_devlist(const char *filename)
750 pthread_mutex_lock(&iot_mutex_lock);
751 load_iot_devlist_from_file(filename);
752 pthread_mutex_unlock(&iot_mutex_lock);
755 /*****************************************************************************
757 ** Function add_iot_device
759 ** Description This function is used to add the device to the blacklist file
762 ** Returns true incase the device is blacklisted otherwise fasle.
764 *******************************************************************************/
765 bool add_iot_device(const char *filename, char* header,
766 unsigned char* device_details, tBLACKLIST_METHOD method_type)
768 char line_start[MAX_LINE];
769 FILE *iot_devlist_fp;
770 char *header_end = NULL;
771 int index = 0, i, len = 0;
773 if((header == NULL) || (device_details == NULL)) {
774 ALOGE("Error adding device to the list: Invalid input data");
777 if (is_device_present (header , device_details)) {
778 ALOGW("Device already present in the blacklist");
782 pthread_mutex_lock(&iot_mutex_lock);
783 iot_devlist_fp = fopen(filename, "a");
785 if (iot_devlist_fp == NULL) {
786 ALOGE(" File %s does not exist ", filename);
787 pthread_mutex_unlock(&iot_mutex_lock);
790 /* first copy the header */
791 len = strlcpy(&line_start[index], header, strlen(header)+ 1);
794 line_start[index++] = '=';
795 /* then copy the device addr/device name */
796 if(method_type == METHOD_BD) {
797 /* for addr take first 3 bytes */
798 for(i = 0; i < 3; i++) {
800 len = snprintf(&line_start[index], MAX_LINE - index, "%02X:",
801 *(device_details + i));
804 len = snprintf(&line_start[index], MAX_LINE - index, "%02X",
805 *(device_details + i));
810 else if(method_type == METHOD_NAME) {
811 len = strlcpy(&line_start[index], (const char*) device_details,
812 strlen((const char*)device_details) + 1);
815 /* append the new line characer at the end */
816 line_start[index++] = '\n';
817 line_start[index++] = '\0';
819 header_end = strchr(line_start,'=');
821 populate_header(line_start, header_end);
823 if(fputs(line_start, iot_devlist_fp)) {
824 fclose(iot_devlist_fp);
825 pthread_mutex_unlock(&iot_mutex_lock);
829 fclose(iot_devlist_fp);
830 pthread_mutex_unlock(&iot_mutex_lock);
835 /*****************************************************************************
837 ** Function form_bd_addr
839 ** Description Adds the colon after 2 bytes to form valid BD address to
840 ** compare the entry prsent in file.
844 *******************************************************************************/
845 static void form_bd_addr(char *addr, char *new_addr, int max_len)
847 int i = 0, index = 0, len =0;
848 /* for addr take first 3 bytes */
849 for(i = 0; i < 3; i++) {
851 len = snprintf(&new_addr[index], max_len - index, "%02X:",
855 len = snprintf(&new_addr[index], max_len - index, "%02X",
860 new_addr[max_len - 1]= '\0';
863 /*****************************************************************************
865 ** Function remove_iot_device_from_queue
867 ** Description This function is used remove the entry from internal queue.
869 ** Returns true if the entry removed from queue else false.
871 *******************************************************************************/
872 bool remove_iot_device_from_queue(unsigned char* device_details, char* header,
873 tBLACKLIST_METHOD method_type)
875 if(!iot_header_queue)
877 for (const list_node_t *header_node = list_begin(iot_header_queue);
878 header_node != list_end(iot_header_queue);
879 header_node = list_next(header_node)) {
880 iot_header_node_t *header_entry = list_node(header_node);
882 if(!header_entry->devlist)
885 if((!strcmp(header, header_entry->header_name)) &&
886 method_type == header_entry->method_type) {
888 for (const list_node_t *device_node = list_begin(header_entry->devlist);
889 device_node != list_end(header_entry->devlist);
890 device_node = list_next(device_node)) {
891 if(method_type == METHOD_BD) {
892 iot_devlist_bd_node_t *bd_addr_entry = list_node(device_node);
893 if(!memcmp(device_details, bd_addr_entry->dev_bd, 3)) {
894 list_remove(header_entry->devlist, bd_addr_entry);
898 else if(method_type == METHOD_NAME) {
899 iot_devlist_name_node_t *bd_name_entry = list_node(device_node);
900 if(!strcmp((char *)device_details, bd_name_entry->dev_name)) {
901 list_remove(header_entry->devlist, bd_name_entry);
911 /*****************************************************************************
913 ** Function edit_line
915 ** Description This function is used to remove the device entry from the
916 ** inputted line buffer if the entry present.
918 ** Returns true if the entry removed from line else false.
920 *******************************************************************************/
921 static void edit_line(char *line_start, char *dev_info, int line_len)
923 char *dev_ptr = strstr(line_start, dev_info);
924 char *comma_ptr = NULL;
927 comma_ptr = strchr(dev_ptr, ',');
929 len_to_copy = line_len - (comma_ptr - line_start + 1);
932 *(dev_ptr - 1) = '\n';
937 memmove(dev_ptr, comma_ptr + 1, len_to_copy);
941 /*****************************************************************************
943 ** Function is_single_entry_line
945 ** Description This function is used to check the line consists of single
946 ** input line if the entry present.
948 ** Returns true if the single entry present else false.
950 *******************************************************************************/
951 static bool is_single_entry_line(char *line_start)
953 char *comma_ptr = strchr(line_start, ',');
954 // check the char next to ,
955 if( !comma_ptr || (*(comma_ptr + 1) == '\n')) {
963 /*****************************************************************************
965 ** Function get_header_from_line
967 ** Description This function is used to get the header from line buffer.
969 ** Returns true if the header found else false.
971 *******************************************************************************/
972 bool get_header_from_line(char *line_start, char* header)
975 if(!line_start || !header || !strchr(line_start, '=')) {
978 while (line_start[i] != '=') {
979 header[i] = line_start[i];
986 /*****************************************************************************
988 ** Function remove_iot_device
990 ** Description This function is used to remove the device from internal
991 ** blacklisted queue as well as black list file.
993 ** Returns true if the device is removed else false.
995 *******************************************************************************/
996 bool remove_iot_device(const char *filename, char* header,
997 unsigned char* device_details, tBLACKLIST_METHOD method_type)
999 char line_start[MAX_LINE];
1000 FILE *iot_devlist_fp, *iot_devlist_new_fp;
1001 char bd_addr[MAX_ADDR_STR_LEN];
1002 char header_name[MAX_NAME_LEN] = { 0 };
1006 if((header == NULL) || (device_details == NULL)) {
1007 ALOGE("Invalid input data to add the device");
1010 if (!is_device_present (header , device_details)) {
1011 ALOGW("Device doesn't exist in the list");
1014 pthread_mutex_lock(&iot_mutex_lock);
1015 iot_devlist_fp = fopen(filename, "rt");
1017 if (iot_devlist_fp == NULL) {
1018 ALOGE(" File %s does not exist ", filename);
1019 pthread_mutex_unlock(&iot_mutex_lock);
1022 iot_devlist_new_fp = fopen(IOT_DEV_CONF_BKP_FILE, "wt");
1024 if (iot_devlist_new_fp == NULL) {
1025 ALOGE(" Unable to create backup file %s", IOT_DEV_CONF_BKP_FILE);
1026 fclose(iot_devlist_fp);
1027 pthread_mutex_unlock(&iot_mutex_lock);
1031 /* then copy the device addr/device name */
1032 while (fgets(line_start, sizeof line_start, iot_devlist_fp)) {
1033 len = strlen(line_start);
1036 get_header_from_line(line_start, header_name);
1037 if(method_type == METHOD_BD) {
1038 form_bd_addr((char*)device_details, bd_addr, MAX_ADDR_STR_LEN);
1041 else if(method_type == METHOD_NAME) {
1042 dev = (char *) device_details;
1044 // copy as it is if the line consists comments
1045 if( (line_start[0] == '#') || (line_start[0] == '/') ||
1046 (line_start[0] == ' ') || (line_start[0] == '\n')) {
1047 fputs(line_start, iot_devlist_new_fp);
1049 else if((!strcmp(header_name, header)) && (strstr(line_start, dev))) {
1050 if(is_single_entry_line(line_start)) {
1051 if(!remove_iot_device_from_queue(device_details, header, method_type)) {
1052 // if unable to remove from queue put the same line as it is
1053 fputs(line_start, iot_devlist_new_fp);
1056 ALOGE(" Removed %s device from blacklist file %s", dev, IOT_DEV_CONF_FILE);
1060 if(remove_iot_device_from_queue(device_details, header, method_type)) {
1061 edit_line(line_start, dev, len + 1);
1062 fputs(line_start, iot_devlist_new_fp);
1063 ALOGE(" Removed %s device from blacklist file %s", dev, IOT_DEV_CONF_FILE);
1066 fputs(line_start, iot_devlist_new_fp);
1071 fputs(line_start, iot_devlist_new_fp);
1076 fclose(iot_devlist_fp);
1077 fclose(iot_devlist_new_fp);
1079 rename(IOT_DEV_CONF_BKP_FILE, filename);
1080 pthread_mutex_unlock(&iot_mutex_lock);
1084 /*****************************************************************************
1086 ** Function init_soc_type
1088 ** Description Get Bluetooth SoC type from system setting and stores it
1093 *******************************************************************************/
1094 static void init_soc_type()
1097 char bt_soc_type[PROPERTY_VALUE_MAX];
1099 ALOGI("init_soc_type");
1101 soc_type = BT_SOC_DEFAULT;
1102 ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL);
1105 ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type);
1106 for ( i = 0 ; i < sizeof(soc_type_entries)/sizeof(soc_type_entries[0]) ; i++ )
1108 char* soc_name = soc_type_entries[i].soc_name;
1109 if (!strcmp(bt_soc_type, soc_name)) {
1110 soc_type = soc_type_entries[i].soc_type;
1117 /*****************************************************************************
1119 ** Function get_soc_type
1121 ** Description This function is used to get the Bluetooth SoC type.
1123 ** Returns bt_soc_type.
1125 *******************************************************************************/
1126 bt_soc_type get_soc_type()