mbed-os/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.cpp

140 lines
4.6 KiB
C++

/* Wiced implementation of NetworkInterfaceAPI
* Copyright (c) 2017-2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 "nsapi.h"
#include "lwipopts.h"
#include "WhdSoftAPInterface.h"
#include "nsapi.h"
#include "lwipopts.h"
#include "lwip/etharp.h"
#include "lwip/ethip6.h"
#include "rtos.h"
#include "whd_emac.h"
#include "whd_wifi_api.h"
extern int whd_toerror(whd_result_t res);
extern nsapi_security_t whd_tosecurity(whd_security_t sec);
extern whd_security_t whd_fromsecurity(nsapi_security_t sec);
extern "C" void whd_emac_wifi_link_state_changed(bool state_up, whd_interface_t ifp);
static const whd_event_num_t ap_client_events[] = { WLC_E_DEAUTH, WLC_E_DEAUTH_IND, WLC_E_DISASSOC, WLC_E_DISASSOC_IND, WLC_E_ASSOC_IND, WLC_E_REASSOC_IND, WLC_E_NONE };
static uint16_t ap_event_entry = 2;
WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stack)
: EMACInterface(emac, stack),
_whd_emac(emac)
{
}
int WhdSoftAPInterface::start(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel,
bool start_dhcp_server, const whd_custom_ie_info_t *ie_info)
{
nsapi_error_t err;
/* set up our interface */
if (!_interface) {
nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface);
if (err != NSAPI_ERROR_OK) {
_interface = NULL;
return err;
}
_interface->attach(_connection_status_cb);
}
// setup ssid
whd_ssid_t whd_ssid;
strncpy((char *)whd_ssid.value, ssid, SSID_NAME_SIZE);
whd_ssid.value[SSID_NAME_SIZE - 1] = '\0';
whd_ssid.length = strlen((char *)whd_ssid.value);
// choose network security
whd_security_t whd_security = whd_fromsecurity(security);
/* set up the AP info */
err = whd_wifi_init_ap(_whd_emac.ifp, &whd_ssid, whd_security, (const uint8_t *)pass,
strlen(pass), channel);
if (err != NSAPI_ERROR_OK) {
printf("whd_wifi_init_ap() ERROR: %d\n", err);
return err;
}
if (ie_info) {
err = whd_wifi_manage_custom_ie(_whd_emac.ifp, WHD_ADD_CUSTOM_IE, (const uint8_t *)ie_info->oui,
ie_info->subtype, (const void *)ie_info->data, ie_info->length, ie_info->which_packets);
if (err != NSAPI_ERROR_OK) {
printf("whd_wifi_manage_custom_ie() ERROR: %d\n", err);
return err;
}
}
err = whd_wifi_start_ap(_whd_emac.ifp);
if (err != NSAPI_ERROR_OK) {
printf("whd_wifi_start_ap() ERROR: %d\n", err);
return err;
}
// Set static IP address for SoftAP and bring up
set_dhcp(false);
if (whd_wifi_is_ready_to_transceive(_whd_emac.ifp) == WHD_SUCCESS) {
whd_emac_wifi_link_state_changed(true, _whd_emac.ifp);
}
// bring up
err = _interface->bringup(_dhcp,
_ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0,
DEFAULT_STACK);
if (err != NSAPI_ERROR_OK) {
printf("bringup() ERROR: %d\n", err);
}
return err;
}
int WhdSoftAPInterface::stop(void)
{
return whd_wifi_stop_ap(_whd_emac.ifp);
}
int WhdSoftAPInterface::remove_custom_ie(const whd_custom_ie_info_t *ie_info)
{
return whd_wifi_manage_custom_ie(_whd_emac.ifp, WHD_REMOVE_CUSTOM_IE, (const uint8_t *)ie_info->oui,
ie_info->subtype, (const void *)ie_info->data, ie_info->length, ie_info->which_packets);
}
int WhdSoftAPInterface::get_associated_client_list(void *client_list_buffer, uint16_t buffer_length)
{
return whd_wifi_get_associated_client_list(_whd_emac.ifp, client_list_buffer, buffer_length);
}
int WhdSoftAPInterface::register_event_handler(whd_event_handler_t softap_event_handler)
{
return whd_management_set_event_handler(_whd_emac.ifp, ap_client_events, softap_event_handler, NULL, &ap_event_entry);
}
int WhdSoftAPInterface::unregister_event_handler(void)
{
return whd_wifi_deregister_event_handler(_whd_emac.ifp, ap_event_entry);
}