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

Commit

Permalink
controller: bml: DCS channel scan, get results
Browse files Browse the repository at this point in the history
Add get results function in bml and bml_internal

Signed-off-by: itay elenzweig <[email protected]>
  • Loading branch information
itayx committed Jan 22, 2020
1 parent 5d3d48a commit 22a9b51
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 13 deletions.
8 changes: 5 additions & 3 deletions controller/src/beerocks/bml/bml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ int bml_get_dcs_continuous_scan_params(BML_CTX ctx, const char *radio_mac, int *
}

int bml_get_dcs_scan_results(BML_CTX ctx, const char *radio_mac,
struct BML_DCS_NEIGHBOR_AP **output_results,
struct BML_NEIGHBOR_AP **output_results,
unsigned int *output_results_size, unsigned char *output_result_status,
bool is_single_scan)
{
Expand All @@ -621,8 +621,10 @@ int bml_get_dcs_scan_results(BML_CTX ctx, const char *radio_mac,
return (-BML_RET_INVALID_ARGS);
}

// TODO: call suitable bml api
return BML_RET_OP_FAILED;
auto pBML = static_cast<bml_internal *>(ctx);
return pBML->get_dcs_scan_results(network_utils::mac_from_string(std::string(radio_mac)),
output_results, output_results_size, *output_results_size,
output_result_status, is_single_scan);
}

