Skip to content
This repository has been archived by the owner on Sep 7, 2020. It is now read-only.

Commit

Permalink
bwl: Add NL DWPAL base implementation
Browse files Browse the repository at this point in the history
Open nl socket at dwpal init state for each interface.
proccess nl events after select.
Add stubs and structures for monitor hal.

Signed-off-by: alex kanter <[email protected]>
Signed-off-by: itay elenzweig <[email protected]>
  • Loading branch information
itayx authored and Alex Kanter committed Jan 12, 2020
1 parent b62089f commit f4a9df0
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 2 deletions.
6 changes: 6 additions & 0 deletions common/beerocks/bwl/dwpal/ap_wlan_hal_dwpal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,12 @@ bool ap_wlan_hal_dwpal::process_dwpal_event(char *buffer, int bufLen, const std:
return true;
}

bool ap_wlan_hal_dwpal::process_dwpal_nl_event(struct nl_msg *msg)
{
LOG(ERROR) << __func__ << "isn't implemented by this derived and shouldn't be called";
return false;
}

} // namespace dwpal

std::shared_ptr<ap_wlan_hal> ap_wlan_hal_create(std::string iface_name, hal_conf_t hal_conf,
Expand Down
1 change: 1 addition & 0 deletions common/beerocks/bwl/dwpal/ap_wlan_hal_dwpal.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ap_wlan_hal_dwpal : public base_wlan_hal_dwpal, public ap_wlan_hal {
// Protected methods:
protected:
virtual bool process_dwpal_event(char *buffer, int bufLen, const std::string &opcode) override;
virtual bool process_dwpal_nl_event(struct nl_msg *msg) override;

// Overload for AP events
bool event_queue_push(ap_wlan_hal::Event event, std::shared_ptr<void> data = {})
Expand Down
186 changes: 184 additions & 2 deletions common/beerocks/bwl/dwpal/base_wlan_hal_dwpal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ bool base_wlan_hal_dwpal::fsm_setup()
attached = true;
}

//Attach NL interface
if (!m_dwpal_nl_ctx) {
//Attach nl interface
if (dwpal_driver_nl_attach(&m_dwpal_nl_ctx) == DWPAL_FAILURE) {
LOG(ERROR) << "dwpal_driver_nl_attach returned ERROR for interface ="
<< m_radio_info.iface_name;
return (transition.change_destination(dwpal_fsm_state::Detach));
}

LOG(DEBUG) << "dwpal_driver_nl_attach() success for radio ="
<< m_radio_info.iface_name;
}

if (attached) {
if (get_type() != HALType::Station) {
transition.change_destination(dwpal_fsm_state::GetRadioInfo);
Expand Down Expand Up @@ -292,6 +305,25 @@ bool base_wlan_hal_dwpal::fsm_setup()
// Success
LOG(DEBUG)
<< "Open and attach an event interface to wpa_supplicant/hostapd - SUCCESS!";

// Get the nl event interface file descriptor
if (!m_dwpal_nl_ctx) {
LOG(DEBUG) << "new nl interface";
if (dwpal_driver_nl_fd_get(m_dwpal_nl_ctx, &m_fd_nl_events, &m_fd_nl_cmd_get)) {
LOG(ERROR)
<< "dwpal_driver_nl_fd_get() failed for: " << m_radio_info.iface_name;
return (transition.change_destination(dwpal_fsm_state::Detach));
}

LOG(DEBUG) << "dwpal_driver_nl_fd_get() success for radio ="
<< m_radio_info.iface_name << " nl_fd = " << m_fd_nl_events
<< " fdcmdget_nl = " << m_fd_nl_cmd_get;
} else {
LOG(ERROR) << "Can't get event fd since dwpal ctx is NULL!";
return (transition.change_destination(dwpal_fsm_state::Detach));
}

LOG(DEBUG) << "Open and attach an event interface to nl - SUCCESS!";
return true;
})

Expand Down Expand Up @@ -331,6 +363,17 @@ bool base_wlan_hal_dwpal::fsm_setup()

m_fd_ext_events = -1;

// detach nl socket from main vap
if (m_dwpal_nl_ctx) {
LOG(DEBUG) << "detaching nl interface";
if (dwpal_driver_nl_detach(&m_dwpal_nl_ctx) == DWPAL_FAILURE) {
LOG(ERROR) << "dwpal_driver_nl_detach() failed for radio ="
<< m_radio_info.iface_name;
}
m_fd_nl_events = -1;
m_fd_nl_cmd_get = -1;
}

return success;
})

Expand Down Expand Up @@ -509,8 +552,147 @@ bool base_wlan_hal_dwpal::attach_ctrl_interface(int vap_id)

