mirror of https://github.com/ARMmbed/mbed-os.git
PSOC6: add WHD EMAC driver
parent
8ede226c16
commit
572221446f
|
@ -0,0 +1,478 @@
|
|||
/* WHD STAION implementation of NetworkInterfaceAPI
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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 <cstring>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "WhdSTAInterface.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"
|
||||
#include "whd_wlioctl.h"
|
||||
|
||||
#define CMP_MAC( a, b ) (((((unsigned char*)a)[0])==(((unsigned char*)b)[0]))&& \
|
||||
((((unsigned char*)a)[1])==(((unsigned char*)b)[1]))&& \
|
||||
((((unsigned char*)a)[2])==(((unsigned char*)b)[2]))&& \
|
||||
((((unsigned char*)a)[3])==(((unsigned char*)b)[3]))&& \
|
||||
((((unsigned char*)a)[4])==(((unsigned char*)b)[4]))&& \
|
||||
((((unsigned char*)a)[5])==(((unsigned char*)b)[5])))
|
||||
|
||||
struct whd_scan_userdata {
|
||||
Semaphore* sema;
|
||||
WiFiAccessPoint *aps;
|
||||
vector<whd_scan_result_t> *result_buff;
|
||||
unsigned count;
|
||||
unsigned offset;
|
||||
whd_interface_t ifp;
|
||||
bool scan_in_progress;
|
||||
};
|
||||
|
||||
static whd_scan_userdata interal_scan_data;
|
||||
static whd_scan_result_t internal_scan_result;
|
||||
static whd_scan_result_t *result_ptr = &internal_scan_result;
|
||||
|
||||
extern "C" void whd_emac_wifi_link_state_changed(bool state_up, whd_interface_t ifp);
|
||||
|
||||
|
||||
int whd_toerror(whd_result_t res) {
|
||||
switch (res) {
|
||||
case WHD_SUCCESS: return NSAPI_ERROR_OK;
|
||||
case WHD_UNSUPPORTED:
|
||||
case WHD_WLAN_UNSUPPORTED:
|
||||
case WHD_WLAN_ACM_NOTSUPPORTED: return NSAPI_ERROR_UNSUPPORTED;
|
||||
case WHD_BADARG:
|
||||
case WHD_WLAN_BADARG: return NSAPI_ERROR_PARAMETER;
|
||||
case WHD_WLAN_NOTASSOCIATED:
|
||||
case WHD_INVALID_JOIN_STATUS: return NSAPI_ERROR_NO_CONNECTION;
|
||||
case WHD_BUFFER_UNAVAILABLE_PERMANENT:
|
||||
case WHD_BUFFER_UNAVAILABLE_TEMPORARY:
|
||||
case WHD_RX_BUFFER_ALLOC_FAIL:
|
||||
case WHD_BUFFER_ALLOC_FAIL:
|
||||
case WHD_WLAN_NOMEM:
|
||||
case WHD_MALLOC_FAILURE: return NSAPI_ERROR_NO_MEMORY;
|
||||
case WHD_ACCESS_POINT_NOT_FOUND:
|
||||
case WHD_NETWORK_NOT_FOUND: return NSAPI_ERROR_NO_SSID;
|
||||
case WHD_NOT_AUTHENTICATED:
|
||||
case WHD_INVALID_KEY:
|
||||
case WHD_NOT_KEYED: return NSAPI_ERROR_AUTH_FAILURE;
|
||||
case WHD_PENDING:
|
||||
case WHD_JOIN_IN_PROGRESS: return NSAPI_ERROR_IN_PROGRESS;
|
||||
case WHD_CONNECTION_LOST: return NSAPI_ERROR_CONNECTION_LOST;
|
||||
case WHD_TIMEOUT:
|
||||
case WHD_EAPOL_KEY_PACKET_M1_TIMEOUT:
|
||||
case WHD_EAPOL_KEY_PACKET_M3_TIMEOUT:
|
||||
case WHD_EAPOL_KEY_PACKET_G1_TIMEOUT: return NSAPI_ERROR_CONNECTION_TIMEOUT;
|
||||
case WHD_WLAN_BUSY: return NSAPI_ERROR_BUSY;
|
||||
case WHD_WLAN_NODEVICE: return NSAPI_ERROR_DEVICE_ERROR;
|
||||
default: return -res;
|
||||
}
|
||||
}
|
||||
|
||||
static nsapi_security_t whd_tosecurity(whd_security_t sec) {
|
||||
switch (sec) {
|
||||
case WHD_SECURITY_OPEN: return NSAPI_SECURITY_NONE;
|
||||
case WHD_SECURITY_WEP_PSK:
|
||||
case WHD_SECURITY_WEP_SHARED: return NSAPI_SECURITY_WEP;
|
||||
case WHD_SECURITY_WPA_TKIP_PSK:
|
||||
case WHD_SECURITY_WPA_TKIP_ENT: return NSAPI_SECURITY_WPA;
|
||||
case WHD_SECURITY_WPA2_MIXED_PSK: return NSAPI_SECURITY_WPA_WPA2;
|
||||
case WHD_SECURITY_WPA2_AES_PSK:
|
||||
case WHD_SECURITY_WPA2_AES_ENT:
|
||||
case WHD_SECURITY_WPA2_FBT_PSK:
|
||||
case WHD_SECURITY_WPA2_FBT_ENT: return NSAPI_SECURITY_WPA2;
|
||||
default:
|
||||
return NSAPI_SECURITY_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
whd_security_t whd_fromsecurity(nsapi_security_t sec) {
|
||||
switch (sec) {
|
||||
case NSAPI_SECURITY_NONE: return WHD_SECURITY_OPEN;
|
||||
case NSAPI_SECURITY_WEP: return WHD_SECURITY_WEP_PSK;
|
||||
case NSAPI_SECURITY_WPA: return WHD_SECURITY_WPA_MIXED_PSK;
|
||||
case NSAPI_SECURITY_WPA2: return WHD_SECURITY_WPA2_AES_PSK;
|
||||
case NSAPI_SECURITY_WPA_WPA2: return WHD_SECURITY_WPA2_MIXED_PSK;
|
||||
default: return WHD_SECURITY_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
MBED_WEAK WhdSTAInterface::OlmInterface &WhdSTAInterface::OlmInterface::get_default_instance()
|
||||
{
|
||||
static OlmInterface olm;
|
||||
return olm;
|
||||
}
|
||||
|
||||
WhdSTAInterface::WhdSTAInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, OlmInterface &olm)
|
||||
: EMACInterface(emac, stack),
|
||||
_ssid("\0"),
|
||||
_pass("\0"),
|
||||
_security(NSAPI_SECURITY_NONE),
|
||||
_whd_emac(emac),
|
||||
_olm(&olm)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t WhdSTAInterface::connect(
|
||||
const char *ssid, const char *pass,
|
||||
nsapi_security_t security,
|
||||
uint8_t channel)
|
||||
{
|
||||
int err = set_channel(channel);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = set_credentials(ssid, pass, security);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return connect();
|
||||
}
|
||||
|
||||
nsapi_error_t WhdSTAInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
|
||||
{
|
||||
if ((ssid == NULL) ||
|
||||
(strlen(ssid) == 0) ||
|
||||
(pass == NULL && (security != NSAPI_SECURITY_NONE)) ||
|
||||
(strlen(pass) == 0 && ( security != NSAPI_SECURITY_NONE)) ||
|
||||
(strlen(pass) > 63 && (security == NSAPI_SECURITY_WPA2 || security == NSAPI_SECURITY_WPA || security == NSAPI_SECURITY_WPA_WPA2))
|
||||
)
|
||||
{
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
memset(_ssid, 0, sizeof(_ssid));
|
||||
strncpy(_ssid, ssid, sizeof(_ssid));
|
||||
|
||||
memset(_pass, 0, sizeof(_pass));
|
||||
strncpy(_pass, pass, sizeof(_pass));
|
||||
|
||||
_security = security;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t WhdSTAInterface::connect()
|
||||
{
|
||||
|
||||
#define MAX_RETRY_COUNT ( 5 )
|
||||
int i;
|
||||
|
||||
// initialize wiced, this is noop if already init
|
||||
if (!_whd_emac.powered_up)
|
||||
_whd_emac.power_up();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Initialize the Offload Manager
|
||||
if(_olm != NULL) {
|
||||
_olm->init_ols(_whd_emac.ifp, this);
|
||||
}
|
||||
|
||||
if ((_ssid == NULL) ||
|
||||
(strlen(_ssid) == 0)) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
// setup ssid
|
||||
whd_ssid_t ssid;
|
||||
strncpy((char*)ssid.value, _ssid, SSID_NAME_SIZE);
|
||||
ssid.value[SSID_NAME_SIZE-1] = '\0';
|
||||
ssid.length = strlen((char*)ssid.value);
|
||||
|
||||
// choose network security
|
||||
whd_security_t security = whd_fromsecurity(_security);
|
||||
|
||||
// join the network
|
||||
whd_result_t res;
|
||||
for ( i = 0; i < MAX_RETRY_COUNT; i++ )
|
||||
{
|
||||
res = (whd_result_t)whd_wifi_join(_whd_emac.ifp,
|
||||
&ssid,
|
||||
security,
|
||||
(const uint8_t *)_pass, strlen(_pass));
|
||||
if (res == WHD_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != WHD_SUCCESS) {
|
||||
return whd_toerror(res);
|
||||
}
|
||||
|
||||
if(whd_wifi_is_ready_to_transceive(_whd_emac.ifp) == WHD_SUCCESS)
|
||||
{
|
||||
whd_emac_wifi_link_state_changed(true, _whd_emac.ifp);
|
||||
}
|
||||
|
||||
// bring up
|
||||
return _interface->bringup(_dhcp,
|
||||
_ip_address[0] ? _ip_address : 0,
|
||||
_netmask[0] ? _netmask : 0,
|
||||
_gateway[0] ? _gateway : 0,
|
||||
DEFAULT_STACK);
|
||||
}
|
||||
|
||||
void WhdSTAInterface::wifi_on()
|
||||
{
|
||||
if (!_whd_emac.powered_up)
|
||||
_whd_emac.power_up();
|
||||
}
|
||||
|
||||
nsapi_error_t WhdSTAInterface::disconnect()
|
||||
{
|
||||
if (!_interface) {
|
||||
return NSAPI_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
// bring down
|
||||
int err = _interface->bringdown();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// leave network
|
||||
whd_result_t res = whd_wifi_leave(_whd_emac.ifp);
|
||||
if (res != WHD_SUCCESS) {
|
||||
return whd_toerror(res);
|
||||
}
|
||||
|
||||
// de-init Offload Manager
|
||||
if(_olm != NULL) {
|
||||
_olm->deinit_ols();
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
int8_t WhdSTAInterface::get_rssi()
|
||||
{
|
||||
int32_t rssi;
|
||||
whd_result_t res;
|
||||
|
||||
// initialize wiced, this is noop if already init
|
||||
if (!_whd_emac.powered_up)
|
||||
_whd_emac.power_up();
|
||||
|
||||
res = (whd_result_t)whd_wifi_get_rssi(_whd_emac.ifp, &rssi);
|
||||
if (res != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int8_t)rssi;
|
||||
}
|
||||
|
||||
static void whd_scan_handler(whd_scan_result_t** result_ptr,
|
||||
void* user_data, whd_scan_status_t status)
|
||||
{
|
||||
|
||||
whd_scan_userdata *data = (whd_scan_userdata*)user_data;
|
||||
|
||||
/* Even after stopping scan, some results will still come as results are already present in the queue */
|
||||
if (data->scan_in_progress == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// finished scan, either succesfully or through an abort
|
||||
if (status != WHD_SCAN_INCOMPLETE) {
|
||||
data->scan_in_progress = false;
|
||||
data->sema->release();
|
||||
return;
|
||||
}
|
||||
|
||||
// can't really keep anymore scan results
|
||||
if (data->count > 0 && data->offset >= data->count) {
|
||||
/* We can not abort the scan as this function is getting executed in WHD context,
|
||||
Note that to call any WHD API, caller function should not in WHD context */
|
||||
return;
|
||||
}
|
||||
|
||||
whd_scan_result_t* record = *result_ptr;
|
||||
|
||||
for (unsigned int i=0; i<data->result_buff->size(); i++) {
|
||||
if (CMP_MAC( (*data->result_buff)[i].BSSID.octet, record->BSSID.octet ))
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->count > 0) {
|
||||
// get ap stats
|
||||
nsapi_wifi_ap ap;
|
||||
|
||||
uint8_t length = record->SSID.length;
|
||||
if (length < sizeof(ap.ssid)-1) {
|
||||
length = sizeof(ap.ssid)-1;
|
||||
}
|
||||
memcpy(ap.ssid, record->SSID.value, length);
|
||||
ap.ssid[length] = '\0';
|
||||
|
||||
memcpy(ap.bssid, record->BSSID.octet, sizeof(ap.bssid));
|
||||
|
||||
ap.security = whd_tosecurity(record->security);
|
||||
ap.rssi = record->signal_strength;
|
||||
ap.channel = record->channel;
|
||||
data->aps[data->offset] = WiFiAccessPoint(ap);
|
||||
}
|
||||
|
||||
// store to result_buff for future duplication removal
|
||||
data->result_buff->push_back(*record);
|
||||
data->offset = data->result_buff->size();
|
||||
|
||||
}
|
||||
|
||||
|
||||
int WhdSTAInterface::scan(WiFiAccessPoint *aps, unsigned count)
|
||||
{
|
||||
// initialize wiced, this is noop if already init
|
||||
if (!_whd_emac.powered_up)
|
||||
_whd_emac.power_up();
|
||||
|
||||
interal_scan_data.sema = new Semaphore();
|
||||
interal_scan_data.aps = aps;
|
||||
interal_scan_data.count = count;
|
||||
interal_scan_data.offset = 0;
|
||||
interal_scan_data.ifp = _whd_emac.ifp;
|
||||
interal_scan_data.scan_in_progress = true;
|
||||
interal_scan_data.result_buff = new vector<whd_scan_result_t>();
|
||||
whd_result_t whd_res;
|
||||
int res;
|
||||
|
||||
|
||||
whd_res = (whd_result_t)whd_wifi_scan(_whd_emac.ifp, WHD_SCAN_TYPE_ACTIVE, WHD_BSS_TYPE_ANY,
|
||||
NULL, NULL, NULL, NULL, whd_scan_handler, (whd_scan_result_t **) &result_ptr, &interal_scan_data );
|
||||
if (whd_res != WHD_SUCCESS) {
|
||||
res = whd_toerror(whd_res);
|
||||
} else {
|
||||
int tok = interal_scan_data.sema->wait();
|
||||
if (tok < 1) {
|
||||
res = NSAPI_ERROR_WOULD_BLOCK;
|
||||
} else {
|
||||
res = interal_scan_data.offset;
|
||||
}
|
||||
}
|
||||
|
||||
delete interal_scan_data.sema;
|
||||
delete interal_scan_data.result_buff;
|
||||
return res;
|
||||
}
|
||||
|
||||
int WhdSTAInterface::is_interface_connected(void )
|
||||
{
|
||||
_whd_emac.ifp->role = WHD_STA_ROLE;
|
||||
if ( ( whd_wifi_is_ready_to_transceive( _whd_emac.ifp ) == WHD_SUCCESS ) )
|
||||
{
|
||||
return WHD_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WHD_CONNECTION_LOST;
|
||||
}
|
||||
}
|
||||
|
||||
int WhdSTAInterface::get_bssid(uint8_t *bssid)
|
||||
{
|
||||
whd_mac_t ap_mac;
|
||||
whd_result_t res = WHD_SUCCESS;
|
||||
|
||||
memset(&ap_mac, 0, sizeof(ap_mac));
|
||||
_whd_emac.ifp->role = WHD_STA_ROLE;
|
||||
if ( ( whd_wifi_is_ready_to_transceive( _whd_emac.ifp ) == WHD_SUCCESS ) )
|
||||
{
|
||||
res = whd_wifi_get_bssid(_whd_emac.ifp, &ap_mac);
|
||||
|
||||
if ( res == WHD_SUCCESS )
|
||||
{
|
||||
memcpy(bssid, ap_mac.octet, sizeof(ap_mac.octet));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WhdSTAInterface::whd_log_print ( void )
|
||||
{
|
||||
return whd_wifi_print_whd_log( _whd_emac.drvp );
|
||||
}
|
||||
|
||||
int WhdSTAInterface::whd_log_read ( char *buffer, int buffer_size )
|
||||
{
|
||||
whd_result_t res = WHD_SUCCESS;
|
||||
if ( buffer != NULL )
|
||||
{
|
||||
res = whd_wifi_read_wlan_log( _whd_emac.drvp, buffer, buffer_size);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
nsapi_error_t WhdSTAInterface::wifi_get_ac_params_sta(void *acp )
|
||||
{
|
||||
whd_result_t res = WHD_SUCCESS;
|
||||
edcf_acparam_t *ac_param = ( edcf_acparam_t * )acp;
|
||||
|
||||
res = whd_wifi_get_acparams(_whd_emac.ifp, ac_param );
|
||||
if ( res != WHD_SUCCESS )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WhdSTAInterface::wifi_set_iovar_value ( const char *iovar, uint32_t value )
|
||||
{
|
||||
whd_result_t res = WHD_SUCCESS;
|
||||
_whd_emac.ifp->role = WHD_STA_ROLE;
|
||||
res = whd_wifi_set_iovar_value (_whd_emac.ifp, iovar, value );
|
||||
return res;
|
||||
}
|
||||
|
||||
int WhdSTAInterface::wifi_get_iovar_value ( const char *iovar, uint32_t *value )
|
||||
{
|
||||
int res = WHD_SUCCESS;
|
||||
_whd_emac.ifp->role = WHD_STA_ROLE;
|
||||
res = whd_wifi_get_iovar_value ( _whd_emac.ifp, iovar, value );
|
||||
return res;
|
||||
}
|
||||
int WhdSTAInterface::wifi_set_ioctl_value( uint32_t ioctl, uint32_t value )
|
||||
{
|
||||
int res = WHD_SUCCESS;
|
||||
_whd_emac.ifp->role = WHD_STA_ROLE;
|
||||
res = whd_wifi_set_ioctl_value(_whd_emac.ifp, ioctl, value );
|
||||
return res;
|
||||
}
|
||||
|
||||
int WhdSTAInterface::wifi_set_up ( void )
|
||||
{
|
||||
int res = WHD_SUCCESS;
|
||||
res = whd_wifi_set_up(_whd_emac.ifp);
|
||||
return res;
|
||||
}
|
||||
|
||||
int WhdSTAInterface::wifi_set_down ( void )
|
||||
{
|
||||
int res = WHD_SUCCESS;
|
||||
res = whd_wifi_set_down(_whd_emac.ifp);
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
/* WHD implementation of NetworkInterfaceAPI
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef WHD_STA_INTERFACE_H
|
||||
#define WHD_STA_INTERFACE_H
|
||||
|
||||
#include "mbed.h"
|
||||
#include "EthernetInterface.h"
|
||||
#include "netsocket/OnboardNetworkStack.h"
|
||||
#include "whd_emac.h"
|
||||
#include "whd_types_int.h"
|
||||
|
||||
struct ol_desc;
|
||||
|
||||
/** WhdSTAInterface class
|
||||
* Implementation of the NetworkStack for the WHD
|
||||
*/
|
||||
class WhdSTAInterface : public WiFiInterface, public EMACInterface
|
||||
{
|
||||
public:
|
||||
|
||||
class OlmInterface
|
||||
{
|
||||
public:
|
||||
/** Get the default OLM interface. */
|
||||
static OlmInterface &get_default_instance();
|
||||
|
||||
OlmInterface(struct ol_desc *list = NULL) {}
|
||||
|
||||
virtual int init_ols(void *whd, void *ip) { return 0; }
|
||||
virtual int sleep() { return 0; }
|
||||
virtual int wake() { return 0; }
|
||||
|
||||
virtual void deinit_ols(void) {}
|
||||
};
|
||||
|
||||
WhdSTAInterface(
|
||||
WHD_EMAC &emac = WHD_EMAC::get_instance(),
|
||||
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance(),
|
||||
OlmInterface &olm = OlmInterface::get_default_instance());
|
||||
|
||||
static WhdSTAInterface *get_default_instance();
|
||||
|
||||
/* Turn on the wifi device*/
|
||||
void wifi_on();
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to connect to a WiFi network. Requires ssid and passphrase to be set.
|
||||
* If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned.
|
||||
*
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
nsapi_error_t connect();
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to connect to a WiFi network.
|
||||
*
|
||||
* @param ssid Name of the network to connect to
|
||||
* @param pass Security passphrase to connect to the network
|
||||
* @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE)
|
||||
* @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED
|
||||
* @return 0 on success, or error code on failure
|
||||
*/
|
||||
nsapi_error_t connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0);
|
||||
|
||||
/** Stop the interface
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
nsapi_error_t disconnect();
|
||||
|
||||
/** Set the WiFi network credentials
|
||||
*
|
||||
* @param ssid Name of the network to connect to
|
||||
* @param pass Security passphrase to connect to the network
|
||||
* @param security Type of encryption for connection
|
||||
* (defaults to NSAPI_SECURITY_NONE)
|
||||
* @return 0 on success, or error code on failure
|
||||
*/
|
||||
nsapi_error_t set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE);
|
||||
|
||||
/** Set the WiFi network channel - NOT SUPPORTED
|
||||
*
|
||||
* This function is not supported and will return NSAPI_ERROR_UNSUPPORTED
|
||||
*
|
||||
* @param channel Channel on which the connection is to be made, or 0 for any (Default: 0)
|
||||
* @return Not supported, returns NSAPI_ERROR_UNSUPPORTED
|
||||
*/
|
||||
nsapi_error_t set_channel(uint8_t channel) {
|
||||
if (channel != 0) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Gets the current radio signal strength for active connection
|
||||
*
|
||||
* @return Connection strength in dBm (negative value)
|
||||
*/
|
||||
int8_t get_rssi();
|
||||
|
||||
/** Scan for available networks
|
||||
*
|
||||
* This function will block.
|
||||
*
|
||||
* @param ap Pointer to allocated array to store discovered AP
|
||||
* @param count Size of allocated @a res array, or 0 to only count available AP
|
||||
* @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0)
|
||||
* @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int scan(WiFiAccessPoint *res, unsigned count);
|
||||
|
||||
/* is interface connected, if yes return WICED_SUCCESS else WICED_NOT_CONNECTED */
|
||||
int is_interface_connected();
|
||||
|
||||
/* get bssid of the AP if success return WICED_SUCCESS else WICED_ERROR */
|
||||
int get_bssid(uint8_t *bssid);
|
||||
|
||||
/* print WHD log (this routine will malloc/free a buffer
|
||||
* You need to enable printing with WHD_LOGGING_BUFFER_ENABLE
|
||||
*/
|
||||
int whd_log_print ( void );
|
||||
|
||||
/* read WHD log */
|
||||
int whd_log_read ( char *buffer, int buffer_size );
|
||||
|
||||
/* Get EDCF AC params */
|
||||
nsapi_error_t wifi_get_ac_params_sta(void * ac_param );
|
||||
|
||||
/* get iovar value */
|
||||
int wifi_get_iovar_value ( const char *iovar, uint32_t *value );
|
||||
|
||||
/* set iovar value */
|
||||
int wifi_set_iovar_value ( const char *iovar, uint32_t value );
|
||||
|
||||
/* set ioctl value */
|
||||
int wifi_set_ioctl_value( uint32_t ioctl, uint32_t value ) ;
|
||||
|
||||
/* set wifi interface up */
|
||||
int wifi_set_up (void );
|
||||
|
||||
/* set wifi interface down */
|
||||
int wifi_set_down (void );
|
||||
|
||||
/** Set Offload Manager Information
|
||||
* NOTE: Only allowed while disconnected
|
||||
*
|
||||
* @param olm Offload Manager info structure
|
||||
* @return true if completed successfully
|
||||
* false if Interface is connected
|
||||
*/
|
||||
int set_olm(OlmInterface *olm) {
|
||||
if (get_connection_status() == NSAPI_STATUS_DISCONNECTED)
|
||||
{
|
||||
_olm = olm;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Network stack is suspended
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int net_suspended() {
|
||||
int ret = _olm->sleep();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Network stack is resuming
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int net_resuming() {
|
||||
int ret = _olm->wake();
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
|
||||
char _ssid[33]; /* The longest possible name (defined in 802.11) +1 for the \0 */
|
||||
char _pass[64]; /* The longest allowed passphrase + 1 */
|
||||
nsapi_security_t _security;
|
||||
WHD_EMAC& _whd_emac;
|
||||
OlmInterface *_olm;
|
||||
};
|
||||
|
||||
extern int wiced_leave_ap ( int interface );
|
||||
#endif
|
|
@ -0,0 +1,138 @@
|
|||
/* Wiced implementation of NetworkInterfaceAPI
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/* WHD SoftAP implementation of SoftAPInterface
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef WHD_SOFTAP_INTERFACE_H
|
||||
#define WHD_SOFTAP_INTERFACE_H
|
||||
|
||||
#include "mbed.h"
|
||||
#include "EthernetInterface.h"
|
||||
#include "netsocket/OnboardNetworkStack.h"
|
||||
#include "whd_emac.h"
|
||||
|
||||
|
||||
/**
|
||||
* Vendor IE details
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t oui[WIFI_IE_OUI_LENGTH]; /**< Unique identifier for the IE */
|
||||
uint8_t subtype; /**< Sub-type of the IE */
|
||||
void* data; /**< Pointer to IE data */
|
||||
uint16_t length; /**< IE data length */
|
||||
uint16_t which_packets; /**< Mask of the packet in which this IE details to be included */
|
||||
} whd_custom_ie_info_t;
|
||||
|
||||
|
||||
|
||||
/** WhdSoftAPInterface class
|
||||
* Implementation of the SoftAPInterface for the Whd
|
||||
*/
|
||||
class WhdSoftAPInterface : public EMACInterface
|
||||
{
|
||||
public:
|
||||
/** Construct SoftAP interface
|
||||
* @return pointer to default WhdSoftAPInterface instance
|
||||
*/
|
||||
WhdSoftAPInterface(WHD_EMAC &emac = WHD_EMAC::get_instance(WHD_AP_ROLE),
|
||||
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance());
|
||||
|
||||
/** Get the default WhdSoftAPInterface instance.
|
||||
* @return pointer to default WhdSoftAPInterface instance
|
||||
*/
|
||||
static WhdSoftAPInterface *get_default_instance();
|
||||
|
||||
/** Set static IP address for SoftAP
|
||||
*
|
||||
* Configures the static IP address of SoftAP
|
||||
* Requires that the network is stopped.
|
||||
*
|
||||
* @param ip_address Null-terminated representation of the local IP address
|
||||
* @param netmask Null-terminated representation of the local network mask
|
||||
* @param gateway Null-terminated representation of the local gateway
|
||||
* @return 0 on success, negative error code on failure
|
||||
* int set_network(const char *ip_address, const char *netmask, const char *gateway);
|
||||
*/
|
||||
|
||||
/** Start a SoftAP
|
||||
*
|
||||
* @param ssid Name of the SoftAP to create
|
||||
* @param pass Security passphrase for connection to SoftAP
|
||||
* @param security Type of encryption for connection
|
||||
* @param channel Channel for SoftAP
|
||||
* @param start_dhcp_server start dhcp server for connection
|
||||
* @param[in] Optional Custom IE
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int start(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel,
|
||||
bool start_dhcp_server = true, const whd_custom_ie_info_t* ie_info = NULL);
|
||||
|
||||
/**
|
||||
* Remove Wi-Fi custom IE
|
||||
*
|
||||
* @param[in] ie_info : Pointer to the structure which contains custom IE information
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int remove_custom_ie(const whd_custom_ie_info_t* ie_info);
|
||||
|
||||
/** Stop the Software Access Point
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int stop(void);
|
||||
|
||||
/**
|
||||
* Gets information about associated clients.
|
||||
*
|
||||
* @note Only applicable if softAP interface is up
|
||||
*
|
||||
* @param[out] client_list_buffer : pointer to a buffer that will be populated with a variable length structure defined by @ref whd_maclist_t
|
||||
* @param[in] buffer_length : length of the buffer
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int get_associated_client_list(void* client_list_buffer, uint16_t buffer_length);
|
||||
|
||||
|
||||
/**
|
||||
* Register soft AP event handler
|
||||
*
|
||||
* @param[in] softap_event_handler : A function pointer to the event handler
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int register_event_handler(whd_event_handler_t softap_event_handler);
|
||||
|
||||
/**
|
||||
* Unregister soft AP event handler
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
* see @a nsapi_error
|
||||
*/
|
||||
int unregister_event_handler(void);
|
||||
|
||||
|
||||
protected:
|
||||
WHD_EMAC& _whd_emac;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* 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 "WhdSTAInterface.h"
|
||||
#include "WhdSoftAPInterface.h"
|
||||
|
||||
WiFiInterface *WiFiInterface::get_target_default_instance()
|
||||
{
|
||||
static WhdSTAInterface wifi;
|
||||
return &wifi;
|
||||
}
|
||||
|
||||
WhdSoftAPInterface *WhdSoftAPInterface::get_default_instance()
|
||||
{
|
||||
static WhdSoftAPInterface softap;
|
||||
return &softap;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2019 Cypress Semiconductor Corporation
|
||||
* 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.
|
||||
*/
|
||||
#ifndef INCLUDED_EMAC_EAPOL_H_
|
||||
#define INCLUDED_EMAC_EAPOL_H_
|
||||
|
||||
#include "whd.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
#define EAPOL_PACKET_TYPE (0x888E)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
typedef whd_buffer_t whd_eapol_packet_t;
|
||||
|
||||
typedef void (*eapol_packet_handler_t) (whd_interface_t interface, whd_buffer_t buffer);
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
whd_result_t emac_register_eapol_packet_handler ( eapol_packet_handler_t eapol_packet_handler );
|
||||
void emac_unregister_eapol_packet_handler( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* ifndef INCLUDED_EMAC_EAPOL_H_ */
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* 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 <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cmsis_os.h"
|
||||
#include "whd_emac.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "mbed_shared_queues.h"
|
||||
#include "whd_wlioctl.h"
|
||||
#include "whd_buffer_api.h"
|
||||
#include "cybsp_api_wifi.h"
|
||||
#include "emac_eapol.h"
|
||||
#include "cy_result.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
eapol_packet_handler_t emac_eapol_packet_handler = NULL;
|
||||
} // extern "C"
|
||||
|
||||
WHD_EMAC::WHD_EMAC(whd_interface_role_t role)
|
||||
: interface_type(role)
|
||||
{
|
||||
}
|
||||
|
||||
WHD_EMAC::WHD_EMAC()
|
||||
: interface_type(WHD_STA_ROLE)
|
||||
{
|
||||
}
|
||||
|
||||
WHD_EMAC &WHD_EMAC::get_instance() {
|
||||
return get_instance(WHD_STA_ROLE);
|
||||
}
|
||||
|
||||
WHD_EMAC &WHD_EMAC::get_instance(whd_interface_role_t role) {
|
||||
static WHD_EMAC emac_sta(WHD_STA_ROLE);
|
||||
static WHD_EMAC emac_ap(WHD_AP_ROLE);
|
||||
return role == WHD_AP_ROLE ? emac_ap : emac_sta;
|
||||
}
|
||||
|
||||
uint32_t WHD_EMAC::get_mtu_size() const
|
||||
{
|
||||
return WHD_PAYLOAD_MTU;
|
||||
}
|
||||
|
||||
uint32_t WHD_EMAC::get_align_preference() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WHD_EMAC::add_multicast_group(const uint8_t *addr)
|
||||
{
|
||||
memcpy(multicast_addr.octet, addr, sizeof(multicast_addr.octet));
|
||||
whd_wifi_register_multicast_address(ifp, &multicast_addr);
|
||||
}
|
||||
|
||||
void WHD_EMAC::remove_multicast_group(const uint8_t *addr)
|
||||
{
|
||||
whd_wifi_unregister_multicast_address(ifp, &multicast_addr);
|
||||
}
|
||||
|
||||
void WHD_EMAC::set_all_multicast(bool all)
|
||||
{
|
||||
/* No-op at this stage */
|
||||
}
|
||||
|
||||
void WHD_EMAC::power_down()
|
||||
{
|
||||
if(powered_up)
|
||||
{
|
||||
powered_up = false;
|
||||
whd_wifi_off(ifp);
|
||||
whd_deinit(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
bool WHD_EMAC::power_up()
|
||||
{
|
||||
if(!powered_up)
|
||||
{
|
||||
if(CY_RSLT_SUCCESS != cybsp_wifi_init()){
|
||||
return false;
|
||||
}
|
||||
drvp = *(cybsp_get_wifi_driver());
|
||||
if(WHD_SUCCESS != whd_wifi_on(drvp, &ifp /* OUT */)){
|
||||
return false;
|
||||
}
|
||||
powered_up = true;
|
||||
if (link_state && emac_link_state_cb ) {
|
||||
emac_link_state_cb(link_state);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WHD_EMAC::get_hwaddr(uint8_t *addr) const
|
||||
{
|
||||
whd_mac_t mac;
|
||||
whd_result_t res = whd_wifi_get_mac_address(ifp, &mac);
|
||||
MBED_ASSERT(res == WHD_SUCCESS);
|
||||
memcpy(addr, mac.octet, sizeof(mac.octet));
|
||||
return true;
|
||||
}
|
||||
|
||||
void WHD_EMAC::set_hwaddr(const uint8_t *addr)
|
||||
{
|
||||
/* No-op at this stage */
|
||||
}
|
||||
|
||||
uint8_t WHD_EMAC::get_hwaddr_size() const
|
||||
{
|
||||
whd_mac_t mac;
|
||||
return sizeof(mac.octet);
|
||||
}
|
||||
|
||||
void WHD_EMAC::set_link_input_cb(emac_link_input_cb_t input_cb)
|
||||
{
|
||||
emac_link_input_cb = input_cb;
|
||||
}
|
||||
|
||||
void WHD_EMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb)
|
||||
{
|
||||
emac_link_state_cb = state_cb;
|
||||
}
|
||||
|
||||
void WHD_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr)
|
||||
{
|
||||
memory_manager = &mem_mngr;
|
||||
}
|
||||
|
||||
bool WHD_EMAC::link_out(emac_mem_buf_t *buf)
|
||||
{
|
||||
uint16_t offset = 64;
|
||||
whd_buffer_t buffer;
|
||||
|
||||
uint16_t size = memory_manager->get_total_len(buf);
|
||||
|
||||
whd_result_t res = whd_host_buffer_get(drvp, &buffer, WHD_NETWORK_TX, size+offset, WHD_TRUE);
|
||||
if ( res != WHD_SUCCESS)
|
||||
{
|
||||
memory_manager->free(buf);
|
||||
return true;
|
||||
}
|
||||
MBED_ASSERT(res == WHD_SUCCESS);
|
||||
|
||||
whd_buffer_add_remove_at_front(drvp, &buffer, offset);
|
||||
|
||||
void *dest = whd_buffer_get_current_piece_data_pointer(drvp, buffer);
|
||||
memory_manager->copy_from_buf(dest, size, buf);
|
||||
|
||||
if (activity_cb) {
|
||||
activity_cb(true);
|
||||
}
|
||||
whd_network_send_ethernet_data(ifp, buffer);
|
||||
memory_manager->free(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WHD_EMAC::get_ifname(char *name, uint8_t size) const
|
||||
{
|
||||
memcpy(name, "whd", size);
|
||||
}
|
||||
|
||||
void WHD_EMAC::set_activity_cb(mbed::Callback<void(bool)> cb)
|
||||
{
|
||||
activity_cb = cb;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static void emac_receive_eapol_packet(whd_interface_t interface, whd_buffer_t buffer)
|
||||
{
|
||||
if ( buffer != NULL )
|
||||
{
|
||||
if ( emac_eapol_packet_handler != NULL )
|
||||
{
|
||||
|
||||
emac_eapol_packet_handler( interface, buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
whd_buffer_release( interface->whd_driver,buffer, WHD_NETWORK_RX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
whd_result_t emac_register_eapol_packet_handler( eapol_packet_handler_t eapol_packet_handler )
|
||||
{
|
||||
|
||||
if ( emac_eapol_packet_handler == NULL )
|
||||
{
|
||||
emac_eapol_packet_handler = eapol_packet_handler;
|
||||
return WHD_SUCCESS;
|
||||
}
|
||||
|
||||
return WHD_HANDLER_ALREADY_REGISTERED;
|
||||
}
|
||||
|
||||
void emac_unregister_eapol_packet_handler( void )
|
||||
{
|
||||
emac_eapol_packet_handler = NULL;
|
||||
}
|
||||
|
||||
void cy_network_process_ethernet_data(whd_interface_t ifp, whd_buffer_t buffer)
|
||||
{
|
||||
emac_mem_buf_t *mem_buf = NULL;
|
||||
|
||||
WHD_EMAC &emac = WHD_EMAC::get_instance(ifp->role);
|
||||
|
||||
if (!emac.powered_up && !emac.emac_link_input_cb) {
|
||||
// ignore any trailing packets
|
||||
whd_buffer_release(emac.drvp, buffer, WHD_NETWORK_RX);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *data = whd_buffer_get_current_piece_data_pointer(emac.drvp, buffer);
|
||||
|
||||
uint16_t size = whd_buffer_get_current_piece_size(emac.drvp, buffer);
|
||||
|
||||
|
||||
if (size > WHD_ETHERNET_SIZE ) {
|
||||
|
||||
uint16_t ethertype;
|
||||
|
||||
ethertype = (uint16_t) (data[12] << 8 | data[13]);
|
||||
|
||||
if (ethertype == EAPOL_PACKET_TYPE) {
|
||||
|
||||
/* pass it to the EAP layer, but do not release the packet */
|
||||
emac_receive_eapol_packet(ifp,buffer);
|
||||
|
||||
} else {
|
||||
mem_buf = buffer;
|
||||
if (emac.activity_cb) {
|
||||
emac.activity_cb(false);
|
||||
}
|
||||
emac.emac_link_input_cb(mem_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void whd_emac_wifi_link_state_changed(bool state_up, whd_interface_t ifp)
|
||||
{
|
||||
WHD_EMAC &emac = WHD_EMAC::get_instance(ifp->role);
|
||||
|
||||
emac.link_state = state_up;
|
||||
if (emac.emac_link_state_cb ) {
|
||||
emac.emac_link_state_cb(state_up);
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef WHD_EMAC_H_
|
||||
#define WHD_EMAC_H_
|
||||
|
||||
#include "EMAC.h"
|
||||
#include "EMACInterface.h"
|
||||
#include "WiFiInterface.h"
|
||||
#include "whd_int.h"
|
||||
|
||||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Mutex.h"
|
||||
|
||||
class WHD_EMAC : public EMAC {
|
||||
public:
|
||||
WHD_EMAC();
|
||||
WHD_EMAC(whd_interface_role_t itype);
|
||||
|
||||
static WHD_EMAC &get_instance();
|
||||
|
||||
static WHD_EMAC &get_instance(whd_interface_role_t role);
|
||||
|
||||
/**
|
||||
* Return maximum transmission unit
|
||||
*
|
||||
* @return MTU in bytes
|
||||
*/
|
||||
virtual uint32_t get_mtu_size() const;
|
||||
|
||||
/**
|
||||
* Gets memory buffer alignment preference
|
||||
*
|
||||
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
|
||||
* align link out memory buffer chains using the alignment.
|
||||
*
|
||||
* @return Memory alignment requirement in bytes
|
||||
*/
|
||||
virtual uint32_t get_align_preference() const;
|
||||
|
||||
/**
|
||||
* Return interface name
|
||||
*
|
||||
* @param name Pointer to where the name should be written
|
||||
* @param size Maximum number of character to copy
|
||||
*/
|
||||
virtual void get_ifname(char *name, uint8_t size) const;
|
||||
|
||||
/**
|
||||
* Returns size of the underlying interface HW address size.
|
||||
*
|
||||
* @return HW address size in bytes
|
||||
*/
|
||||
virtual uint8_t get_hwaddr_size() const;
|
||||
|
||||
/**
|
||||
* Return interface-supplied HW address
|
||||
*
|
||||
* Copies HW address to provided memory, @param addr has to be of correct size see @a get_hwaddr_size
|
||||
*
|
||||
* HW address need not be provided if this interface does not have its own HW
|
||||
* address configuration; stack will choose address from central system
|
||||
* configuration if the function returns false and does not write to addr.
|
||||
*
|
||||
* @param addr HW address for underlying interface
|
||||
* @return true if HW address is available
|
||||
*/
|
||||
virtual bool get_hwaddr(uint8_t *addr) const;
|
||||
|
||||
/**
|
||||
* Set HW address for interface
|
||||
*
|
||||
* Provided address has to be of correct size, see @a get_hwaddr_size
|
||||
*
|
||||
* Called to set the MAC address to actually use - if @a get_hwaddr is provided
|
||||
* the stack would normally use that, but it could be overridden, eg for test
|
||||
* purposes.
|
||||
*
|
||||
* @param addr Address to be set
|
||||
*/
|
||||
virtual void set_hwaddr(const uint8_t *addr);
|
||||
|
||||
/**
|
||||
* Sends the packet over the link
|
||||
*
|
||||
* That can not be called from an interrupt context.
|
||||
*
|
||||
* @param buf Packet to be send
|
||||
* @return True if the packet was send successfully, False otherwise
|
||||
*/
|
||||
virtual bool link_out(emac_mem_buf_t *buf);
|
||||
|
||||
/**
|
||||
* Initializes the HW
|
||||
*
|
||||
* @return True on success, False in case of an error.
|
||||
*/
|
||||
virtual bool power_up();
|
||||
|
||||
/**
|
||||
* Deinitializes the HW
|
||||
*
|
||||
*/
|
||||
virtual void power_down();
|
||||
|
||||
/**
|
||||
* Sets a callback that needs to be called for packets received for that interface
|
||||
*
|
||||
* @param input_cb Function to be register as a callback
|
||||
*/
|
||||
virtual void set_link_input_cb(emac_link_input_cb_t input_cb);
|
||||
|
||||
/**
|
||||
* Sets a callback that needs to be called on link status changes for given interface
|
||||
*
|
||||
* @param state_cb Function to be register as a callback
|
||||
*/
|
||||
virtual void set_link_state_cb(emac_link_state_change_cb_t state_cb);
|
||||
|
||||
/** Add device to a multicast group
|
||||
*
|
||||
* @param address A multicast group hardware address
|
||||
*/
|
||||
virtual void add_multicast_group(const uint8_t *address);
|
||||
|
||||
/** Remove device from a multicast group
|
||||
*
|
||||
* @param address A multicast group hardware address
|
||||
*/
|
||||
virtual void remove_multicast_group(const uint8_t *address);
|
||||
|
||||
/** Request reception of all multicast packets
|
||||
*
|
||||
* @param all True to receive all multicasts
|
||||
* False to receive only multicasts addressed to specified groups
|
||||
*/
|
||||
virtual void set_all_multicast(bool all);
|
||||
|
||||
/** Sets memory manager that is used to handle memory buffers
|
||||
*
|
||||
* @param mem_mngr Pointer to memory manager
|
||||
*/
|
||||
virtual void set_memory_manager(EMACMemoryManager &mem_mngr);
|
||||
|
||||
/** Set callback to receive EMAC activity events
|
||||
*
|
||||
* @param activity_cb The callback for activity events
|
||||
*/
|
||||
virtual void set_activity_cb(mbed::Callback<void(bool is_tx_activity)> activity_cb);
|
||||
|
||||
emac_link_input_cb_t emac_link_input_cb = NULL; /**< Callback for incoming data */
|
||||
emac_link_state_change_cb_t emac_link_state_cb = NULL;
|
||||
EMACMemoryManager *memory_manager;
|
||||
bool powered_up = false;
|
||||
bool link_state = false;
|
||||
whd_interface_role_t interface_type;
|
||||
whd_driver_t drvp = NULL;
|
||||
whd_interface_t ifp = NULL;
|
||||
whd_mac_t multicast_addr;
|
||||
struct whd_resource_source *resource_ops = NULL;
|
||||
whd_buffer_funcs_t *buffer_ops = NULL;
|
||||
whd_netif_funcs_t *netif_ops = NULL;
|
||||
whd_init_config_t *whd_init_config = NULL;
|
||||
mbed::Callback<void(bool)> activity_cb;
|
||||
|
||||
};
|
||||
|
||||
#endif /* WHD_EMAC_H_ */
|
|
@ -0,0 +1,143 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef WICED_NETWORK_H
|
||||
#define WICED_NETWORK_H
|
||||
#include "w_dtls_types.h"
|
||||
#include "wiced_result.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
#define IP_HANDLE(interface) (wiced_ip_handle[(interface) & 3])
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define WICED_MAXIMUM_NUMBER_OF_SOCKETS_WITH_CALLBACKS (1)
|
||||
#define WICED_MAXIMUM_NUMBER_OF_SERVER_SOCKETS (1)
|
||||
|
||||
#define SIZE_OF_ARP_ENTRY sizeof(1)
|
||||
|
||||
#define IP_STACK_SIZE (2 * 1024)
|
||||
#define ARP_CACHE_SIZE (6 * SIZE_OF_ARP_ENTRY)
|
||||
#define DHCP_STACK_SIZE (1024)
|
||||
#define WICED_PKT_SIZE (1500)
|
||||
#define WICED_ANY_PORT (0)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WICED_SOCKET_ERROR
|
||||
} wiced_socket_state_t;
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t* payload;
|
||||
uint16_t len;
|
||||
uint16_t pktstart;
|
||||
} wiced_packet_t;
|
||||
|
||||
|
||||
//typedef NOOS_DUMMY wiced_tls_context_type_t;
|
||||
//typedef NOOS_DUMMY wiced_tls_context_t;
|
||||
//typedef NOOS_DUMMY wiced_tls_session_t;
|
||||
//typedef NOOS_DUMMY wiced_tls_certificate_t;
|
||||
//typedef NOOS_DUMMY wiced_tls_endpoint_type_t;
|
||||
typedef void* NOOS_TCP_SOCKET;
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
typedef struct wiced_tcp_socket_struct wiced_tcp_socket_t;
|
||||
typedef struct wiced_udp_socket_struct wiced_udp_socket_t;
|
||||
|
||||
typedef wiced_result_t (*wiced_tcp_socket_callback_t)( wiced_tcp_socket_t* socket, void* arg );
|
||||
typedef wiced_result_t (*wiced_udp_socket_callback_t)( wiced_udp_socket_t* socket, void* arg );
|
||||
|
||||
struct wiced_udp_socket_struct
|
||||
{
|
||||
wiced_dtls_context_t* dtls_context;
|
||||
struct
|
||||
{
|
||||
wiced_tcp_socket_callback_t disconnect;
|
||||
wiced_tcp_socket_callback_t receive;
|
||||
wiced_tcp_socket_callback_t connect;
|
||||
} callbacks;
|
||||
void* callback_arg;
|
||||
};
|
||||
|
||||
struct wiced_tcp_socket_struct
|
||||
{
|
||||
NOOS_TCP_SOCKET socket;
|
||||
wiced_tls_context_t* tls_context;
|
||||
wiced_bool_t context_malloced;
|
||||
struct
|
||||
{
|
||||
wiced_tcp_socket_callback_t disconnect;
|
||||
wiced_tcp_socket_callback_t receive;
|
||||
wiced_tcp_socket_callback_t connect;
|
||||
} callbacks;
|
||||
void* callback_arg;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wiced_tcp_socket_t socket[WICED_MAXIMUM_NUMBER_OF_SERVER_SOCKETS];
|
||||
int interface;
|
||||
uint16_t port;
|
||||
wiced_tls_identity_t* tls_identity;
|
||||
} wiced_tcp_server_t;
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
typedef struct
|
||||
{
|
||||
int dummy;
|
||||
}NOOS_IP;
|
||||
typedef struct
|
||||
{
|
||||
int dummy;
|
||||
}NOOS_PACKET_POOL;
|
||||
/*
|
||||
* Note: These objects are for internal use only!
|
||||
*/
|
||||
extern NOOS_IP wiced_ip_handle [3];
|
||||
extern NOOS_PACKET_POOL wiced_packet_pools [2]; /* 0=TX, 1=RX */
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
#endif
|
Loading…
Reference in New Issue