diff options
Diffstat (limited to 'lib/scanmerge.c')
-rw-r--r-- | lib/scanmerge.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/lib/scanmerge.c b/lib/scanmerge.c new file mode 100644 index 0000000..2b376ff --- /dev/null +++ b/lib/scanmerge.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*-------------------------------------------------------------------*/ +#include "includes.h" +#include "scanmerge.h" +#include "shlist.h" + +#define IS_HIDDEN_AP(a) (((a)->ssid_len == 0) || ((a)->ssid[0] == '\0')) +/*----------------------------------------------------------------------------- +Routine Name: scan_init +Routine Description: Inits scan merge list +Arguments: + mydrv - pointer to private driver data structure +Return Value: +-----------------------------------------------------------------------------*/ +void scan_init( struct wpa_driver_ti_data *mydrv ) +{ + mydrv->last_scan = -1; + shListInitList( &(mydrv->scan_merge_list) ); +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_free +Routine Description: Frees scan structure private data +Arguments: + ptr - pointer to private data structure +Return Value: +-----------------------------------------------------------------------------*/ +static void scan_free( void *ptr ) +{ + os_free( ptr ); +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_exit +Routine Description: Cleans scan merge list +Arguments: + mydrv - pointer to private driver data structure +Return Value: +-----------------------------------------------------------------------------*/ +void scan_exit( struct wpa_driver_ti_data *mydrv ) +{ + shListDelAllItems( &(mydrv->scan_merge_list), scan_free ); +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_equal +Routine Description: Compares bssid of scan result and scan merge structure +Arguments: + val - pointer to scan result structure + idata - pointer to scan merge structure +Return Value: 1 - if equal, 0 - if not +-----------------------------------------------------------------------------*/ +static int scan_equal( void *val, void *idata ) +{ + struct wpa_scan_result *new_res = (struct wpa_scan_result *)val; + struct wpa_scan_result *lst_res = + (struct wpa_scan_result *)(&(((scan_merge_t *)idata)->scanres)); + int ret; + size_t len; + + len = (IS_HIDDEN_AP(new_res) || IS_HIDDEN_AP(lst_res)) ? + 0 : new_res->ssid_len; + ret = ((lst_res->ssid_len != new_res->ssid_len) && (len != 0)) || + (os_memcmp(new_res->bssid, lst_res->bssid, ETH_ALEN) || + os_memcmp(new_res->ssid, lst_res->ssid, len)); + return !ret; +} + +/*----------------------------------------------------------------------------- +Routine Name: copy_scan_res +Routine Description: copies scan result structure to scan merge list item +Arguments: + dst - pointer to scan result structure in the list + src - source pointer to scan result structure +Return Value: NONE +-----------------------------------------------------------------------------*/ +void copy_scan_res( struct wpa_scan_result *dst, struct wpa_scan_result *src ) +{ + if( IS_HIDDEN_AP(src) ) { + os_memcpy( src->ssid, dst->ssid, dst->ssid_len ); + src->ssid_len = dst->ssid_len; + } + os_memcpy( dst, src, sizeof(struct wpa_scan_result) ); +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_add +Routine Description: adds scan result structure to scan merge list +Arguments: + head - pointer to scan merge list head + res_ptr - pointer to scan result structure +Return Value: Pointer to scan merge item +-----------------------------------------------------------------------------*/ +static scan_merge_t *scan_add( SHLIST *head, struct wpa_scan_result *res_ptr ) +{ + scan_merge_t *scan_ptr; + + scan_ptr = (scan_merge_t *)os_malloc( sizeof(scan_merge_t) ); + if( !scan_ptr ) + return( NULL ); + os_memcpy( &(scan_ptr->scanres), res_ptr, sizeof(struct wpa_scan_result) ); + scan_ptr->count = SCAN_MERGE_COUNT; + shListInsLastItem( head, (void *)scan_ptr ); + return scan_ptr; +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_find +Routine Description: Looks for scan merge item in scan results array +Arguments: + scan_ptr - pointer to scan merge item + results - pointer to scan results array + number_items - current number of items +Return Value: 1 - if item was found, 0 - otherwise +-----------------------------------------------------------------------------*/ +static int scan_find( scan_merge_t *scan_ptr, struct wpa_scan_result *results, + unsigned int number_items ) +{ + unsigned int i; + + for(i=0;( i < number_items );i++) { + if( scan_equal( &(results[i]), scan_ptr ) ) + return 1; + } + return 0; +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_merge +Routine Description: Merges current scan results with previous +Arguments: + mydrv - pointer to private driver data structure + results - pointer to scan results array + number_items - current number of items + max_size - maximum namber of items +Return Value: Merged number of items +-----------------------------------------------------------------------------*/ +unsigned int scan_merge( struct wpa_driver_ti_data *mydrv, + struct wpa_scan_result *results, int force_flag, + unsigned int number_items, unsigned int max_size ) +{ + SHLIST *head = &(mydrv->scan_merge_list); + SHLIST *item, *del_item; + scan_merge_t *scan_ptr; + unsigned int i; + + /* Prepare items for removal */ + item = shListGetFirstItem( head ); + while( item != NULL ) { + scan_ptr = (scan_merge_t *)(item->data); + if( scan_ptr->count != 0 ) + scan_ptr->count--; + item = shListGetNextItem( head, item ); + } + + for(i=0;( i < number_items );i++) { /* Find/Add new items */ + item = shListFindItem( head, &(results[i]), scan_equal ); + if( item ) { + scan_ptr = (scan_merge_t *)(item->data); + copy_scan_res(&(scan_ptr->scanres), &(results[i])); + scan_ptr->count = SCAN_MERGE_COUNT; + } + else { + scan_add( head, &(results[i]) ); + } + } + + item = shListGetFirstItem( head ); /* Add/Remove missing items */ + while( item != NULL ) { + del_item = NULL; + scan_ptr = (scan_merge_t *)(item->data); + if( scan_ptr->count != SCAN_MERGE_COUNT ) { + if( !force_flag && ((scan_ptr->count == 0) || + (mydrv->last_scan == SCAN_TYPE_NORMAL_ACTIVE)) ) + del_item = item; + else { + if( number_items < max_size ) { + os_memcpy(&(results[number_items]), + &(scan_ptr->scanres),sizeof(struct wpa_scan_result)); + number_items++; + } + } + } + item = shListGetNextItem( head, item ); + shListDelItem( head, del_item, scan_free ); + } + + return( number_items ); +} + +/*----------------------------------------------------------------------------- +Routine Name: scan_get_by_bssid +Routine Description: Gets scan_result pointer to item by bssid +Arguments: + mydrv - pointer to private driver data structure + bssid - pointer to bssid value +Return Value: pointer to scan_result item +-----------------------------------------------------------------------------*/ +struct wpa_scan_result *scan_get_by_bssid( struct wpa_driver_ti_data *mydrv, + u8 *bssid ) +{ + SHLIST *head = &(mydrv->scan_merge_list); + SHLIST *item; + struct wpa_scan_result *cur_res; + + item = shListGetFirstItem( head ); /* Add/Remove missing items */ + if( item == NULL ) + return( NULL ); + do { + cur_res = + (struct wpa_scan_result *)&(((scan_merge_t *)(item->data))->scanres); + if( (!os_memcmp(cur_res->bssid, bssid, ETH_ALEN)) && + (!IS_HIDDEN_AP(cur_res)) ) { + return( cur_res ); + } + item = shListGetNextItem( head, item ); + } while( item != NULL ); + + return( NULL ); +} |