bool base_wlan_hal_dwpal::process_nl_events()
{
LOG(ERROR) << __func__ << "isn't implemented by derived and shouldn't be called";
return false;
if (!m_dwpal_nl_ctx) {
LOG(ERROR) << "Invalid Netlink socket used for nl events (m_dwpal_nl_ctx == nullptr)";
return false;
}

// check if there is nothing to proccess
if (m_fd_nl_events <= 0) {
LOG(ERROR) << __func__ << "nothing to proccess fd= " << m_fd_nl_events;
return false;
}

// Passing a lambda with capture is not supported for standard C function
// pointers. As a workaround, we create a static (but thread local) wrapper
// function that calls the capturing lambda function.
static __thread std::function<DWPAL_Ret(struct nl_msg * msg)> nl_handler_cb_wrapper;
nl_handler_cb_wrapper = [&](struct nl_msg *msg) -> DWPAL_Ret {
if (!process_dwpal_nl_event(msg)) {
LOG(ERROR) << "User's netlink handler function failed!";
return DWPAL_FAILURE;
}
return DWPAL_SUCCESS;
};
auto nl_handler_cb = [](struct nl_msg *msg) -> DWPAL_Ret { return nl_handler_cb_wrapper(msg); };

//parsing will be done in callback function
if (dwpal_driver_nl_msg_get(m_dwpal_nl_ctx, DWPAL_NL_UNSOLICITED_EVENT, NULL, nl_handler_cb) ==
DWPAL_FAILURE) {
LOG(ERROR) << " dwpal_driver_nl_msg_get failed,"
<< " ctx=" << m_dwpal_nl_ctx;
return false;
}

return true;
}

bool base_wlan_hal_dwpal::dwpal_nl_cmd_set(const std::string &ifname, unsigned int nl_cmd,
unsigned char *vendor_data, size_t vendor_data_size)
{
if (vendor_data == nullptr) {
LOG(ERROR) << __func__ << "vendor_data is NULL ==> Abort!";
return false;
}

if (dwpal_driver_nl_cmd_send(m_dwpal_nl_ctx, DWPAL_NL_UNSOLICITED_EVENT, (char *)ifname.c_str(),
NL80211_CMD_VENDOR, DWPAL_NETDEV_ID,
(enum ltq_nl80211_vendor_subcmds)nl_cmd, vendor_data,
vendor_data_size) != DWPAL_SUCCESS) {
LOG(ERROR) << __func__ << "ERROR for cmd = " << nl_cmd;
return false;
}

return true;
}

size_t base_wlan_hal_dwpal::dwpal_nl_cmd_get(const std::string &ifname, unsigned int nl_cmd,
unsigned char *out_buffer,
const size_t max_buffer_size)
{

size_t data_size = 0;

if (out_buffer == nullptr) {
LOG(ERROR) << __FUNCTION__ << "out_buffer is invalid ==> Abort!";
return data_size;
}

/* Handle a command which invokes an event with the output data */
if (dwpal_driver_nl_cmd_send(
m_dwpal_nl_ctx, DWPAL_NL_SOLICITED_EVENT, (char *)ifname.c_str(), NL80211_CMD_VENDOR,
DWPAL_NETDEV_ID, (enum ltq_nl80211_vendor_subcmds)nl_cmd, NULL, 0) == DWPAL_FAILURE) {
LOG(ERROR) << __FUNCTION__ << "ERROR for cmd = " << nl_cmd;
return data_size;
}

// Passing a lambda with capture is not supported for standard C function
// pointers. As a workaround, we create a static (but thread local) wrapper
// function that calls the capturing lambda function.
static __thread std::function<DWPAL_Ret(char *ifname, int event, int subevent, size_t len,
unsigned char *data)>
nl_handler_cb_wrapper;
nl_handler_cb_wrapper = [&](char *ifname, int event, int subevent, size_t len,
unsigned char *data) -> DWPAL_Ret {
if (!len || !data) {
LOG(ERROR) << "len=0 and/or data is NULL ==> Abort!";
return DWPAL_FAILURE;
}
if (event == NL80211_CMD_VENDOR) {
if (len >= max_buffer_size) {
LOG(ERROR) << "NL size exceeds out_buffer size ==> Abort!";
return DWPAL_FAILURE;
}

// copy result from nl data buffer to local buffer
std::copy_n(data, len, out_buffer);

// update data size
data_size = len;
} else {
LOG(ERROR) << "not handling non vendor event = " << event;
return DWPAL_FAILURE;
}
return DWPAL_SUCCESS;
};
auto nl_handler_cb = [](char *ifname, int event, int subevent, size_t len,
unsigned char *data) -> DWPAL_Ret {
return nl_handler_cb_wrapper(ifname, event, subevent, len, data);
};

//parsing will be done in callback func
if (dwpal_driver_nl_msg_get(m_dwpal_nl_ctx, DWPAL_NL_SOLICITED_EVENT, nl_handler_cb, NULL) ==
DWPAL_FAILURE) {
LOG(ERROR) << " dwpal_driver_nl_msg_get failed,"
<< " ctx=" << m_dwpal_nl_ctx;
return data_size;
}

return data_size;
}