int bml_start_dcs_single_scan(BML_CTX ctx, const char *radio_mac, int dwell_time,
Expand Down
176 changes: 175 additions & 1 deletion controller/src/beerocks/bml/internal/bml_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,39 @@ static void config_logger(const std::string log_file = std::string())

#endif // BEEROCKS_DEBUG

static void translate_channel_scan_results(const beerocks_message::sChannelScanResults &res_in,
BML_NEIGHBOR_AP *res_out)
{
if (!res_out) {
LOG(ERROR) << "Failed translating results, res_out==NULL";
return;
}

string_utils::copy_string(res_out->ap_SSID, res_in.ssid,
beerocks::message::WIFI_SSID_MAX_LENGTH);
std::copy_n(res_in.bssid.oct, BML_MAC_ADDR_LEN, res_out->ap_BSSID);
std::copy_n(res_in.security_mode_enabled, BML_CHANNEL_SCAN_ENUM_LIST_SIZE,
res_out->ap_SecurityModeEnabled);
std::copy_n(res_in.encryption_mode, BML_CHANNEL_SCAN_ENUM_LIST_SIZE,
res_out->ap_EncryptionMode);
std::copy_n(res_in.supported_standards, BML_CHANNEL_SCAN_ENUM_LIST_SIZE,
res_out->ap_SupportedStandards);
std::copy_n(res_in.basic_data_transfer_rates_kbps, BML_CHANNEL_SCAN_ENUM_LIST_SIZE,
res_out->ap_BasicDataTransferRates);
std::copy_n(res_in.supported_data_transfer_rates_kbps, BML_CHANNEL_SCAN_ENUM_LIST_SIZE,
res_out->ap_SupportedDataTransferRates);

res_out->ap_Channel = res_in.channel;
res_out->ap_SignalStrength = res_in.signal_strength_dBm;
res_out->ap_OperatingFrequencyBand = res_in.operating_frequency_band;
res_out->ap_OperatingStandards = res_in.operating_standards;
res_out->ap_OperatingChannelBandwidth = res_in.operating_channel_bandwidth;
res_out->ap_BeaconPeriod = res_in.beacon_period_ms;
res_out->ap_Noise = res_in.noise_dBm;
res_out->ap_DTIMPeriod = res_in.dtim_period;
res_out->ap_ChannelUtilization = res_in.channel_utilization;
}

//////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Implementation ///////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -920,7 +953,7 @@ int bml_internal::process_cmdu_header(std::shared_ptr<beerocks_header> beerocks_
<< " response, but no one is waiting...";
}
} break;
case beerocks_message::ACTION_BML_CHANNEL_SCAN_GET_CONTINUOUS_PARAMS_RESPONSE: {
case beerocks_message::ACTION_BML_CHANNEL_SCAN_GET_CONTINUOUS_PARAMS_RESPONSE: {
auto response = beerocks_header->addClass<
beerocks_message::cACTION_BML_CHANNEL_SCAN_GET_CONTINUOUS_PARAMS_RESPONSE>();
if (!response) {
Expand Down Expand Up @@ -958,6 +991,60 @@ int bml_internal::process_cmdu_header(std::shared_ptr<beerocks_header> beerocks_
}
} break;
case beerocks_message::ACTION_BML_CHANNEL_SCAN_GET_RESULTS_RESPONSE: {
LOG(DEBUG) << "ACTION_BML_DCS_GET_SCAN_RESULTS_RESPONSE received";
auto response =
beerocks_header
->addClass<beerocks_message::cACTION_BML_CHANNEL_SCAN_GET_RESULTS_RESPONSE>();
if (!response) {
LOG(ERROR) << "addClass cACTION_BML_CHANNEL_SCAN_GET_RESULTS_RESPONSE failed";
return BML_RET_OP_FAILED;
}

//Signal any waiting threads
if (m_prmChannelScanResultsGet) {

if (m_scan_results && m_scan_results_maxsize && m_scan_results_status) {

LOG(DEBUG) << "Receiving Response";

uint8_t op_error_code = response->op_error_code();
*m_scan_results_status = response->result_status();
auto scan_results_size = response->results_size();
uint8_t last = response->last();

LOG(DEBUG) << "Opt code: " << int(op_error_code)
<< ", status: " << int(*m_scan_results_status)
<< ", size: " << int(scan_results_size);

if (scan_results_size > 0) {
LOG(DEBUG) << "currently with " << m_scan_results->size() << " results";

// Get results from CMDU
auto results = &std::get<1>(response->results(0));

// Cap results if no more room is avaliable
scan_results_size =
(m_scan_results->size() + scan_results_size > *m_scan_results_maxsize)
? *m_scan_results_maxsize - m_scan_results->size()
: scan_results_size;

// Insert results
m_scan_results->insert(m_scan_results->end(), results,
results + scan_results_size);
LOG(DEBUG) << scan_results_size << " results added";
}
LOG(DEBUG) << "last: " << (int)last;
if (last == 1) {
LOG(DEBUG) << "Results done";
m_prmChannelScanResultsGet->set_value(op_error_code);
} else {
LOG(DEBUG) << "Results cont";
}
}
} else {
LOG(WARNING) << "Received ACTION_BML_CHANNEL_SCAN_GET_RESULTS_REQUEST response, "
<< "but no one is waiting...";
}
} break;
case beerocks_message::ACTION_BML_CHANNEL_SCAN_START_SCAN_RESPONSE: {
LOG(DEBUG) << "ACTION_BML_DCS_GET_SCAN_RESULTS_RESPONSE received";
Expand Down Expand Up @@ -1487,6 +1574,93 @@ int bml_internal::get_dcs_continuous_scan_params(const sMacAddr &mac, int *outpu
return (iRet);
}

int bml_internal::get_dcs_scan_results(const sMacAddr &mac, BML_NEIGHBOR_AP **output_results,
unsigned int *output_results_size,
const unsigned int max_results_size,
uint8_t *output_result_status, bool is_single_scan)
{
if (!output_results || !output_results_size || !output_result_status) {
LOG(ERROR) << "Function is called, but no data is being requested!";
return (-BML_RET_INVALID_DATA);
}

// If the socket is not valid, attempt to re-establish the connection
if (!m_sockMaster) {
int iRet = connect_to_master();
if (iRet != BML_RET_OK) {
return iRet;
}
}

// Initialize the promise for receiving the response
beerocks::promise<int> prmChannelScanResultsGet;
m_prmChannelScanResultsGet = &prmChannelScanResultsGet;
int iOpTimeout = DELAYED_RESPONSE_TIMEOUT; // Default timeout
auto scan_results = std::list<beerocks_message::sChannelScanResults>();
uint32_t scan_results_maxsize = uint32_t(max_results_size);

m_scan_results = &scan_results;
m_scan_results_maxsize = &scan_results_maxsize;
m_scan_results_status = output_result_status;

auto request = message_com::create_vs_message<
beerocks_message::cACTION_BML_CHANNEL_SCAN_GET_RESULTS_REQUEST>(cmdu_tx);

if (!request) {
LOG(ERROR) << "Failed building cACTION_BML_CHANNEL_SCAN_GET_RESULTS_REQUEST message!";
return (-BML_RET_OP_FAILED);
}

request->radio_mac() = mac;
request->scan_mode() = (is_single_scan) ? 1 : 0;
// Build and send the message
if (!message_com::send_cmdu(m_sockMaster, cmdu_tx)) {
LOG(ERROR) << "Failed sending param get message!";
m_prmChannelScanResultsGet = nullptr;
m_scan_results = nullptr;
m_scan_results_maxsize = nullptr;
m_scan_results_status = nullptr;
return (-BML_RET_OP_FAILED);
}
LOG(DEBUG) << "ACTION_BML_CHANNEL_SCAN_GET_RESULTS_REQUEST sent";

int iRet = BML_RET_OK;

if (!m_prmChannelScanResultsGet->wait_for(iOpTimeout)) {
LOG(WARNING) << "Timeout while waiting for results get response...";
iRet = -BML_RET_TIMEOUT;
}

// Clear the scan results members
m_scan_results = nullptr;
m_scan_results_maxsize = nullptr;
m_scan_results_status = nullptr;

// Clear the promise holder
m_prmChannelScanResultsGet = nullptr;

if (iRet != BML_RET_OK) {
LOG(ERROR) << "Results get failed!";
return (iRet);
}

iRet = prmChannelScanResultsGet.get_value();
if (iRet != int(eChannelScanOpErrCode::CHANNEL_SCAN_OP_SUCCESS)) {
LOG(ERROR) << "Results returned with error code:" << iRet << ". Aborting!";
return iRet;
}

//output_results_size will be set to the number of actual returning results
*output_results_size = 0;
for (auto res : scan_results) {
auto out = &((*output_results)[*output_results_size]);
translate_channel_scan_results(res, out);
*output_results_size += 1;
}

return BML_RET_OK;
}

int bml_internal::start_dcs_single_scan(const sMacAddr &mac, int dwell_time_ms,
int channel_pool_size, unsigned int *channel_pool)
{
Expand Down
31 changes: 22 additions & 9 deletions controller/src/beerocks/bml/internal/bml_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ class bml_internal : public beerocks::socket_thread {
int *output_interval_time, unsigned int *output_channel_pool,
int *output_channel_pool_size);

//get channel scan results
int get_dcs_scan_results(const sMacAddr &mac, BML_NEIGHBOR_AP **output_results,
unsigned int *output_results_size, const unsigned int max_results_size,
uint8_t *output_result_status, bool is_single_scan);

//trigger single channel scan
int start_dcs_single_scan(const sMacAddr &mac, int dwell_time_ms, int channel_pool_size,
unsigned int *channel_pool);
Expand Down Expand Up @@ -231,6 +236,8 @@ class bml_internal : public beerocks::socket_thread {
beerocks::promise<int> *m_prmRdkbWlan = nullptr;
//Promise used to indicate the GetParams response was received
beerocks::promise<bool> *m_prmChannelScanParamsGet = nullptr;
//Promise used to indicate the GetResults response was received
beerocks::promise<int> *m_prmChannelScanResultsGet = nullptr;

std::map<uint8_t, beerocks::promise<int> *> m_prmCliResponses;

Expand All @@ -240,16 +247,22 @@ class bml_internal : public beerocks::socket_thread {
BML_STATS_UPDATE_CB m_cbStatsUpdate = nullptr;
BML_EVENT_CB m_cbEvent = nullptr;

beerocks_message::sDeviceInfo *m_device_info = nullptr;
beerocks_message::sWifiCredentials *m_wifi_credentials = nullptr;
beerocks_message::sAdminCredentials *m_admin_credentials = nullptr;
beerocks_message::sVersions *m_master_slave_versions = nullptr;
beerocks_message::sRestrictedChannels *m_Restricted_channels = nullptr;
beerocks_message::sDeviceInfo *m_device_info = nullptr;
beerocks_message::sWifiCredentials *m_wifi_credentials = nullptr;
beerocks_message::sAdminCredentials *m_admin_credentials = nullptr;
beerocks_message::sVersions *m_master_slave_versions = nullptr;
beerocks_message::sRestrictedChannels *m_Restricted_channels = nullptr;
//m_scan_params is used when receiving the channel scan parameters
beerocks_message::sChannelScanRequestParams *m_scan_params = nullptr;
BML_VAP_INFO *m_vaps = nullptr;
uint8_t *m_pvaps_list_size = nullptr;
uint16_t id = 0;
beerocks_message::sChannelScanRequestParams *m_scan_params = nullptr;
//m_scan_results is used when receiving channel scan results
std::list<beerocks_message::sChannelScanResults> *m_scan_results = nullptr;
//m_scan_results_status is used to store the results' latest status
uint8_t *m_scan_results_status = nullptr;
//m_scan_results_maxsize is used to indicate the maximum capacity of the requested results
uint32_t *m_scan_results_maxsize = nullptr;
BML_VAP_INFO *m_vaps = nullptr;
uint8_t *m_pvaps_list_size = nullptr;
uint16_t id = 0;
static bool s_fExtLogContext;
};

Expand Down

0 comments on commit 22a9b51

Please sign in to comment.