-
Notifications
You must be signed in to change notification settings - Fork 32
[DCS Patch 1/5] port dynamic channel selection from rdkb bwl #637
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -284,6 +284,12 @@ bool base_wlan_hal_dummy::dummy_send_cmd(const std::string &cmd) { return false; | |
|
||
bool base_wlan_hal_dummy::dummy_send_cmd(const std::string &cmd, char **reply) { return false; } | ||
|
||
bool base_wlan_hal_dummy::process_nl_events() | ||
{ | ||
LOG(ERROR) << __func__ << "not implemented"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't we agree to remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. first time i hear about it. why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is redundant - see @vitalybu 's comments |
||
return false; | ||
} | ||
|
||
bool base_wlan_hal_dummy::refresh_radio_info() | ||
{ | ||
if (get_iface_name() == "wlan2") { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,6 +136,20 @@ 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: " | ||
<< m_radio_info.iface_name << "disbling netlink for this platform"; | ||
m_dwpal_nl_ctx = nullptr; | ||
} else { | ||
LOG(DEBUG) | ||
<< "dwpal_driver_nl_attach() success for: " << m_radio_info.iface_name; | ||
} | ||
} | ||
|
||
if (attached) { | ||
if (get_type() != HALType::Station) { | ||
transition.change_destination(dwpal_fsm_state::GetRadioInfo); | ||
|
@@ -292,6 +306,22 @@ 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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The dwpal netlink context is created in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure it this test is mandatory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still, this should be removed as part of #665 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here is a live example why it should stay. netgear-rax40-1_logs: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly. Remember that RAX40 has a much older driver version at the moment so the attach will fail |
||
if (dwpal_driver_nl_fd_get(m_dwpal_nl_ctx, &m_fd_nl_events, &m_fd_nl_cmd_get)) { | ||
LOG(ERROR) << "getting nl fd failed for: " << m_radio_info.iface_name | ||
<< "disbling netlink for this platform"; | ||
m_dwpal_nl_ctx = nullptr; | ||
} else { | ||
LOG(DEBUG) << "Attach event interface to nl - SUCCESS! for: " | ||
<< m_radio_info.iface_name << " nl_fd = " << m_fd_nl_events | ||
<< " fdcmdget_nl = " << m_fd_nl_cmd_get; | ||
} | ||
} else { | ||
LOG(ERROR) << "NL ctx is NULL! netlink is disabled for this platform"; | ||
} | ||
|
||
return true; | ||
}) | ||
|
||
|
@@ -331,6 +361,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; | ||
}) | ||
|
||
|
@@ -507,6 +548,150 @@ bool base_wlan_hal_dwpal::attach_ctrl_interface(int vap_id) | |
return true; | ||
} | ||
|
||
bool base_wlan_hal_dwpal::process_nl_events() | ||
{ | ||
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; | ||
vitalybu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
LOG(ERROR) << __func__ << "vendor_data is NULL ==> Abort!"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function should return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
unsigned char *out_buffer, | ||
const size_t max_buffer_size) | ||
{ | ||
size_t data_size = 0; | ||
|
||
if (out_buffer == nullptr) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
LOG(ERROR) << __func__ << "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) << __func__ << "ERROR for cmd = " << nl_cmd; | ||
return data_size; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either initialize There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
// 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment repeates in every function, maybe it would be better to move it to the Doxygen. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
// 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() | ||
{ | ||
char *reply = nullptr; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it's better to create a FindNL cmake file and use the standard cmake
find_package()
.Here's an example: https://github.com/nasa/channel-emulator/blob/master/cmake/Modules/FindLibNL.cmake
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Careful with that! The project is GPL-2.0 so presumably that file is GPL-2.0 as well. As such it's OK if we include GPL-2.0 files that are used during the build (it just means that if you distribute the source code, you need to give the recipient the right to redistribute that particular file further). But it's making our license more complicated. If you do take over that file, it should get a copyright header including authorship information of the original (which is difficult to retrieve since they probably also copied it from somewhere else).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was just an example. We should write our own cmake find file for libnl..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As agreed, and since its already exists for other libraries, lets do this in a separate PR as part #665.
Keeping the comment open for that.