bool base_wlan_hal_dwpal::dwpal_nl_cmd_scan_dump()
{
// Passing a lambda with capture is not supported for standard C function
// pointers. As a workaround, we create a static (but thread local) wrapper
// function that calls the capturing lambda function.
static __thread std::function<DWPAL_Ret(struct nl_msg * msg)> nl_handler_cb_wrapper;
nl_handler_cb_wrapper = [&](struct nl_msg *msg) -> DWPAL_Ret {
if (!process_dwpal_nl_event(msg)) {
LOG(ERROR) << "User's netlink handler function failed!";
return DWPAL_FAILURE;
}
return DWPAL_SUCCESS;
};
auto nl_handler_cb = [](struct nl_msg *msg) -> DWPAL_Ret { return nl_handler_cb_wrapper(msg); };

if (dwpal_driver_nl_scan_dump(m_dwpal_nl_ctx, (char *)m_radio_info.iface_name.c_str(),
nl_handler_cb) != DWPAL_SUCCESS) {
LOG(ERROR) << "dwpal_driver_nl_scan_dump Failed to request the nl scan dump";
return false;
}

return true;
}

bool base_wlan_hal_dwpal::refresh_radio_info()
Expand Down
28 changes: 28 additions & 0 deletions common/beerocks/bwl/dwpal/base_wlan_hal_dwpal.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class base_wlan_hal_dwpal : public virtual base_wlan_hal,

// Process dwpal event
virtual bool process_dwpal_event(char *buffer, int bufLen, const std::string &opcode) = 0;
virtual bool process_dwpal_nl_event(struct nl_msg *msg) = 0;

bool set(const std::string &param, const std::string &value,
int vap_id = beerocks::IFACE_RADIO_ID);
Expand All @@ -72,6 +73,30 @@ class base_wlan_hal_dwpal : public virtual base_wlan_hal,
bool dwpal_send_cmd(const std::string &cmd, int vap_id = beerocks::IFACE_RADIO_ID);
bool attach_ctrl_interface(int vap_id);

/**
* @brief handle get data cmd from netlink
* @param ifname radio interface name
* @param nl_cmd netlink get command number
* @param out_buffer pointer to data buffer for the result
* @param max_buffer_size buffer size
* @return size of returned data (success if > 0)
*/
size_t dwpal_nl_cmd_get(const std::string &ifname, unsigned int nl_cmd,
unsigned char *out_buffer, const size_t max_buffer_size);
/**
* @brief handle set vendor data cmd to netlink
* @param ifname radio interface name
* @param nl_cmd netlink set command number
* @param vendor_data pointer to vendor data buffer
* @param vendor_data_size size of data
* @return true on success
* @return false on failure
*/
bool dwpal_nl_cmd_set(const std::string &ifname, unsigned int nl_cmd,
unsigned char *vendor_data, size_t vendor_data_size);
bool dwpal_nl_cmd_scan_dump();
void *get_dwpal_nl_ctx() const { return (m_dwpal_nl_ctx); }

// Private data-members:
private:
const uint32_t AP_ENABLED_TIMEOUT_SEC = 15;
Expand All @@ -85,6 +110,9 @@ class base_wlan_hal_dwpal : public virtual base_wlan_hal,
std::chrono::steady_clock::time_point m_state_timeout;

void *m_dwpal_ctx[beerocks::IFACE_TOTAL_VAPS] = {nullptr};
void *m_dwpal_nl_ctx = nullptr;

int m_fd_nl_cmd_get = -1;

char m_wpa_ctrl_buffer[HOSTAPD_TO_DWPAL_MSG_LENGTH];
size_t m_wpa_ctrl_buffer_size = HOSTAPD_TO_DWPAL_MSG_LENGTH;
Expand Down
6 changes: 6 additions & 0 deletions common/beerocks/bwl/dwpal/mon_wlan_hal_dwpal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,12 @@ bool mon_wlan_hal_dwpal::process_dwpal_event(char *buffer, int bufLen, const std
return true;
}

