/*----------------------------------------------------------------------------- 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 ) { scan_ssid_t n_ssid, l_ssid, *p_ssid; scan_result_t *new_res = (scan_result_t *)val; scan_result_t *lst_res = (scan_result_t *)(&(((scan_merge_t *)idata)->scanres)); int ret; size_t len; p_ssid = scan_get_ssid(new_res); if (!p_ssid) return 0; os_memcpy(&n_ssid, p_ssid, sizeof(scan_ssid_t)); p_ssid = scan_get_ssid(lst_res); if (!p_ssid) return 0; os_memcpy(&l_ssid, p_ssid, sizeof(scan_ssid_t)); len = (IS_HIDDEN_AP(&n_ssid) || IS_HIDDEN_AP(&l_ssid)) ? 0 : n_ssid.ssid_len; ret = ((l_ssid.ssid_len != n_ssid.ssid_len) && (len != 0)) || (os_memcmp(new_res->bssid, lst_res->bssid, ETH_ALEN) || os_memcmp(n_ssid.ssid, l_ssid.ssid, len)); return !ret; }
/*----------------------------------------------------------------------------- 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 -----------------------------------------------------------------------------*/ scan_result_t *scan_get_by_bssid( struct wpa_driver_ti_data *mydrv, u8 *bssid ) { SHLIST *head = &(mydrv->scan_merge_list); SHLIST *item; scan_result_t *cur_res; scan_ssid_t *p_ssid; item = shListGetFirstItem(head); if( item == NULL ) return( NULL ); do { cur_res = (scan_result_t *)&(((scan_merge_t *)(item->data))->scanres); p_ssid = scan_get_ssid(cur_res); if( (!os_memcmp(cur_res->bssid, bssid, ETH_ALEN)) && (!IS_HIDDEN_AP(p_ssid)) ) { return( cur_res ); } item = shListGetNextItem(head, item); } while( item != NULL ); return( NULL ); }
/*----------------------------------------------------------------------------- Routine Name: wpa_driver_tista_driver_cmd Routine Description: executes driver-specific commands Arguments: priv - pointer to private data structure cmd - command buf - return buffer buf_len - buffer length Return Value: actual buffer length - success, -1 - failure -----------------------------------------------------------------------------*/ static int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len ) { struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv; int ret = -1, prev_events, flags; wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd); if( os_strcasecmp(cmd, "start") == 0 ) { wpa_printf(MSG_DEBUG,"Start command"); scan_exit(drv); /* Clear scan cache */ ret = wpa_driver_tista_driver_start(priv); if( ret == 0 ) { drv->driver_is_loaded = TRUE; wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); } return( TI2WPA_STATUS(ret) ); } TI_CHECK_DRIVER( drv->driver_is_loaded, -1 ); if( os_strcasecmp(cmd, "stop") == 0 ) { wpa_printf(MSG_DEBUG,"Stop command"); if ((wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) && (flags & IFF_UP)) { wpa_printf(MSG_ERROR, "TI: %s when iface is UP", cmd); wpa_driver_wext_set_ifflags(drv->wext, flags & ~IFF_UP); } ret = wpa_driver_tista_driver_stop(priv); if( ret == 0 ) { scan_exit(drv); /* Clear scan cache */ drv->driver_is_loaded = FALSE; wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); } } if( os_strcasecmp(cmd, "reload") == 0 ) { wpa_printf(MSG_DEBUG,"Reload command"); ret = 0; wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); } else if( os_strcasecmp(cmd, "macaddr") == 0 ) { wpa_driver_tista_get_mac_addr(priv); wpa_printf(MSG_DEBUG, "Macaddr command"); ret = sprintf(buf, "Macaddr = " MACSTR "\n", MAC2STR(drv->own_addr)); wpa_printf(MSG_DEBUG, "buf %s", buf); } else if( os_strcasecmp(cmd, "scan-passive") == 0 ) { wpa_printf(MSG_DEBUG,"Scan Passive command"); drv->scan_type = SCAN_TYPE_NORMAL_PASSIVE; ret = 0; } else if( os_strcasecmp(cmd, "scan-active") == 0 ) { wpa_printf(MSG_DEBUG,"Scan Active command"); drv->scan_type = SCAN_TYPE_NORMAL_ACTIVE; ret = 0; } else if( os_strcasecmp(cmd, "scan-mode") == 0 ) { wpa_printf(MSG_DEBUG,"Scan Mode command"); ret = snprintf(buf, buf_len, "ScanMode = %u\n", drv->scan_type); if (ret < (int)buf_len) { return( ret ); } } else if( os_strcasecmp(cmd, "linkspeed") == 0 ) { struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx); wpa_printf(MSG_DEBUG,"Link Speed command"); drv->link_speed = wpa_s->link_speed / 1000000; ret = sprintf(buf,"LinkSpeed %u\n", drv->link_speed); wpa_printf(MSG_DEBUG, "buf %s", buf); } else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) { int noOfChan; noOfChan = atoi(cmd + 13); wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan); if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) ) drv->scan_channels = noOfChan; ret = sprintf(buf,"Scan-Channels = %d\n", drv->scan_channels); wpa_printf(MSG_DEBUG, "buf %s", buf); } else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) { scan_result_t *cur_res; struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx); scan_ssid_t *p_ssid; int rssi, len; wpa_printf(MSG_DEBUG,"rssi-approx command"); if( !wpa_s ) return( ret ); cur_res = scan_get_by_bssid(drv, wpa_s->bssid); if( cur_res ) { p_ssid = scan_get_ssid(cur_res); if( p_ssid ) { len = (int)(p_ssid->ssid_len); rssi = cur_res->level; if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) { os_memcpy((void *)buf, (void *)(p_ssid->ssid), len); ret = len; ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi); } } } } else if( os_strcasecmp(cmd, "rssi") == 0 ) { u8 ssid[MAX_SSID_LEN]; scan_result_t *cur_res; struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx); int rssi_data, rssi_beacon, len; wpa_printf(MSG_DEBUG,"rssi command"); ret = wpa_driver_tista_get_rssi(priv, &rssi_data, &rssi_beacon); if( ret == 0 ) { len = wpa_driver_tista_get_ssid(priv, (u8 *)ssid); wpa_printf(MSG_DEBUG,"rssi_data %d rssi_beacon %d", rssi_data, rssi_beacon); if( (len > 0) && (len <= MAX_SSID_LEN) ) { os_memcpy((void *)buf, (void *)ssid, len); ret = len; ret += sprintf(&buf[ret], " rssi %d\n", rssi_beacon); wpa_printf(MSG_DEBUG, "buf %s", buf); /* Update cached value */ if( !wpa_s ) return( ret ); cur_res = scan_get_by_bssid(drv, wpa_s->bssid); if( cur_res ) cur_res->level = rssi_beacon; } else { wpa_printf(MSG_DEBUG, "Fail to get ssid when reporting rssi"); ret = -1; } } } else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) { u32 mode; TPowerMgr_PowerMode tMode; mode = (u32)atoi(cmd + 9); wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode); if( mode < POWER_MODE_MAX ) { tMode.PowerMode = (PowerMgr_PowerMode_e)mode; tMode.PowerMngPriority = POWER_MANAGER_USER_PRIORITY; ret = wpa_driver_tista_config_power_management( priv, &tMode, 1 ); } } else if (os_strncasecmp(cmd, "getpower", 8) == 0 ) { u32 mode; TPowerMgr_PowerMode tMode; os_memset(&tMode, 0, sizeof(TPowerMgr_PowerMode)); ret = wpa_driver_tista_config_power_management( priv, &tMode, 0 ); if( ret == 0 ) { ret = sprintf(buf, "powermode = %u\n", tMode.PowerMode); wpa_printf(MSG_DEBUG, "buf %s", buf); } } else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) { u32 mode; mode = (u32)atoi(cmd + 10); wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode); ret = wpa_driver_tista_enable_bt_coe( priv, mode ); if( ret == 0 ) { drv->btcoex_mode = mode; } } else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) { u32 status = drv->btcoex_mode; wpa_printf(MSG_DEBUG,"BtCoex Status"); ret = wpa_driver_tista_get_bt_coe_status( priv, &status ); if( ret == 0 ) { ret = sprintf(buf, "btcoexstatus = 0x%x\n", status); wpa_printf(MSG_DEBUG, "buf %s", buf); } } else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) { wpa_printf(MSG_DEBUG,"Rx Data Filter Start command"); ret = wpa_driver_tista_driver_enable_rx_data_filter( priv ); } else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) { wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command"); ret = wpa_driver_tista_driver_disable_rx_data_filter( priv ); } else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) { TCuCommon_RxDataFilteringStatistics stats; int len, i; os_memset(&stats, 0, sizeof(TCuCommon_RxDataFilteringStatistics)); wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command"); ret = wpa_driver_tista_driver_rx_data_filter_statistics( priv, &stats ); if( ret == 0 ) { ret = snprintf(buf, buf_len, "RxFilterStat: %u", (u32)stats.unmatchedPacketsCount); for(i=0; ( i < MAX_DATA_FILTERS ); i++) { ret += snprintf(&buf[ret], buf_len-ret, " %u", (u32)stats.matchedPacketsCount[i]); } ret += snprintf(&buf[ret], buf_len-ret, "\n"); if (ret >= (int)buf_len) { ret = -1; } } } else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) { TRxDataFilterRequest dfreq; char *cp = cmd + 12; char *endp; int type; if (*cp != '\0') { type = (int)strtol(cp, &endp, 0); if (endp != cp) { wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type); ret = prepare_filter_struct( priv, type, &dfreq ); if( ret == 0 ) { ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 1 ); } } } } else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) { TRxDataFilterRequest dfreq; char *cp = cmd + 15; char *endp; int type; if (*cp != '\0') { type = (int)strtol(cp, &endp, 0); if (endp != cp) { wpa_printf(MSG_DEBUG,"Rx Data Filter remove [%d] command", type); ret = prepare_filter_struct( priv, type, &dfreq ); if( ret == 0 ) { ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 0 ); } } } } else { wpa_printf(MSG_DEBUG,"Unsupported command"); } return ret; }
unsigned int scan_merge( struct wpa_driver_ti_data *mydrv, scan_result_t *results, int force_flag, unsigned int number_items, unsigned int max_size ) #endif { SHLIST *head = &(mydrv->scan_merge_list); SHLIST *item, *del_item; scan_result_t *res_ptr; 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 */ #if defined WPA_SUPPLICANT_VER_0_6_X || defined WPA_SUPPLICANT_VER_0_8_X res_ptr = results[i]; #else res_ptr = &(results[i]); #endif item = shListFindItem( head, res_ptr, scan_equal ); if( item ) { #if defined WPA_SUPPLICANT_VER_0_6_X || defined WPA_SUPPLICANT_VER_0_8_X scan_ssid_t *p_ssid; scan_result_t *new_ptr; #endif scan_ptr = (scan_merge_t *)(item->data); copy_scan_res(&(scan_ptr->scanres), res_ptr); scan_ptr->count = SCAN_MERGE_COUNT; #if defined WPA_SUPPLICANT_VER_0_6_X || defined WPA_SUPPLICANT_VER_0_8_X p_ssid = scan_get_ssid(res_ptr); if (p_ssid && IS_HIDDEN_AP(p_ssid)) { new_ptr = scan_dup(res_ptr); if (new_ptr) { results[i] = new_ptr; os_free(res_ptr); } } #endif } else { scan_add(head, res_ptr); } } 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 ) { #if defined WPA_SUPPLICANT_VER_0_6_X || defined WPA_SUPPLICANT_VER_0_8_X res_ptr = scan_dup(&(scan_ptr->scanres)); if (res_ptr) { results[number_items] = res_ptr; number_items++; } #else os_memcpy(&(results[number_items]), &(scan_ptr->scanres), sizeof(scan_result_t)); number_items++; #endif } } } item = shListGetNextItem(head, item); shListDelItem(head, del_item, scan_free); } return( number_items ); }