/* * wifi_api_scan.c * * Created on: 23/04/2017 * Author: pvvx */ #include "FreeRTOS.h" #include #include "main.h" #include #if CONFIG_EXAMPLE_WLAN_FAST_CONNECT #error "Udnef CONFIG_EXAMPLE_WLAN_FAST_CONNECT!" #endif #ifndef USE_FLASH_EEP #error "Define USE_FLASH_EEP!" #endif #include "task.h" #include #include #include "flash_api.h" #include #include "dhcp/dhcps.h" #include "ethernetif.h" #if CONFIG_ETHERNET #include "ethernet_mii/ethernet_mii.h" #endif #include "wlan_lib.h" #include "flash_eep.h" #include "feep_config.h" #include "wifi_api.h" #include "main.h" #include "wifi_user_set.h" /****************************************************** * Constants ******************************************************/ #define SCAN_USE_SEMAPHORE 0 #define MAX_AP_SIZE 64 extern internal_scan_handler_t scan_result_handler_ptr; void wifi_scan_each_report_hdl(char* buf, int buf_len, int flags, void* userdata); /* xQueueWiFiScan = xQueueCreate(25, sizeof(rtw_scan_result_t)); // Create a queue... if(xQueueWebSrv) { */ LOCAL void _wifi_scan_done_hdl(char* buf, int buf_len, int flags, void* userdata) { int i = 0; internal_scan_handler_t * pscan_rec = &scan_result_handler_ptr; rtw_scan_handler_result_t scan_result_report; for (i = 0; i < pscan_rec->scan_cnt; i++) { rtw_memcpy(&scan_result_report.ap_details, pscan_rec->pap_details[i], sizeof(rtw_scan_result_t)); scan_result_report.scan_complete = pscan_rec->scan_complete; scan_result_report.user_data = pscan_rec->user_data; (*pscan_rec->gscan_result_handler)(&scan_result_report); } pscan_rec->scan_complete = RTW_TRUE; scan_result_report.scan_complete = RTW_TRUE; (*pscan_rec->gscan_result_handler)(&scan_result_report); rtw_free(pscan_rec->ap_details); rtw_free(pscan_rec->pap_details); #if SCAN_USE_SEMAPHORE rtw_up_sema(&pscan_rec->scan_semaphore); #else pscan_rec->scan_running = 0; #endif wifi_unreg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, wifi_scan_each_report_hdl); wifi_unreg_event_handler(WIFI_EVENT_SCAN_DONE, _wifi_scan_done_hdl); return; } /* -------- WiFi Scan ------------------------------- */ LOCAL int _wifi_scan(rtw_scan_type_t scan_type, rtw_bss_type_t bss_type) { int ret; scan_buf_arg * pscan_buf; u16 flags = scan_type | (bss_type << 8); wifi_reg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, wifi_scan_each_report_hdl, NULL); wifi_reg_event_handler(WIFI_EVENT_SCAN_DONE, _wifi_scan_done_hdl, NULL); return wext_set_scan(WLAN0_NAME, NULL, 0, flags); } /* -------- WiFi Scan ------------------------------- */ LOCAL int _wifi_scan_networks(rtw_scan_result_handler_t results_handler) { internal_scan_handler_t * pscan_rec = &scan_result_handler_ptr; #if SCAN_USE_SEMAPHORE rtw_bool_t result; if(NULL == pscan_rec->scan_semaphore) rtw_init_sema(&pscan_rec->scan_semaphore, 1); pscan_rec->scan_start_time = rtw_get_current_time(); /* Initialise the semaphore that will prevent simultaneous access - cannot be a mutex, since * we don't want to allow the same thread to start a new scan */ result = (rtw_bool_t)rtw_down_timeout_sema(&pscan_rec->scan_semaphore, SCAN_LONGEST_WAIT_TIME); if ( result != RTW_TRUE ) { /* Return error result, but set the semaphore to work the next time */ rtw_up_sema(&pscan_rec->scan_semaphore); return RTW_TIMEOUT; } #else if (pscan_rec->scan_running) { int count = 100; while (pscan_rec->scan_running && count > 0) { rtw_msleep_os(20); count--; } if (count == 0) { printf("[%d]WiFi: Scan is running. Wait 2s timeout.\n", rtw_get_current_time()); return RTW_TIMEOUT; } } pscan_rec->scan_start_time = rtw_get_current_time(); pscan_rec->scan_running = 1; #endif pscan_rec->gscan_result_handler = results_handler; pscan_rec->max_ap_size = MAX_AP_SIZE; pscan_rec->ap_details = (rtw_scan_result_t*) rtw_zmalloc(MAX_AP_SIZE * sizeof(rtw_scan_result_t) + MAX_AP_SIZE * sizeof(rtw_scan_result_t*)); if (pscan_rec->ap_details != NULL) { pscan_rec->pap_details = (rtw_scan_result_t**) (&pscan_rec->ap_details[MAX_AP_SIZE]); pscan_rec->scan_cnt = 0; pscan_rec->scan_complete = RTW_FALSE; pscan_rec->user_data = NULL; // ????????? if (_wifi_scan(RTW_SCAN_COMMAMD << 4 | RTW_SCAN_TYPE_ACTIVE, RTW_BSS_TYPE_ANY) == RTW_SUCCESS) { return RTW_SUCCESS; }; rtw_free((u8*)pscan_rec->ap_details); }; rtw_memset((void *) pscan_rec, 0, sizeof(internal_scan_handler_t)); return RTW_ERROR; } /* -------- WiFi Scan ------------------------------- */ #define scan_channels 14 /* -------- WiFi Scan ------------------------------- */ LOCAL int wext_set_pscan_channels(void) { struct iwreq iwr; int ret = -1; __u8 *para; int i = 0; rtw_memset(&iwr, 0, sizeof(iwr)); //Format of para:function_name num_channel chan1... pscan_config1 ... iwr.u.data.length = (scan_channels + scan_channels + 1) + 12; para = pvPortMalloc((scan_channels + scan_channels + 1) + 12); //size:num_chan + num_time + length + function_name iwr.u.data.pointer = para; if (para != NULL) { //Cmd rtw_memcpy((char*) para, "PartialScan", 12); //length *(para + 12) = scan_channels; for (i = 0; i < scan_channels; i++) { *(para + 13 + i) = i + 1; *((__u16 *) (para + 13 + scan_channels + i)) = PSCAN_ENABLE; } ret = iw_ioctl(WLAN0_NAME, SIOCDEVPRIVATE, &iwr); vPortFree(para); } #if CONFIG_DEBUG_LOG > 3 else { error_printf("%s: Can't malloc memory!\n", __func__); } #endif return ret; } /* -------- WiFi Scan ------------------------------- */ LOCAL volatile uint8_t scan_end; /* -------- WiFi Scan ------------------------------- */ LOCAL rtw_result_t _scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ) { if (malloced_scan_result->scan_complete != RTW_TRUE) { rtw_scan_result_t* record = &malloced_scan_result->ap_details; record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ if(scan_end == 1) { printf("\nScan networks:\n\n"); printf("N\tType\tMAC\t\t\tSignal\tCh\tWPS\tSecyrity\tSSID\n\n"); }; printf("%d\t", scan_end++); printf("%s\t", (record->bss_type == RTW_BSS_TYPE_ADHOC)? "Adhoc": "Infra"); printf(MAC_FMT, MAC_ARG(record->BSSID.octet)); printf("\t%d\t", record->signal_strength); printf("%d\t", record->channel); printf("%d\t", record->wps_type); { uint8 * s = rtw_security_to_str(record->security); printf("%s\t", s); if(strlen(s) < 8) printf("\t"); } printf("%s\n", record->SSID.val); } else { scan_end = 0; printf("\n"); } return RTW_SUCCESS; } /* -------- WiFi Scan ------------------------------- */ void api_wifi_scan(void) { scan_end = 1; if(wext_set_pscan_channels() < 0){ error_printf("ERROR: wifi set partial scan channel fail\n"); } else if(_wifi_scan_networks(_scan_result_handler) != RTW_SUCCESS){ error_printf("ERROR: wifi scan failed\n"); } else { int i = 300; while(i-- && scan_end) { vTaskDelay(10); }; }; }