diff options
| author | Srinu Jella <sjella@codeaurora.org> | 2015-10-08 17:14:16 +0530 |
|---|---|---|
| committer | Srinu Jella <sjella@codeaurora.org> | 2015-10-15 11:26:42 +0530 |
| commit | 3692a46fd8a70dbaaaf9f88565d1116a0004e348 (patch) | |
| tree | 5423b9ec81b0f19e83d1ea6431be1a8b26474265 /utils/src | |
| parent | 372bc8d755d4fd727c6a85355532551bdd415bf5 (diff) | |
| download | android_system_bt-3692a46fd8a70dbaaaf9f88565d1116a0004e348.tar.gz android_system_bt-3692a46fd8a70dbaaaf9f88565d1116a0004e348.tar.bz2 android_system_bt-3692a46fd8a70dbaaaf9f88565d1116a0004e348.zip | |
Bluetooth: Implement dynamic blacklist method for role switch
- Blacklist the device if it's rejected the role switch for
max number of times.Same is added to the iot_devlist.conf
file.
- Maximum number of failed (BTM_MAX_SW_ROLE_FAILED_ATTEMPTS)
attempts set to 3 and it is configurable.
- Same blacklisted device is referred by the BTM module when
any other module like profile is requesting for role switch
and BTM module returns BTM_REPEATED_ATTEMPTS as the switch
role status.
- There is option to retry for role switch even though the
device is blacklisted and it can be controlled by feature
flag BTM_SAFE_REATTEMPT_ROLE_SWITCH. And by default it is
enabled.
CRs-Fixed: 831542
Change-Id: I570e1539578e60901794941ca46f0722e368a954
Diffstat (limited to 'utils/src')
| -rw-r--r-- | utils/src/bt_utils.c | 884 |
1 files changed, 884 insertions, 0 deletions
diff --git a/utils/src/bt_utils.c b/utils/src/bt_utils.c index 4a73c8057..4bd4abdf6 100644 --- a/utils/src/bt_utils.c +++ b/utils/src/bt_utils.c @@ -42,8 +42,38 @@ #include "btcore/include/module.h" #include "osi/include/compat.h" #include "osi/include/log.h" +#include "gki.h" +#include "list.h" +#include <string.h> /******************************************************************************* +** Local type definitions +*******************************************************************************/ +typedef struct { + char header_name[MAX_NAME_LEN]; // name of header in iot_devlist_conf file + list_t *devlist; // list of BD addresses + tBLACKLIST_METHOD method_type; +} iot_header_node_t; + +typedef struct { + char dev_bd[3]; // BD address of blacklisted device +} iot_devlist_bd_node_t; + +typedef struct { + char dev_name[MAX_NAME_LEN]; // Name of blacklisted device +} iot_devlist_name_node_t; + +typedef struct { + char *header; // header name + unsigned char *dev_details; // details of blacklisted device + bool device_found; +} iot_input_param; + +static list_t *iot_header_queue = NULL; +#define MAX_LINE 2048 +#define MAX_ADDR_STR_LEN 9 +static pthread_mutex_t iot_mutex_lock; +/******************************************************************************* ** Type definitions for callback functions ********************************************************************************/ static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX]; @@ -65,11 +95,13 @@ static future_t *init(void) { pthread_mutexattr_init(&lock_attr); pthread_mutex_init(&gIdxLock, &lock_attr); + pthread_mutex_init(&iot_mutex_lock, NULL); return NULL; } static future_t *clean_up(void) { pthread_mutex_destroy(&gIdxLock); + pthread_mutex_destroy(&iot_mutex_lock); return NULL; } @@ -174,3 +206,855 @@ void adjust_priority_a2dp(int start) { } } } + +/***************************************************************************** +** +** Function check_bd_cb +** +** Description Compares the BD address. +** +** Returns returns true if the BD address matches otherwise false +** +*******************************************************************************/ +static bool check_bd_cb(void* node, void* cb_data) +{ + iot_devlist_bd_node_t *bd_node = (iot_devlist_bd_node_t*)node; + iot_input_param *input_param = (iot_input_param*)cb_data; + + if (input_param->device_found == true) + return true; + + if ((bd_node->dev_bd[0] == input_param->dev_details[0]) && + (bd_node->dev_bd[1] == input_param->dev_details[1]) && + (bd_node->dev_bd[2] == input_param->dev_details[2])) { + input_param->device_found = true; + return true; + } + return false; +} + +/***************************************************************************** +** +** Function check_name_cb +** +** Description Compares the Device name. +** +** Returns returns true if the name matches otherwise false +** +*******************************************************************************/ +static bool check_name_cb(void* node, void* cb_data) +{ + iot_devlist_name_node_t *name_node = (iot_devlist_name_node_t*)node; + iot_input_param *input_param = (iot_input_param*)cb_data; + + if (input_param->device_found == true) + return true; + + if (!strncmp(name_node->dev_name, (const char*)input_param->dev_details, + strlen((char *)input_param->dev_details))) { + input_param->device_found = true; + return true; + } + return false; +} + +/***************************************************************************** +** +** Function check_header_cb +** +** Description Iterates through the each entry in the header list and +** calls the callback associated to each entry. +** +** Returns boolean +** +*******************************************************************************/ +static bool check_header_cb(void* node, void* cb_data) +{ + iot_header_node_t *header_node = (iot_header_node_t*)node; + iot_input_param *input_param = (iot_input_param*)cb_data; + if (!strcmp(header_node->header_name, input_param->header)) { + if(header_node->devlist) { + if (header_node->method_type == METHOD_BD) + list_foreach_ext(header_node->devlist, check_bd_cb, cb_data); + else if (header_node->method_type == METHOD_NAME) + list_foreach_ext(header_node->devlist, check_name_cb, cb_data); + } + } + return true; +} + +/***************************************************************************** +** +** Function is_device_present +** +** Description Checks if the device is already present in the blacklisted +** device list or not.The input can be address based or name +** based. +** +** Returns true incase device is present false otherwise. +** +*******************************************************************************/ +bool is_device_present(char* header, unsigned char* device_details) +{ + int device_present = false; + iot_input_param input_param; + input_param.dev_details = device_details; + input_param.header = header; + input_param.device_found = false; + + pthread_mutex_lock(&iot_mutex_lock); + if (!iot_header_queue) { + pthread_mutex_unlock(&iot_mutex_lock); + return false; + } + list_foreach_ext(iot_header_queue, check_header_cb, &input_param); + pthread_mutex_unlock(&iot_mutex_lock); + + if (input_param.device_found) + return true; + else + return false; +} + +/***************************************************************************** +** +** Function parse_bd +** +** Description It will read 3 bytes and copy them into node. It also +** increments header pointer. +** +** Returns void. +** +*******************************************************************************/ +static void parse_bd(char **start_ptr, iot_devlist_bd_node_t *bd) +{ + char *p_end; + bd->dev_bd[0] = (unsigned char)strtol(*start_ptr, &p_end, 16); + (*start_ptr) = p_end + 1; + bd->dev_bd[1] = (unsigned char)strtol(*start_ptr, &p_end, 16); + (*start_ptr) = p_end + 1; + bd->dev_bd[2] = (unsigned char)strtol(*start_ptr, &p_end, 16); + (*start_ptr) = p_end; +} + +/***************************************************************************** +** +** Function parse_name +** +** Description It will read name and copy them into node. It also +** increments header pointer. +** +** Returns void. +** +*******************************************************************************/ +static void parse_name(char **start_ptr, iot_devlist_name_node_t *name) +{ + char *split = strchr(*start_ptr, ','); // split point to first occurrence of , + int len = 0; + if (split == NULL) { + // check once for end of line, for the last name in list + split = strchr(*start_ptr, '\n'); + if (split == NULL) + return; + } + len = (((split - (*start_ptr)) >= MAX_NAME_LEN) ? MAX_NAME_LEN - 1 : + (split - (*start_ptr))); + memcpy(name->dev_name, *start_ptr, len); + name->dev_name[len] = '\0'; + *start_ptr = split; +} + +/***************************************************************************** +** +** Function is_device_node_exist +** +** Description Checks if the device node is already present in the queue +** or not.The input can be address based or name based. +** +** Returns true if the entry found else false. +** +*******************************************************************************/ +static bool is_device_node_exist(iot_header_node_t *header_entry, char* device_details, + tBLACKLIST_METHOD method_type) +{ + if(!header_entry || !header_entry->devlist) + return false; + + for (const list_node_t *device_node = list_begin(header_entry->devlist); + device_node != list_end(header_entry->devlist); + device_node = list_next(device_node)) { + if(method_type == METHOD_BD) { + iot_devlist_bd_node_t *bd_addr_entry = list_node(device_node); + if(!memcmp(device_details, bd_addr_entry->dev_bd, 3)) { + return true; + } + } + else if(method_type == METHOD_NAME) { + iot_devlist_name_node_t *bd_name_entry = list_node(device_node); + if(!strcmp((char *)device_details, bd_name_entry->dev_name)) { + return true; + } + } + } + return false; +} + +/***************************************************************************** +** +** Function populate_list +** +** Description It goes through the input buffer and add device node to the +** header list if the valid entry is found.It ignores the +** duplicated entries. +** +** Returns void. +** +*******************************************************************************/ +static void populate_list(char *header_end, iot_header_node_t *node) +{ + if(node->devlist == NULL) + node->devlist = list_new(GKI_freebuf); + while(header_end && (*header_end != '\n')&&(*header_end != '\0')) // till end of line reached + { + // read from line buffer and copy to list + if (node->method_type == METHOD_BD) { + iot_devlist_bd_node_t *bd = GKI_getbuf(sizeof(iot_devlist_bd_node_t)); + if(bd == NULL) { + ALOGE(" Unable to allocate memory for addr entry"); + return; + } + header_end++; + parse_bd(&header_end, bd); + if(is_device_node_exist(node, (char *) bd, node->method_type)) { + GKI_freebuf(bd); + } + else { + list_append(node->devlist, bd); + } + } + else if (node->method_type == METHOD_NAME) { + iot_devlist_name_node_t *name = GKI_getbuf(sizeof(iot_devlist_name_node_t)); + if(name == NULL) { + ALOGE(" Unable to allocate memory for name entry"); + return; + } + header_end++; + parse_name(&header_end, name); + if(is_device_node_exist(node, (char *)name, node->method_type)) { + GKI_freebuf(name); + } + else { + list_append(node->devlist, name); + } + } + } +} + +/***************************************************************************** +** +** Function create_header_node +** +** Description This function is used to create the header node. +** +** Returns valid pointer incase the node is created otherwise NULL. +** +*******************************************************************************/ +static iot_header_node_t *create_header_node(char* name, unsigned int len, + tBLACKLIST_METHOD method_type) +{ + iot_header_node_t *node = NULL; + if(len >= MAX_NAME_LEN) { + return NULL; + } + node = GKI_getbuf(sizeof(iot_header_node_t)); + if (node == NULL) { + ALOGE(" Not enough memory to create the header node"); + return NULL; + } + memcpy(node->header_name, name, len); + node->header_name[len] = '\0'; // header copied + node->method_type = method_type; + node->devlist = NULL; + return node; +} + +/***************************************************************************** +** +** Function get_existing_header_node +** +** Description This function is used to get exisiting header node if present. +** +** Returns valid pointer incase the node is already prsent otherwise NULL. +** +*******************************************************************************/ +static iot_header_node_t *get_existing_header_node(char* name, unsigned int len) +{ + for (const list_node_t *node = list_begin(iot_header_queue); + node != list_end(iot_header_queue); node = list_next(node)) { + iot_header_node_t *entry = list_node(node); + if (!strncmp(entry->header_name, name, len)) { + return entry; + } + } + return NULL; +} + +/***************************************************************************** +** +** Function populate_header +** +** Description It goes through the input buffer and add header node to the +** main queue if the valid entry is found.It ignores the +** duplicated entries. +** +** Returns void. +** +*******************************************************************************/ +static void populate_header(char* line_start, char *header_end) +{ + tBLACKLIST_METHOD method_type; + iot_header_node_t *node = NULL; + + if (*(header_end + 3) == ':') + method_type = METHOD_BD; + else + method_type = METHOD_NAME; + + if (!iot_header_queue) { + iot_header_queue = list_new(GKI_freebuf); + if (iot_header_queue == NULL) { + ALOGE(" Not enough memory to create the queue"); + return; + } + } + + if( (node = get_existing_header_node(line_start, header_end - line_start)) == NULL) { + node = create_header_node(line_start, header_end - line_start, method_type); + if(node) + list_append(iot_header_queue, node); + } + if(node) + populate_list(header_end, node); +} + +/***************************************************************************** +** +** Function free_header_list +** +** Description This function is used to free all entries under blacklist +** queue. +** +** Returns boolean +** +*******************************************************************************/ +static bool free_header_list(void* node) +{ + iot_header_node_t *header_node = (iot_header_node_t*)node; + list_free(header_node->devlist); + return true; +} + +/***************************************************************************** +** +** Function unload_iot_devlist +** +** Description This function is used to free the IOT blacklist queue. +** +** Returns void +** +*******************************************************************************/ +void unload_iot_devlist() +{ + pthread_mutex_lock(&iot_mutex_lock); + if (!iot_header_queue) { + ALOGV(" Blacklist queue is not initialized "); + pthread_mutex_unlock(&iot_mutex_lock); + return; + } + list_foreach(iot_header_queue, free_header_list); + list_free(iot_header_queue); + iot_header_queue = NULL; + pthread_mutex_unlock(&iot_mutex_lock); +} + +/***************************************************************************** +** +** Function copy_file +** +** Description This function is used to copy one file to other. +** +** Returns true incase copy is successful otherwise false. +** +*******************************************************************************/ +static bool copy_file(const char *src, const char *dst) +{ + FILE *src_fp = NULL, *dst_fp = NULL; + int ch; + + if( !src || !dst) { + return false; + } + src_fp = fopen(src, "rt"); + if(src_fp) + dst_fp = fopen(dst, "wt"); + if(src_fp && dst_fp) { + while( ( ch = fgetc(src_fp) ) != EOF ) { + fputc(ch, dst_fp); + } + fclose(dst_fp); + fclose(src_fp); + return true; + } + else { + if(src_fp) + fclose(src_fp); + if(dst_fp) + fclose(dst_fp); + return false; + } +} + +/***************************************************************************** +** +** Function dump_all_iot_devices +** +** Description This function is used to print all blacklisted devices +** which are loaded from iot_devlist.conf file.. +** +** Returns void. +** +*******************************************************************************/ +static void dump_all_iot_devices(void) +{ + tBLACKLIST_METHOD method_type; + + if(!iot_header_queue) + return; + + for (const list_node_t *header_node = list_begin(iot_header_queue); + header_node != list_end(iot_header_queue); + header_node = list_next(header_node)) { + iot_header_node_t *header_entry = list_node(header_node); + method_type = header_entry->method_type; + + if(!header_entry->devlist) + continue; + + ALOGW(" ########### Blacklisted Device summary ##############"); + for (const list_node_t *device_node = list_begin(header_entry->devlist); + device_node != list_end(header_entry->devlist); + device_node = list_next(device_node)) { + if(method_type == METHOD_BD) { + iot_devlist_bd_node_t *bd_addr_entry = list_node(device_node); + ALOGW(" Device %02X:%02X:%02X Blacklisted under %s", + bd_addr_entry->dev_bd[0], bd_addr_entry->dev_bd[1], + bd_addr_entry->dev_bd[2], header_entry->header_name); + } + else if(method_type == METHOD_NAME) { + iot_devlist_name_node_t *bd_name_entry = list_node(device_node); + ALOGW(" Device %s Blacklisted under %s", bd_name_entry->dev_name, + header_entry->header_name); + } + } + } +} + +/***************************************************************************** +** +** Function load_iot_devlist_from_file +** +** Description This function is used to initialize the queue and load the +** load the devices from file. +** +** Returns void. +** +*******************************************************************************/ +void load_iot_devlist_from_file(const char *filename) +{ + if (!filename) { + ALOGE(" Invalid IOT blacklist filename"); + return; + } + char line_start[MAX_LINE]; + int line_number = 0; + char *header_end = NULL; + FILE *iot_devlist_fp = fopen(filename, "rt"); + if (iot_devlist_fp == NULL) { + if(!strcmp(filename, IOT_DEV_CONF_FILE)) { + //load it from system partition + if(copy_file(IOT_DEV_BASE_CONF_FILE, IOT_DEV_CONF_FILE) == false) { + ALOGE(" Can't copy it from Base file %s", IOT_DEV_BASE_CONF_FILE); + return; + } + else { + if((iot_devlist_fp = fopen(filename, "rt")) == NULL) + return; + } + } + else { + ALOGE(" File %s does not exist ",filename); + return; + } + } + while(fgets(line_start, MAX_LINE, iot_devlist_fp)) { + line_number++; + if((*line_start == '\n') ||(*line_start == '#')) { + ALOGV("line %d is empty",line_number); + continue; + } + header_end = strchr(line_start, '='); + if (header_end == NULL) { + ALOGV(" NOT A valid line %d", line_number); + continue; + } + populate_header(line_start, header_end); + } + dump_all_iot_devices(); + fclose(iot_devlist_fp); +} + +/***************************************************************************** +** +** Function load_iot_devlist +** +** Description This function is used to initialize the queue. +** +** Returns void. +** +*******************************************************************************/ +void load_iot_devlist(const char *filename) +{ + pthread_mutex_lock(&iot_mutex_lock); + load_iot_devlist_from_file(filename); + pthread_mutex_unlock(&iot_mutex_lock); +} + +/***************************************************************************** +** +** Function add_iot_device +** +** Description This function is used to add the device to the blacklist file +** as well as queue. +** +** Returns true incase the device is blacklisted otherwise fasle. +** +*******************************************************************************/ +bool add_iot_device(const char *filename, char* header, + unsigned char* device_details, tBLACKLIST_METHOD method_type) +{ + char line_start[MAX_LINE]; + FILE *iot_devlist_fp; + char *header_end = NULL; + int index = 0, i, len = 0; + + if((header == NULL) || (device_details == NULL)) { + ALOGE("Error adding device to the list: Invalid input data"); + return false; + } + if (is_device_present (header , device_details)) { + ALOGW("Device already present in the blacklist"); + return true; + } + + pthread_mutex_lock(&iot_mutex_lock); + iot_devlist_fp = fopen(filename, "a"); + + if (iot_devlist_fp == NULL) { + ALOGE(" File %s does not exist ", filename); + pthread_mutex_unlock(&iot_mutex_lock); + return false; + } + /* first copy the header */ + len = strlcpy(&line_start[index], header, strlen(header)+ 1); + index += len; + + line_start[index++] = '='; + /* then copy the device addr/device name */ + if(method_type == METHOD_BD) { + /* for addr take first 3 bytes */ + for(i = 0; i < 3; i++) { + if(i < 2) { + len = snprintf(&line_start[index], MAX_LINE - index, "%02X:", + *(device_details + i)); + } + else { + len = snprintf(&line_start[index], MAX_LINE - index, "%02X", + *(device_details + i)); + } + index += len; + } + } + else if(method_type == METHOD_NAME) { + len = strlcpy(&line_start[index], (const char*) device_details, + strlen((const char*)device_details) + 1); + index += len; + } + /* append the new line characer at the end */ + line_start[index++] = '\n'; + line_start[index++] = '\0'; + + header_end = strchr(line_start,'='); + if(header_end) { + populate_header(line_start, header_end); + } + if(fputs(line_start, iot_devlist_fp)) { + fclose(iot_devlist_fp); + pthread_mutex_unlock(&iot_mutex_lock); + return true; + } + else { + fclose(iot_devlist_fp); + pthread_mutex_unlock(&iot_mutex_lock); + return false; + } +} + +/***************************************************************************** +** +** Function form_bd_addr +** +** Description Adds the colon after 2 bytes to form valid BD address to +** compare the entry prsent in file. +** +** Returns void +** +*******************************************************************************/ +static void form_bd_addr(char *addr, char *new_addr, int max_len) +{ + int i = 0, index = 0, len =0; + /* for addr take first 3 bytes */ + for(i = 0; i < 3; i++) { + if(i < 2) { + len = snprintf(&new_addr[index], max_len - index, "%02X:", + *(addr + i)); + } + else { + len = snprintf(&new_addr[index], max_len - index, "%02X", + *(addr + i)); + } + index += len; + } + new_addr[max_len - 1]= '\0'; +} + +/***************************************************************************** +** +** Function remove_iot_device_from_queue +** +** Description This function is used remove the entry from internal queue. +** +** Returns true if the entry removed from queue else false. +** +*******************************************************************************/ +bool remove_iot_device_from_queue(unsigned char* device_details, char* header, + tBLACKLIST_METHOD method_type) +{ + if(!iot_header_queue) + return false; + for (const list_node_t *header_node = list_begin(iot_header_queue); + header_node != list_end(iot_header_queue); + header_node = list_next(header_node)) { + iot_header_node_t *header_entry = list_node(header_node); + + if(!header_entry->devlist) + continue; + + if((!strcmp(header, header_entry->header_name)) && + method_type == header_entry->method_type) { + + for (const list_node_t *device_node = list_begin(header_entry->devlist); + device_node != list_end(header_entry->devlist); + device_node = list_next(device_node)) { + if(method_type == METHOD_BD) { + iot_devlist_bd_node_t *bd_addr_entry = list_node(device_node); + if(!memcmp(device_details, bd_addr_entry->dev_bd, 3)) { + list_remove(header_entry->devlist, bd_addr_entry); + return true; + } + } + else if(method_type == METHOD_NAME) { + iot_devlist_name_node_t *bd_name_entry = list_node(device_node); + if(!strcmp((char *)device_details, bd_name_entry->dev_name)) { + list_remove(header_entry->devlist, bd_name_entry); + return true; + } + } + } + } + } + return false; +} + +/***************************************************************************** +** +** Function edit_line +** +** Description This function is used to remove the device entry from the +** inputted line buffer if the entry present. +** +** Returns true if the entry removed from line else false. +** +*******************************************************************************/ +static void edit_line(char *line_start, char *dev_info, int line_len) +{ + char *dev_ptr = strstr(line_start, dev_info); + char *comma_ptr = NULL; + int len_to_copy = 0; + if(dev_ptr) { + comma_ptr = strchr(dev_ptr, ','); + if(comma_ptr) { + len_to_copy = line_len - (comma_ptr - line_start + 1); + } + else { + *(dev_ptr - 1) = '\n'; + *(dev_ptr) = '\0'; + } + } + if(len_to_copy) { + memmove(dev_ptr, comma_ptr + 1, len_to_copy); + } +} + +/***************************************************************************** +** +** Function is_single_entry_line +** +** Description This function is used to check the line consists of single +** input line if the entry present. +** +** Returns true if the single entry present else false. +** +*******************************************************************************/ +static bool is_single_entry_line(char *line_start) +{ + char *comma_ptr = strchr(line_start, ','); + // check the char next to , + if( !comma_ptr || (*(comma_ptr + 1) == '\n')) { + return true; + } + else { + return false; + } +} + +/***************************************************************************** +** +** Function get_header_from_line +** +** Description This function is used to get the header from line buffer. +** +** Returns true if the header found else false. +** +*******************************************************************************/ +bool get_header_from_line(char *line_start, char* header) +{ + int i = 0; + if(!line_start || !header || !strchr(line_start, '=')) { + return false; + } + while (line_start[i] != '=') { + header[i] = line_start[i]; + i++; + } + header[i] = '\0'; + return true; +} + +/***************************************************************************** +** +** Function remove_iot_device +** +** Description This function is used to remove the device from internal +** blacklisted queue as well as black list file. +** +** Returns true if the device is removed else false. +** +*******************************************************************************/ +bool remove_iot_device(const char *filename, char* header, + unsigned char* device_details, tBLACKLIST_METHOD method_type) +{ + char line_start[MAX_LINE]; + FILE *iot_devlist_fp, *iot_devlist_new_fp; + char *header_end = NULL; + char bd_addr[MAX_ADDR_STR_LEN]; + char header_name[MAX_NAME_LEN] = { 0 }; + char *dev = NULL; + int index = 0, i, len = 0; + + if((header == NULL) || (device_details == NULL)) { + ALOGE("Invalid input data to add the device"); + return false; + } + if (!is_device_present (header , device_details)) { + ALOGW("Device doesn't exist in the list"); + return false; + } + pthread_mutex_lock(&iot_mutex_lock); + iot_devlist_fp = fopen(filename, "rt"); + + if (iot_devlist_fp == NULL) { + ALOGE(" File %s does not exist ", filename); + pthread_mutex_unlock(&iot_mutex_lock); + return false; + } + iot_devlist_new_fp = fopen(IOT_DEV_CONF_BKP_FILE, "wt"); + + if (iot_devlist_new_fp == NULL) { + ALOGE(" Unable to create backup file %s", IOT_DEV_CONF_BKP_FILE); + fclose(iot_devlist_fp); + pthread_mutex_unlock(&iot_mutex_lock); + return false; + } + + /* then copy the device addr/device name */ + while (fgets(line_start, sizeof line_start, iot_devlist_fp)) { + len = strlen(line_start); + + if (len) { + get_header_from_line(line_start, header_name); + if(method_type == METHOD_BD) { + form_bd_addr((char*)device_details, bd_addr, MAX_ADDR_STR_LEN); + dev = bd_addr; + } + else if(method_type == METHOD_NAME) { + dev = (char *) device_details; + } + // copy as it is if the line consists comments + if( (line_start[0] == '#') || (line_start[0] == '/') || + (line_start[0] == ' ') || (line_start[0] == '\n')) { + fputs(line_start, iot_devlist_new_fp); + } + else if((!strcmp(header_name, header)) && (strstr(line_start, dev))) { + if(is_single_entry_line(line_start)) { + if(!remove_iot_device_from_queue(device_details, header, method_type)) { + // if unable to remove from queue put the same line as it is + fputs(line_start, iot_devlist_new_fp); + } + else + ALOGE(" Removed %s device from blacklist file %s", dev, IOT_DEV_CONF_FILE); + } + else { + // multi line entry + if(remove_iot_device_from_queue(device_details, header, method_type)) { + edit_line(line_start, dev, len + 1); + fputs(line_start, iot_devlist_new_fp); + ALOGE(" Removed %s device from blacklist file %s", dev, IOT_DEV_CONF_FILE); + } + else { + fputs(line_start, iot_devlist_new_fp); + } + } + } + else { + fputs(line_start, iot_devlist_new_fp); + } + } + } + + fclose(iot_devlist_fp); + fclose(iot_devlist_new_fp); + remove(filename); + rename(IOT_DEV_CONF_BKP_FILE, filename); + pthread_mutex_unlock(&iot_mutex_lock); + return true; +} |
