/** Sets the chip specific AMPDU parameters for AP and STA * For SDK 3.0, and beyond, each chip will need it's own function for setting AMPDU parameters. */ wwd_result_t wwd_wifi_set_ampdu_parameters( void ) { wiced_buffer_t buffer; wwd_result_t retval; /* Set AMPDU Block ACK window size */ uint32_t* data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_AMPDU_BA_WINDOW_SIZE ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) 8; retval = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_STA_INTERFACE ); wiced_assert("set_ampdu_parameters: Failed to set block ack window size\r\n", retval == WWD_SUCCESS ); /* Set number of MPDUs available for AMPDU */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_AMPDU_MPDU ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) 4; retval = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_STA_INTERFACE ); wiced_assert("set_ampdu_parameters: Failed to set number of MPDUs\r\n", retval == WWD_SUCCESS ); /* Set size of advertised receive AMPDU */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_AMPDU_RX_FACTOR ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) AMPDU_RX_FACTOR_8K; retval = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_STA_INTERFACE ); wiced_assert("set_ampdu_parameters: Failed to set advertised receive AMPDU size\r\n", retval == WWD_SUCCESS ); return retval; }
wwd_result_t wwd_wifi_stop_ap( void ) { uint32_t* data; wiced_buffer_t buffer; wiced_buffer_t response; wwd_result_t result; wwd_result_t result2; /* Query bss state (does it exist? if so is it UP?) */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_BSS ); CHECK_IOCTL_BUFFER( data ); *data = wwd_get_bss_index( WWD_AP_INTERFACE ); result = wwd_sdpcm_send_iovar( SDPCM_GET, buffer, &response, WWD_STA_INTERFACE ); if ( result == WWD_WLAN_NOTFOUND ) { /* AP interface does not exist - i.e. it is down */ wwd_wifi_ap_is_up = WICED_FALSE; return WWD_SUCCESS; } CHECK_RETURN( result ); data = (uint32_t*) host_buffer_get_current_piece_data_pointer( response ); if ( data[0] != (uint32_t) BSS_UP ) { /* AP interface indicates it is not up - i.e. it is down */ host_buffer_release( response, WWD_NETWORK_RX ); wwd_wifi_ap_is_up = WICED_FALSE; return WWD_SUCCESS; } host_buffer_release( response, WWD_NETWORK_RX ); /* set BSS down */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, IOVAR_STR_BSS ); CHECK_IOCTL_BUFFER( data ); data[0] = wwd_get_bss_index( WWD_AP_INTERFACE ); data[1] = (uint32_t) BSS_DOWN; CHECK_RETURN( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ) ); /* Wait until AP is brought down */ result = host_rtos_get_semaphore( &wwd_wifi_sleep_flag, (uint32_t) 10000, WICED_FALSE ); result2 = host_rtos_deinit_semaphore( &wwd_wifi_sleep_flag ); if ( result != WWD_SUCCESS ) { return result; } if ( result2 != WWD_SUCCESS ) { return result2; } CHECK_RETURN( wwd_management_set_event_handler( apsta_events, NULL, NULL, WWD_AP_INTERFACE ) ); wwd_wifi_ap_is_up = WICED_FALSE; return WWD_SUCCESS; }
wwd_result_t wwd_wifi_set_block_ack_window_size( wwd_interface_t interface ) { wiced_buffer_t buffer; wwd_result_t retval; uint32_t block_ack_window_size = 2; uint32_t* data = NULL; /* If the AP interface is already up then don't change the Block Ack window size */ if ( wwd_wifi_is_ready_to_transceive( WWD_AP_INTERFACE ) == WWD_SUCCESS ) { return WWD_SUCCESS; } /* AP can handle BA window size of 1 but STA can handle BA window size of 8 */ if ( interface == WWD_STA_INTERFACE ) { block_ack_window_size = 8; } /* Set AMPDU Block ACK window size */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_AMPDU_BA_WINDOW_SIZE ); CHECK_IOCTL_BUFFER( data ); *data = block_ack_window_size; retval = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_STA_INTERFACE ); wiced_assert("set_block_ack_window_size: Failed to set block ack window size\r\n", retval == WWD_SUCCESS ); return retval; }
static besl_result_t p2p_scan( void ) { wiced_buffer_t buffer; wl_p2p_scan_t* p2p_scan; /* Begin p2p scan of the "escan" variety */ p2p_scan = wwd_sdpcm_get_iovar_buffer( &buffer, sizeof(wl_p2p_scan_t), IOVAR_STR_P2P_SCAN ); memset( p2p_scan, 0, sizeof(wl_p2p_scan_t) ); /* Fill in the appropriate details of the scan parameters structure */ p2p_scan->type = 'E'; besl_host_random_bytes((uint8_t*)&p2p_scan->escan.sync_id, sizeof(p2p_scan->escan.sync_id)); p2p_scan->escan.version = htod32(ESCAN_REQ_VERSION); p2p_scan->escan.action = htod16(WL_SCAN_ACTION_START); p2p_scan->escan.params.scan_type = (int8_t) WICED_SCAN_TYPE_ACTIVE; p2p_scan->escan.params.bss_type = (int8_t) WICED_BSS_TYPE_INFRASTRUCTURE; p2p_scan->escan.params.nprobes = (int32_t) -1; p2p_scan->escan.params.active_time = (int32_t) -1; p2p_scan->escan.params.passive_time = (int32_t) -1; p2p_scan->escan.params.home_time = (int32_t) -1; p2p_scan->escan.params.channel_num = 0; p2p_scan->escan.params.ssid.SSID_len = sizeof( P2P_WILDCARD_SSID ) - 1; memcpy( p2p_scan->escan.params.ssid.SSID, P2P_WILDCARD_SSID, sizeof( P2P_WILDCARD_SSID ) - 1 ); if ( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE ) != WWD_SUCCESS ) { return BESL_ERROR_SCAN_START_FAIL; } return BESL_SUCCESS; }
wwd_result_t wwd_wifi_ap_up( void ) { wiced_buffer_t buffer; uint32_t* data; data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, IOVAR_STR_BSS ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = wwd_get_bss_index( WWD_AP_INTERFACE ); data[1] = (uint32_t) BSS_UP; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); /* Wait until AP is brought up */ CHECK_RETURN_WITH_SEMAPHORE( host_rtos_get_semaphore( &wwd_wifi_sleep_flag, (uint32_t) 10000, WICED_FALSE ), &wwd_wifi_sleep_flag ); wwd_wifi_ap_is_up = WICED_TRUE; return WWD_SUCCESS; }
static void p2p_discover( p2p_workspace_t* workspace ) { wwd_result_t result; p2p_message_t message; REFERENCE_DEBUG_ONLY_VARIABLE(result); if ( workspace->p2p_current_state == P2P_STATE_SCANNING ) { workspace->p2p_current_state = P2P_STATE_DISCOVERING; } result = p2p_set_discovery_state( P2P_DISCOVERY_STATE_LISTEN ); wiced_assert("", result == WWD_SUCCESS); while ( host_rtos_pop_from_queue( &p2p_outgoing_packet_queue, &message, 0 ) == WWD_SUCCESS ) { result = wwd_sdpcm_send_iovar( SDPCM_SET, (wiced_buffer_t) message.data, NULL, WICED_STA_INTERFACE ); wiced_assert("", result == WWD_SUCCESS); } }
static besl_result_t p2p_set_discovery_state( p2p_discovery_state_t state ) { wiced_buffer_t buffer; wl_p2p_disc_st_t* discovery_mode = wwd_sdpcm_get_iovar_buffer(&buffer, sizeof(wl_p2p_disc_st_t), IOVAR_STR_P2P_STATE ); discovery_mode->state = state; if (state == P2P_DISCOVERY_STATE_LISTEN) { uint16_t listen_ms; besl_host_random_bytes( (uint8_t*)&listen_ms, 2 ); listen_ms = ( 1 + (listen_ms % P2P_MAX_DISCOVERABLE_INTERVAL ) ) * P2P_BEACON_INTERVAL_MS; discovery_mode->chanspec = 0; discovery_mode->dwell_time_ms = listen_ms; } else { discovery_mode->chanspec = 0; discovery_mode->dwell_time_ms = 0; } return wwd_sdpcm_send_iovar(SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE); }
/* Generic interface for downloading required data onto the dongle */ static int wwd_download2dongle(wwd_interface_t interface, const char *iovar, uint16_t flag, uint16_t dload_type, unsigned char *dload_buf, uint32_t len) { wl_dload_data_t *dload_ptr = (wl_dload_data_t *)dload_buf; unsigned int dload_data_offset; wiced_buffer_t buffer; uint32_t* iov_data; dload_data_offset = offsetof(wl_dload_data_t, data); dload_ptr->flag = (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT) | flag; dload_ptr->dload_type = dload_type; dload_ptr->len = htod32(len - dload_data_offset); dload_ptr->crc = 0; wiced_assert("dload buffer too large", len < 0xffffffff - 8 ); len = len + 8 - (len%8); iov_data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t)len, iovar ); CHECK_IOCTL_BUFFER( iov_data ); memcpy( iov_data, dload_ptr, len); CHECK_RETURN( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, interface ) ); return WWD_SUCCESS; }
wwd_result_t wwd_process_clm_data(void) { wwd_result_t ret = WWD_SUCCESS; uint32_t clm_blob_size; uint32_t datalen; unsigned int size2alloc, data_offset; unsigned char *chunk_buf; uint16_t dl_flag = DL_BEGIN; unsigned int cumulative_len = 0; unsigned int chunk_len; uint32_t size_read; /* clm file size is the initial datalen value which is decremented */ clm_blob_size = resource_get_size( &wifi_firmware_clm_blob ); datalen = clm_blob_size; data_offset = offsetof(wl_dload_data_t, data); size2alloc = data_offset + MAX_CHUNK_LEN; if ((chunk_buf = (unsigned char *)malloc(size2alloc)) != NULL) { memset(chunk_buf, 0, size2alloc); do { if (datalen >= MAX_CHUNK_LEN) chunk_len = MAX_CHUNK_LEN; else chunk_len = datalen; // check size_read is full value also and resource read return if ((ret = resource_read(&wifi_firmware_clm_blob, cumulative_len, chunk_len, &size_read, chunk_buf + data_offset)) != WWD_SUCCESS) { break; } if (size_read != chunk_len) { wiced_assert("During CLM download, resource_read() returned less of the file than should be available\n", 1 == 0); ret = WWD_CLM_BLOB_DLOAD_ERROR; break; } cumulative_len += chunk_len; if (datalen - chunk_len == 0) dl_flag |= DL_END; ret = wwd_download2dongle(WWD_STA_INTERFACE, IOVAR_STR_CLMLOAD, dl_flag, DL_TYPE_CLM, chunk_buf, data_offset + chunk_len); dl_flag &= (uint16_t)~DL_BEGIN; datalen = datalen - chunk_len; } while ((datalen > 0) && (ret == WWD_SUCCESS)); free(chunk_buf); if ( ret != WWD_SUCCESS ) { wwd_result_t ret_clmload_status; wiced_buffer_t buffer; wiced_buffer_t response; void *data; WPRINT_WWD_DEBUG(("clmload (%ld byte file) failed with return %d; ", clm_blob_size, ret)); data = (int*)wwd_sdpcm_get_iovar_buffer( &buffer, 4, IOVAR_STR_CLMLOAD_STATUS ); CHECK_IOCTL_BUFFER( data ); ret_clmload_status = wwd_sdpcm_send_iovar( SDPCM_GET, buffer, &response, WWD_STA_INTERFACE ); if ( ret_clmload_status != WWD_SUCCESS ) { WPRINT_WWD_DEBUG(("clmload_status failed with return %d\n", ret_clmload_status)); } else { uint32_t *clmload_status = (uint32_t *)host_buffer_get_current_piece_data_pointer( response ); if ( clmload_status != NULL ) { WPRINT_WWD_DEBUG(("clmload_status is %lu\n", *clmload_status)); host_buffer_release( response, WWD_NETWORK_RX ); } } } } else { ret = WWD_MALLOC_FAILURE; } return ret; }
static wwd_result_t internal_ap_init( wiced_ssid_t* ssid, wiced_security_t auth_type, const uint8_t* security_key, uint8_t key_length, uint8_t channel ) { wiced_bool_t wait_for_interface = WICED_FALSE; wwd_result_t result; wiced_buffer_t response; wiced_buffer_t buffer; uint32_t* data; uint32_t bss_index = WWD_AP_INTERFACE; #ifdef WICED_WIFI_SOFT_AP_WEP_SUPPORT_ENABLED uint32_t* auth; uint16_t length; #endif if ( ( ( auth_type == WICED_SECURITY_WPA_TKIP_PSK ) || ( auth_type == WICED_SECURITY_WPA2_AES_PSK ) || ( auth_type == WICED_SECURITY_WPA2_MIXED_PSK ) ) && ( ( key_length < (uint8_t) 8 ) || ( key_length > (uint8_t) 64 ) ) ) { WPRINT_APP_INFO(( "Error: WPA security key length must be between 8 and 64\n" )); return WWD_WPA_KEYLEN_BAD; } #ifdef WICED_WIFI_SOFT_AP_WEP_SUPPORT_ENABLED else if( (( auth_type == WICED_SECURITY_WEP_PSK ) || ( auth_type == WICED_SECURITY_WEP_SHARED )) && (( key_length != FORMATTED_ASCII_WEP40_KEY_LENGTH ) && ( key_length != FORMATTED_ASCII_WEP104_KEY_LENGTH )) ) { WPRINT_APP_INFO(( "Error: WEP security Key length must be either 5 / 13 bytes\n" )); return WWD_WEP_KEYLEN_BAD; } #endif if ( ( wwd_wifi_p2p_go_is_up == WICED_TRUE ) || ( wwd_wifi_ap_is_up == WICED_TRUE ) ) { WPRINT_APP_INFO(( "Error: Soft AP or Wi-Fi Direct group owner already up\n" )); return WWD_AP_ALREADY_UP; } /* Query bss state (does it exist? if so is it UP?) */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_BSS ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) bss_index; if ( wwd_sdpcm_send_iovar( SDPCM_GET, buffer, &response, WWD_STA_INTERFACE ) != WWD_SUCCESS ) { /* Note: We don't need to release the response packet since the iovar failed */ wait_for_interface = WICED_TRUE; } else { /* Check if the BSS is already UP, if so return */ uint32_t* data2 = (uint32_t*) host_buffer_get_current_piece_data_pointer( response ); if ( *data2 == (uint32_t) BSS_UP ) { host_buffer_release( response, WWD_NETWORK_RX ); wwd_wifi_ap_is_up = WICED_TRUE; return WWD_SUCCESS; } else { host_buffer_release( response, WWD_NETWORK_RX ); } } CHECK_RETURN( host_rtos_init_semaphore( &wwd_wifi_sleep_flag ) ); /* Register for interested events */ CHECK_RETURN_WITH_SEMAPHORE( wwd_management_set_event_handler( apsta_events, wwd_handle_apsta_event, NULL, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); /* Check if we need to wait for interface to be created */ if ( wait_for_interface == WICED_TRUE ) { CHECK_RETURN_WITH_SEMAPHORE( host_rtos_get_semaphore( &wwd_wifi_sleep_flag, (uint32_t) 10000, WICED_FALSE ), &wwd_wifi_sleep_flag ); } if ( wwd_wifi_set_block_ack_window_size( WWD_AP_INTERFACE ) != WWD_SUCCESS ) { return WWD_SET_BLOCK_ACK_WINDOW_FAIL; } /* Set the SSID */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 40, "bsscfg:" IOVAR_STR_SSID ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = bss_index; /* Set the bsscfg index */ data[1] = ssid->length; /* Set the ssid length */ memcpy( &data[2], (uint8_t*) ssid->value, ssid->length ); CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); /* Set the channel */ data = (uint32_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); *data = channel; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_CHANNEL, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); #ifdef WICED_WIFI_SOFT_AP_WEP_SUPPORT_ENABLED if ( ( auth_type == WICED_SECURITY_WEP_PSK ) || ( auth_type == WICED_SECURITY_WEP_SHARED ) ) { for ( length = 0; length < key_length; length = (uint16_t) ( length + 2 + security_key[ 1 ] ) ) { const wiced_wep_key_t* in_key = (const wiced_wep_key_t*) &security_key[ length ]; wl_wsec_key_t* out_key = (wl_wsec_key_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, sizeof(wl_wsec_key_t) ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( out_key, &wwd_wifi_sleep_flag ); memset( out_key, 0, sizeof(wl_wsec_key_t) ); out_key->index = in_key->index; out_key->len = in_key->length; memcpy( out_key->data, in_key->data, in_key->length ); switch ( in_key->length ) { case WEP40_KEY_LENGTH: out_key->algo = (uint32_t) CRYPTO_ALGO_WEP1; break; case WEP104_KEY_LENGTH: out_key->algo = (uint32_t) CRYPTO_ALGO_WEP128; break; default: host_buffer_release( buffer, WWD_NETWORK_TX ); return WWD_INVALID_KEY; } /* Set the first entry as primary key by default */ if ( length == 0 ) { out_key->flags |= WL_PRIMARY_KEY; } out_key->index = htod32(out_key->index); out_key->len = htod32(out_key->len); out_key->algo = htod32(out_key->algo); out_key->flags = htod32(out_key->flags); CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_KEY, buffer, NULL, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); } /* Set authentication type */ auth = (uint32_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( auth, &wwd_wifi_sleep_flag ); if ( auth_type == WICED_SECURITY_WEP_SHARED ) { *auth = WEP_SHARED_KEY_AUTHENTICATION; /* 1 = Shared Key authentication */ } else { *auth = WEP_OPEN_SYSTEM_AUTHENTICATION; /* 0 = Open System authentication */ } CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_AUTH, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); } #endif data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, "bsscfg:" IOVAR_STR_WSEC ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = bss_index; if ((auth_type & WPS_ENABLED) != 0) { data[1] = (uint32_t) ( ( auth_type & ( ~WPS_ENABLED ) ) | SES_OW_ENABLED ); } else { data[1] = (uint32_t) auth_type; } CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); if ( ( auth_type != WICED_SECURITY_OPEN ) && ( auth_type != WICED_SECURITY_WEP_PSK ) && ( auth_type != WICED_SECURITY_WEP_SHARED ) ) { wsec_pmk_t* psk; /* Set the wpa auth */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, "bsscfg:" IOVAR_STR_WPA_AUTH ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = bss_index; data[1] = (uint32_t) (auth_type == WICED_SECURITY_WPA_TKIP_PSK) ? ( WPA_AUTH_PSK ) : ( WPA2_AUTH_PSK | WPA_AUTH_PSK ); CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); /* Set the passphrase */ psk = (wsec_pmk_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, sizeof(wsec_pmk_t) ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( psk, &wwd_wifi_sleep_flag ); memcpy( psk->key, security_key, key_length ); psk->key_len = key_length; psk->flags = (uint16_t) WSEC_PASSPHRASE; host_rtos_delay_milliseconds( 1 ); /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_WSEC_PMK, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); } /* Set the GMode */ data = (uint32_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); *data = (uint32_t) GMODE_AUTO; result = wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_GMODE, buffer, 0, WWD_AP_INTERFACE ); if ( ( result != WWD_SUCCESS ) && ( result != WWD_WLAN_ASSOCIATED ) ) { wiced_assert("start_ap: Failed to set GMode\n", 0 == 1 ); (void) host_rtos_deinit_semaphore( &wwd_wifi_sleep_flag ); return result; } /* Set the multicast transmission rate to 11 Mbps rather than the default 1 Mbps */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_2G_MULTICAST_RATE ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) RATE_SETTING_11_MBPS; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); /* Set DTIM period */ data = (uint32_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); *data = (uint32_t) WICED_DEFAULT_SOFT_AP_DTIM_PERIOD; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_DTIMPRD, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); #ifdef WICED_DISABLE_SSID_BROADCAST /* Make the AP "hidden" */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_CLOSEDNET ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = (uint32_t) 1; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); #endif #ifdef WICED_WIFI_ISOLATE_AP_CLIENTS result = wwd_wifi_enable_ap_isolate( WWD_AP_INTERFACE, WICED_TRUE ); wiced_assert("start_ap: Failed to disable intra BSS routing\r\n", result == WWD_SUCCESS ); #endif /* WICED_WIFI_ISOLATE_AP_CLIENTS */ return WWD_SUCCESS; }
static wwd_result_t internal_ap_init( wiced_ssid_t* ssid, wiced_security_t auth_type, const uint8_t* security_key, uint8_t key_length, uint8_t channel ) { wiced_bool_t wait_for_interface = WICED_FALSE; wwd_result_t result; wiced_buffer_t response; wiced_buffer_t buffer; uint32_t* data; if ( auth_type == WICED_SECURITY_WEP_PSK ) { return WWD_WEP_NOT_ALLOWED; } if ( ( ( auth_type == WICED_SECURITY_WPA_TKIP_PSK ) || ( auth_type == WICED_SECURITY_WPA2_AES_PSK ) || ( auth_type == WICED_SECURITY_WPA2_MIXED_PSK ) ) && ( ( key_length < (uint8_t) 8 ) || ( key_length > (uint8_t) 64 ) ) ) { return WWD_WPA_KEYLEN_BAD; } if ( wwd_wifi_set_block_ack_window_size( WWD_AP_INTERFACE ) != WWD_SUCCESS ) { return WWD_SET_BLOCK_ACK_WINDOW_FAIL; } /* Query bss state (does it exist? if so is it UP?) */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_BSS ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) CHIP_AP_INTERFACE; if ( wwd_sdpcm_send_iovar( SDPCM_GET, buffer, &response, WWD_STA_INTERFACE ) != WWD_SUCCESS ) { /* Note: We don't need to release the response packet since the iovar failed */ wait_for_interface = WICED_TRUE; } else { /* Check if the BSS is already UP, if so return */ uint32_t* data2 = (uint32_t*) host_buffer_get_current_piece_data_pointer( response ); if ( *data2 == (uint32_t) BSS_UP ) { host_buffer_release( response, WWD_NETWORK_RX ); wwd_wifi_ap_is_up = WICED_TRUE; return WWD_SUCCESS; } else { host_buffer_release( response, WWD_NETWORK_RX ); } } CHECK_RETURN( host_rtos_init_semaphore( &wwd_wifi_sleep_flag ) ); /* Register for interested events */ CHECK_RETURN_WITH_SEMAPHORE( wwd_management_set_event_handler( apsta_events, wwd_handle_apsta_event, NULL, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); /* Set the SSID */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 40, IOVAR_STR_BSSCFG_SSID ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = (uint32_t) CHIP_AP_INTERFACE; /* Set the bsscfg index */ data[1] = ssid->length; /* Set the ssid length */ memcpy( &data[2], (uint8_t*) ssid->value, ssid->length ); CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); /* Check if we need to wait for interface to be created */ if ( wait_for_interface == WICED_TRUE ) { CHECK_RETURN_WITH_SEMAPHORE( host_rtos_get_semaphore( &wwd_wifi_sleep_flag, (uint32_t) 10000, WICED_FALSE ), &wwd_wifi_sleep_flag ); } /* Set the channel */ data = (uint32_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); *data = channel; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_CHANNEL, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, IOVAR_STR_BSSCFG_WSEC ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = (uint32_t) CHIP_AP_INTERFACE; if ((auth_type & WPS_ENABLED) != 0) { data[1] = (uint32_t) ( ( auth_type & ( ~WPS_ENABLED ) ) | SES_OW_ENABLED ); } else { data[1] = (uint32_t) auth_type; } CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); if ( auth_type != WICED_SECURITY_OPEN ) { wsec_pmk_t* psk; /* Set the wpa auth */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, IOVAR_STR_BSSCFG_WPA_AUTH ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = (uint32_t) CHIP_AP_INTERFACE; data[1] = (uint32_t) (auth_type == WICED_SECURITY_WPA_TKIP_PSK) ? ( WPA_AUTH_PSK ) : ( WPA2_AUTH_PSK | WPA_AUTH_PSK ); CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_STA_INTERFACE ), &wwd_wifi_sleep_flag ); /* Set the passphrase */ psk = (wsec_pmk_t*) wwd_sdpcm_get_ioctl_buffer( &buffer, sizeof(wsec_pmk_t) ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( psk, &wwd_wifi_sleep_flag ); memcpy( psk->key, security_key, key_length ); psk->key_len = key_length; psk->flags = (uint16_t) WSEC_PASSPHRASE; host_rtos_delay_milliseconds( 1 ); /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_WSEC_PMK, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); } /* Set the GMode */ data = wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); *data = (uint32_t) GMODE_AUTO; result = wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_GMODE, buffer, 0, WWD_AP_INTERFACE ); if ( ( result != WWD_SUCCESS ) && ( result != WWD_WLAN_ASSOCIATED ) ) { wiced_assert("start_ap: Failed to set GMode\n", 0 == 1 ); (void) host_rtos_deinit_semaphore( &wwd_wifi_sleep_flag ); return result; } /* Set the multicast transmission rate to 11 Mbps rather than the default 1 Mbps */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_2G_MULTICAST_RATE ); CHECK_IOCTL_BUFFER( data ); *data = (uint32_t) RATE_SETTING_11_MBPS; result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_AP_INTERFACE ); wiced_assert("start_ap: Failed to set multicast transmission rate\r\n", result == WWD_SUCCESS ); /* Set DTIM period */ data = wwd_sdpcm_get_ioctl_buffer( &buffer, (uint16_t) 4 ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); *data = (uint32_t) WICED_DEFAULT_SOFT_AP_DTIM_PERIOD; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_SET_DTIMPRD, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); #ifdef WICED_DISABLE_SSID_BROADCAST /* Make the AP "hidden" */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 4, IOVAR_STR_CLOSEDNET ); CHECK_IOCTL_BUFFER_WITH_SEMAPHORE( data, &wwd_wifi_sleep_flag ); data[0] = (uint32_t) 1; CHECK_RETURN_WITH_SEMAPHORE( wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, WWD_AP_INTERFACE ), &wwd_wifi_sleep_flag ); #endif return WWD_SUCCESS; }
void besl_p2p_test( p2p_workspace_t* workspace ) { wiced_buffer_t buffer; wiced_result_t result; uint32_t* data; wiced_mac_t my_mac; REFERENCE_DEBUG_ONLY_VARIABLE(result); wiced_wifi_get_mac_address( &my_mac ); my_mac.octet[0] |= 0x2; wl_p2p_if_t* p2p_if = wwd_sdpcm_get_iovar_buffer( &buffer, sizeof(wl_p2p_if_t), IOVAR_STR_P2P_IFADD ); p2p_if->interface_type = P2P_GROUP_OWNER_MODE; memcpy( &p2p_if->mac_address, &my_mac, sizeof(besl_mac_t) ); result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE ); wiced_assert("", result == WICED_SUCCESS); /* Enable discovery */ data = wwd_sdpcm_get_iovar_buffer( &buffer, 4, IOVAR_STR_P2P_DISC ); *data = 1; result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE ); wiced_assert("", result == WICED_SUCCESS); wiced_buffer_t response; wwd_sdpcm_get_iovar_buffer( &buffer, 4, IOVAR_STR_P2P_DEV ); result = wwd_sdpcm_send_iovar( SDPCM_GET, buffer, &response, WICED_STA_INTERFACE ); wiced_assert("", result == WICED_SUCCESS); workspace->p2p_interface = BESL_READ_32(host_buffer_get_current_piece_data_pointer(response)); host_buffer_release( response, WICED_NETWORK_RX ); BESL_DEBUG( ("interface = %lu\n", workspace->p2p_interface) ); data = wiced_get_ioctl_buffer( &buffer, 4 ); *data = 1; result = wiced_send_ioctl( SDPCM_SET, WLC_SET_CHANNEL, buffer, NULL, workspace->p2p_interface ); wiced_assert("", result == WICED_SUCCESS); /* Set WSEC */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, IOVAR_STR_BSSCFG_WSEC ); data[0] = (uint32_t) workspace->p2p_interface; data[1] = WICED_SECURITY_WPA2_AES_PSK; result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, SDPCM_STA_INTERFACE ); wiced_assert("", result == WICED_SUCCESS); wsec_pmk_t* psk; /* Set the wpa auth */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 8, IOVAR_STR_BSSCFG_WPA_AUTH ); data[0] = (uint32_t) workspace->p2p_interface; data[1] = (uint32_t) WPA2_AUTH_PSK; result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, 0, SDPCM_STA_INTERFACE ); wiced_assert("", result == WICED_SUCCESS ); /* Set the passphrase */ psk = (wsec_pmk_t*) wiced_get_ioctl_buffer( &buffer, sizeof(wsec_pmk_t) ); memcpy( psk->key, "YOUR_AP_PASSPHRASE", 18 ); psk->key_len = 18; psk->flags = (uint16_t) WSEC_PASSPHRASE; host_rtos_delay_milliseconds( 1 ); /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ result = wiced_send_ioctl( SDPCM_SET, WLC_SET_WSEC_PMK, buffer, 0, workspace->p2p_interface ); wiced_assert("", result == WICED_SUCCESS ); wlc_ssid_t* p2p_ssid = wwd_sdpcm_get_iovar_buffer( &buffer, sizeof(wl_p2p_if_t), IOVAR_STR_P2P_SSID ); p2p_ssid->SSID_len = 9; memcpy( p2p_ssid->SSID, "DIRECT-ww", 9 ); result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE ); wiced_assert("", result == WICED_SUCCESS); /* Bring up P2P interface */ wiced_get_ioctl_buffer( &buffer, 0 ); result = wiced_send_ioctl( SDPCM_SET, WLC_UP, buffer, NULL, workspace->p2p_interface ); wiced_assert("", result == WICED_SUCCESS); p2p_set_discovery_state( P2P_DISCOVERY_STATE_LISTEN ); }
static besl_result_t p2p_run_as_go( p2p_workspace_t* workspace, wps_agent_t* wps_registrar ) { uint32_t* data; wwd_result_t result; besl_wps_credential_t credential; wiced_buffer_t buffer; uint8_t passphrase_buffer[32]; uint8_t a; REFERENCE_DEBUG_ONLY_VARIABLE(result); host_rtos_delay_milliseconds( 500 ); /* Limit the rates used on the P2P soft AP */ data = wwd_sdpcm_get_iovar_buffer( &buffer, 4, IOVAR_STR_BSS_RATESET ); data[0] = 1; result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WICED_AP_INTERFACE ); wiced_assert("", result == WWD_SUCCESS); /* Prepare the AP credentials */ credential.security = WICED_SECURITY_WPA2_AES_PSK; credential.ssid.length = workspace->group_candidate.ssid.length; memcpy( credential.ssid.value, workspace->group_candidate.ssid.value, credential.ssid.length ); credential.passphrase_length = 64; besl_host_random_bytes(passphrase_buffer, 32); for ( a = 0; a < 32; ++a ) { credential.passphrase[2*a] = nibble_to_hexchar(passphrase_buffer[a] >> 4); credential.passphrase[2*a + 1] = nibble_to_hexchar(passphrase_buffer[a] & 0x0F); } /* Start the AP */ wwd_wifi_start_ap( &workspace->group_candidate.ssid, WICED_SECURITY_WPA2_AES_PSK | WPS_ENABLED, credential.passphrase, credential.passphrase_length, 1 ); workspace->p2p_interface = WICED_AP_INTERFACE; memcpy( &workspace->device_info.mac_address, &workspace->intended_mac_address, sizeof(besl_mac_t) ); wl_p2p_if_t* p2p_if = wwd_sdpcm_get_iovar_buffer( &buffer, sizeof(wl_p2p_if_t), IOVAR_STR_P2P_IFUPD ); p2p_if->interface_type = P2P_GROUP_OWNER_MODE; memcpy( &p2p_if->mac_address, &workspace->intended_mac_address, sizeof(besl_mac_t) ); result = wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE ); wiced_assert("", result == WWD_SUCCESS); p2p_write_probe_response_ie( workspace ); p2p_write_beacon_ie( workspace ); /* Bring up IP layer on AP interface */ wiced_ip_up( WICED_AP_INTERFACE, WICED_USE_INTERNAL_DHCP_SERVER, &p2p_ip_settings ); besl_wps_init( wps_registrar, workspace->wps_device_details, WPS_REGISTRAR_AGENT, WICED_AP_INTERFACE ); /* Init WPS */ wps_internal_init( wps_registrar, WICED_AP_INTERFACE, WPS_PBC_MODE, "00000000", &credential, 1 ); /* Run WPS state machine in P2P thread */ wiced_wps_thread_main( (uint32_t) wps_registrar ); if ( wps_registrar->wps_result == WPS_COMPLETE ) { workspace->p2p_result = BESL_SUCCESS; } else { workspace->p2p_result = wps_registrar->wps_result; } return BESL_SUCCESS; }
static void p2p_thread_main( uint32_t arg ) { p2p_workspace_t* workspace = (p2p_workspace_t*)arg; wwd_result_t result; p2p_message_t message; uint8_t last_printed_discovered_device = 0; BESL_INFO(("P2P discovery enabled. Advertised as '%s'\n", workspace->p2p_name)); workspace->p2p_result = BESL_IN_PROGRESS; while ( workspace->p2p_current_state != P2P_STATE_COMPLETE && workspace->p2p_current_state != P2P_STATE_ABORTED ) { host_rtos_pop_from_queue(&p2p_message_queue, &message, WICED_NEVER_TIMEOUT); switch(message.type) { case P2P_EVENT_SCAN_COMPLETE: p2p_discover(workspace); break; case P2P_EVENT_DISCOVERY_COMPLETE: if ( workspace->p2p_current_state == P2P_STATE_NEGOTIATING ) { p2p_discover(workspace); break; } /* Otherwise fall through */ case P2P_EVENT_START_REQUESTED: if (workspace->p2p_current_state != P2P_STATE_NEGOTIATING) { workspace->p2p_current_state = P2P_STATE_SCANNING; } result = p2p_set_discovery_state( P2P_DISCOVERY_STATE_SEARCH ); result = p2p_scan( ); break; case P2P_EVENT_PACKET_TO_BE_SENT: result = wwd_sdpcm_send_iovar( SDPCM_SET, (wiced_buffer_t) message.data, NULL, WICED_STA_INTERFACE ); if (result != WWD_SUCCESS) { /* Packet has been lost.. Maybe. Don't think we can recover it though */ } break; case P2P_EVENT_NEGOTIATION_COMPLETE: BESL_INFO( ("P2P negotiation complete...\n") ); workspace->p2p_current_state = P2P_STATE_COMPLETE; break; case P2P_EVENT_STOP_REQUESTED: workspace->p2p_current_state = P2P_STATE_ABORTED; break; case P2P_EVENT_NEW_DEVICE_DISCOVERED: printf( "Found P2P device: %s\r\n", workspace->discovered_devices[last_printed_discovered_device].device_name); ++last_printed_discovered_device; break; default: break; } } /* Remove P2P event handler */ result = wwd_management_set_event_handler( p2p_events, NULL, workspace, workspace->p2p_interface ); wiced_assert("", result == WWD_SUCCESS); /* Remove the unused WPS and P2P IEs */ wps_host_remove_vendor_ie( workspace->p2p_interface, workspace->wps_probe_ie, workspace->wps_probe_ie_length, VENDOR_IE_PROBE_REQUEST ); wps_host_remove_vendor_ie( workspace->p2p_interface, workspace->wps_probe_ie, workspace->wps_probe_ie_length, VENDOR_IE_PROBE_RESPONSE ); p2p_host_remove_vendor_ie( workspace->p2p_interface, workspace->p2p_probe_request_ie, workspace->p2p_probe_request_ie_length, VENDOR_IE_PROBE_REQUEST); p2p_host_remove_vendor_ie( workspace->p2p_interface, workspace->p2p_probe_response_ie, workspace->p2p_probe_response_ie_length, VENDOR_IE_PROBE_RESPONSE); wiced_buffer_t buffer; uint32_t* data; /* Bring down the P2P interface */ data = wwd_sdpcm_get_iovar_buffer(&buffer, sizeof(wiced_mac_t), IOVAR_STR_P2P_IFDEL ); memcpy(data, &workspace->device_info.mac_address, sizeof(wiced_mac_t)); result = wwd_sdpcm_send_iovar(SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE); wiced_assert("", result == WWD_SUCCESS); if (workspace->p2p_current_state == P2P_STATE_COMPLETE) { wps_agent_t* wps_agent = besl_host_malloc( "p2p", sizeof(wps_agent_t) ); if ( wps_agent == NULL ) { goto return_with_error; } memset( wps_agent, 0, sizeof(wps_agent_t) ); if ( workspace->i_am_group_owner == 0 ) { p2p_run_as_client( workspace, wps_agent ); } else { p2p_run_as_go( workspace, wps_agent ); } besl_host_free(wps_agent); } return_with_error: WICED_END_OF_CURRENT_THREAD( ); }
besl_result_t besl_p2p_init( p2p_workspace_t* workspace, const besl_p2p_device_detail_t* device_details ) { wiced_buffer_t buffer; wiced_buffer_t response; uint32_t* data; wwd_result_t result; REFERENCE_DEBUG_ONLY_VARIABLE(result); memset(workspace, 0, sizeof(p2p_workspace_t)); workspace->p2p_capability = 0x0000; workspace->p2p_name = device_details->device_name; workspace->group_owner_intent = 1; /* Turn off all the other Wi-Fi interfaces */ wiced_network_down(WICED_STA_INTERFACE); wiced_network_down(WICED_AP_INTERFACE); /* Query the AP interface to ensure that it is up */ data = (uint32_t*) wwd_sdpcm_get_iovar_buffer( &buffer, (uint16_t) 36, IOVAR_STR_BSSCFG_SSID ); memset(data, 0, 36); data[0] = (uint32_t) CHIP_AP_INTERFACE; wwd_sdpcm_send_iovar( SDPCM_SET, buffer, NULL, WWD_STA_INTERFACE ); /* Enable discovery */ data = wwd_sdpcm_get_iovar_buffer(&buffer, 4, IOVAR_STR_P2P_DISC ); *data = 1; result = wwd_sdpcm_send_iovar(SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE); wiced_assert("", result == WWD_SUCCESS); /* Find what interface is the P2P device */ wwd_sdpcm_get_iovar_buffer(&buffer, 4, IOVAR_STR_P2P_DEV ); result = wwd_sdpcm_send_iovar(SDPCM_GET, buffer, &response, WICED_STA_INTERFACE); wiced_assert("", result == WWD_SUCCESS); workspace->p2p_interface = BESL_READ_32(host_buffer_get_current_piece_data_pointer(response)); host_buffer_release(response, WWD_NETWORK_RX); /* Get the P2P interface MAC address */ besl_host_get_mac_address(&workspace->device_info.mac_address, workspace->p2p_interface); /* Set the standard interface MAC address to be the same as the P2P interface */ besl_host_set_mac_address(&workspace->device_info.mac_address, WICED_STA_INTERFACE); besl_host_set_mac_address(&workspace->device_info.mac_address, WICED_AP_INTERFACE); /* Get the standard MAC address to confirm */ besl_host_get_mac_address(&workspace->intended_mac_address, WICED_STA_INTERFACE); BESL_INFO( ("STA MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", workspace->intended_mac_address.octet[0], workspace->intended_mac_address.octet[1], workspace->intended_mac_address.octet[2], workspace->intended_mac_address.octet[3], workspace->intended_mac_address.octet[4], workspace->intended_mac_address.octet[5]) ); /* Set the device details */ workspace->wps_device_details = &device_details->wps_device_details; /* Allow the P2P library to initialize */ p2p_init(workspace, workspace->p2p_name); /* Bring up P2P interface */ wwd_sdpcm_get_ioctl_buffer( &buffer, 0 ); result = wwd_sdpcm_send_ioctl( SDPCM_SET, WLC_UP, buffer, NULL, workspace->p2p_interface); wiced_assert("", result == WWD_SUCCESS); /* Set wsec to any non-zero value in the discovery bsscfg to ensure our P2P probe responses have the privacy bit set in the 802.11 WPA IE. * Some peer devices may not initiate WPS with us if this bit is not set. */ data = wwd_sdpcm_get_iovar_buffer(&buffer, 8, IOVAR_STR_BSSCFG_WSEC ); data[0] = workspace->p2p_interface; data[1] = WICED_SECURITY_WPA2_AES_PSK; result = wwd_sdpcm_send_iovar(SDPCM_SET, buffer, NULL, WICED_STA_INTERFACE); wiced_assert("", result == WWD_SUCCESS); workspace->p2p_current_state = P2P_STATE_DISCOVERING; /* Add P2P event handler */ result = wwd_management_set_event_handler( p2p_events, p2p_event_handler, workspace, workspace->p2p_interface ); wiced_assert("", result == WWD_SUCCESS); /* Create the message queue */ host_rtos_init_queue(&p2p_message_queue, p2p_message_queue_buffer, sizeof(p2p_message_queue_buffer), sizeof(p2p_message_t)); /* Create the pending outgoing packet queue */ host_rtos_init_queue(&p2p_outgoing_packet_queue, p2p_outgoing_packet_queue_buffer, sizeof(p2p_outgoing_packet_queue_buffer), sizeof(p2p_message_t)); /* Create the P2P thread */ host_rtos_create_thread_with_arg( &p2p_thread, p2p_thread_main, "p2p", p2p_thread_stack, sizeof(p2p_thread_stack), RTOS_HIGHER_PRIORTIY_THAN(RTOS_DEFAULT_THREAD_PRIORITY), (uint32_t)workspace ); return BESL_SUCCESS; }