bool mon_wlan_hal_dwpal::process_dwpal_nl_event(struct nl_msg *msg)
{
LOG(ERROR) << __func__ << "isn't implemented by this derived and shouldn't be called";
return false;
}

} // namespace dwpal

std::shared_ptr<mon_wlan_hal> mon_wlan_hal_create(std::string iface_name,
Expand Down
2 changes: 2 additions & 0 deletions common/beerocks/bwl/dwpal/mon_wlan_hal_dwpal.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define _BWL_MON_WLAN_HAL_DWPAL_H_

#include "base_wlan_hal_dwpal.h"
#include "mon_wlan_hal_dwpal_types.h"
#include <bwl/mon_wlan_hal.h>

namespace bwl {
Expand Down Expand Up @@ -43,6 +44,7 @@ class mon_wlan_hal_dwpal : public base_wlan_hal_dwpal, public mon_wlan_hal {
// Protected methods:
protected:
virtual bool process_dwpal_event(char *buffer, int bufLen, const std::string &opcode) override;
virtual bool process_dwpal_nl_event(struct nl_msg *msg) override;

// Overload for Monitor events
bool event_queue_push(mon_wlan_hal::Event event, std::shared_ptr<void> data = {})
Expand Down
61 changes: 61 additions & 0 deletions common/beerocks/bwl/dwpal/mon_wlan_hal_dwpal_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: BSD-2-Clause-Patent
*
* Copyright (c) 2020 Intel Corporation
*
* This code is subject to the terms of the BSD+Patent license.
* See LICENSE file for more details.
*/

#ifndef _BWL_MON_WLAN_HAL_DWPAL_TYPES_H_
#define _BWL_MON_WLAN_HAL_DWPAL_TYPES_H_

namespace bwl {
namespace dwpal {

#define NL_MAX_REPLY_BUFFSIZE 8192
#define NL_ATTR_HDR 4

/**
* @brief channel scan driver configuration parameters.
*
* @param passive_dwell_time time to wait on the channel during passive scans, in ms.
* @param active_dwell_time time to wait on the channel during active scans, in ms.
* @param num_probe_reqs number of probe requests to send for the same SSID.
* @param probe_reqs_interval time in ms, after which to fire the next round of probe requests for the same SSIDs.
* @param passive_scan_valid_time avoid new non-background passive scans of the channel for this time period, in seconds.
* @param active_scan_valid_time avoid new non-background active scans of the channel for this time period, in seconds.
*/
struct sScanCfgParams {
int passive_dwell_time;
int active_dwell_time;
int num_probe_reqs;
int probe_reqs_interval;
int passive_scan_valid_time;
int active_scan_valid_time;
};

/**
* @brief channel scan driver background configuration parameters.
*
* @param passive_dwell_time time to wait on the channel during passive scans, in ms.
* @param active_dwell_time time to wait on the channel during active scans, in ms.
* @param num_probe_reqs number of probe requests to send for the same SSID.
* @param probe_reqs_interval time in ms, after which to fire the next round of probe requests for the same SSIDs.
* @param num_chans_in_chunk number of channels in single scan chunk.
* @param break_time time in ms, background scan break time duration for dfs channels.
* @param break_time_busy busy flag for backround scan break.
*/
struct sScanCfgParamsBG {
int passive_dwell_time;
int active_dwell_time;
int num_probe_reqs;
int probe_reqs_interval;
int num_chans_in_chunk;
int break_time;
int break_time_busy;
};

} // namespace dwpal
} // namespace bwl

#endif // _BWL_MON_WLAN_HAL_DWPAL_TYPES_H_
6 changes: 6 additions & 0 deletions common/beerocks/bwl/dwpal/sta_wlan_hal_dwpal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,12 @@ bool sta_wlan_hal_dwpal::process_dwpal_event(char *buffer, int bufLen, const std
return true;
}

bool sta_wlan_hal_dwpal::process_dwpal_nl_event(struct nl_msg *msg)
{
LOG(ERROR) << __func__ << "isn't implemented by this derived and shouldn't be called";
return false;
}

// Add a new network and return the ID
int sta_wlan_hal_dwpal::add_network()
{
Expand Down
1 change: 1 addition & 0 deletions common/beerocks/bwl/dwpal/sta_wlan_hal_dwpal.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class sta_wlan_hal_dwpal : public base_wlan_hal_dwpal, public sta_wlan_hal {

protected:
virtual bool process_dwpal_event(char *buffer, int bufLen, const std::string &opcode) override;
virtual bool process_dwpal_nl_event(struct nl_msg *msg) override;

// Overload for Monitor events
bool event_queue_push(sta_wlan_hal::Event event, std::shared_ptr<void> data = {})
Expand Down

0 comments on commit f4a9df0

Please sign in to comment.