C++程序  |  286行  |  12.46 KB

/*
 * Copyright (C) 2016, The Android Open Source Project
 *
 * 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 "offload_utils.h"

#include <android-base/logging.h>
#include <chre/apps/wifi_offload/error_codes.h>

namespace {

bool ToHidlRecordName(const wifi_offload::RpcLogRecord::RpcLogRecordType& chreRecordType,
                      android::hardware::wifi::offload::V1_0::RecordName* hidlRecordName) {
    bool result = true;
    switch (chreRecordType) {
        case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_INIT:
            *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_INT;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_CONFIG_SCANS:
            *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_CONFIG_SCANS;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_SUBSCRIBE_SCAN_RESULTS:
            *hidlRecordName =
                android::hardware::wifi::offload::V1_0::RecordName::CMD_SUBSCRIBE_SCAN_RESULTS;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_UNSUBSCRIBE_SCAN_RESULTS:
            *hidlRecordName =
                android::hardware::wifi::offload::V1_0::RecordName::CMD_UNSUBSCRIBE_SCAN_RESULTS;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_GET_SCAN_STATS:
            *hidlRecordName =
                android::hardware::wifi::offload::V1_0::RecordName::CMD_GET_SCAN_STATS;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_RESET:
            *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_RESET;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT_ASYNC:
            *hidlRecordName =
                android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT_ASYNC;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT:
            *hidlRecordName =
                android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_SCAN_RESULT:
            *hidlRecordName =
                android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_SCAN_RESULT;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_ABORT:
            *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_ABORT;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_ERROR:
            *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_ERROR;
            break;
        case wifi_offload::RpcLogRecord::RpcLogRecordType::REQ_SCAN:
            *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::REQ_SCAN;
            break;
        default:
            result = false;
            break;
    }
    return result;
}

uint8_t ToChreSecurityMode(uint8_t hidlSecurityMode) {
    uint8_t chreSecurityMode = 0;
    if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::OPEN) {
        chreSecurityMode |= wifi_offload::SecurityMode::OPEN;
    }
    if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::WEP) {
        chreSecurityMode |= wifi_offload::SecurityMode::WEP;
    }
    if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::PSK) {
        chreSecurityMode |= wifi_offload::SecurityMode::PSK;
    }
    if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::EAP) {
        chreSecurityMode |= wifi_offload::SecurityMode::EAP;
    }
    return chreSecurityMode;
}

uint8_t ToHidlSecurityMode(uint8_t chreSecurityMode) {
    uint8_t hidlSecurityMode = 0;
    if (chreSecurityMode & wifi_offload::SecurityMode::OPEN) {
        hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::OPEN;
    }
    if (chreSecurityMode & wifi_offload::SecurityMode::WEP) {
        hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::WEP;
    }
    if (chreSecurityMode & wifi_offload::SecurityMode::PSK) {
        hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::PSK;
    }
    if (chreSecurityMode & wifi_offload::SecurityMode::EAP) {
        hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::EAP;
    }
    return hidlSecurityMode;
}

}  // namespace

namespace android {
namespace hardware {
namespace wifi {
namespace offload {
namespace V1_0 {
namespace implementation {
namespace offload_utils {

bool ToHidlScanResult(const wifi_offload::ScanResult& chreScanResult, ScanResult* hidlScanResult) {
    if (hidlScanResult == nullptr) {
        return false;
    }
    hidlScanResult->tsf = chreScanResult.tsf_;
    hidlScanResult->capability = chreScanResult.capability_;
    hidlScanResult->rssi = chreScanResult.rssi_dbm_;
    hidlScanResult->frequency = chreScanResult.frequency_scanned_mhz_;
    memcpy(&hidlScanResult->bssid[0], &chreScanResult.bssid_[0],
           wifi_offload::ScanResult::kBssidSize);
    chreWifiSsidListItem chreWifiSsid;
    chreScanResult.ssid_.ToChreWifiSsidListItem(&chreWifiSsid);
    std::vector<uint8_t> ssid;
    for (size_t i = 0; i < chreWifiSsid.ssidLen; i++) {
        ssid.push_back(chreWifiSsid.ssid[i]);
    }
    hidlScanResult->networkInfo.ssid = ssid;
    hidlScanResult->networkInfo.flags = ToHidlSecurityMode(chreScanResult.security_modes_);
    return true;
}

bool ToHidlScanResults(const std::vector<wifi_offload::ScanResult>& chreScanResults,
                       std::vector<ScanResult>* hidlScanResults) {
    LOG(VERBOSE) << "ScanResults from CHRE, size=" << chreScanResults.size();
    for (const auto& scan_result_from_nano_app : chreScanResults) {
        ScanResult hidl_scan_result;
        if (!ToHidlScanResult(scan_result_from_nano_app, &hidl_scan_result)) {
            return false;
        }
        hidlScanResults->push_back(hidl_scan_result);
    }
    return true;
}

bool ToHidlScanStats(const wifi_offload::ScanStats& chreScanStats, ScanStats* hidlScanStats) {
    hidlScanStats->subscriptionDurationMs = chreScanStats.last_subscription_duration_ms_;
    hidlScanStats->numScansRequestedByWifi = chreScanStats.num_scans_requested_by_nanoapp_;
    hidlScanStats->numScansServicedByWifi = chreScanStats.num_scans_serviced_by_hardware_;
    hidlScanStats->numScansServicedbyCache = chreScanStats.num_scans_serviced_by_cache_;
    std::vector<ScanRecord> hidlScanRecords;
    for (const auto& chreScanRecord : chreScanStats.scan_records_) {
        ScanRecord hidlScanRecord;
        hidlScanRecord.durationMs = chreScanRecord.time_spent_scanning_ms_;
        hidlScanRecord.numChannelsScanned = chreScanRecord.num_channels_scanned_;
        hidlScanRecord.numEntriesAggregated = chreScanRecord.num_entries_aggregated_;
        hidlScanRecords.push_back(hidlScanRecord);
    }
    hidlScanStats->scanRecord = hidlScanRecords;
    std::vector<LogRecord> logRecords;
    for (const auto& chreLogRecord : chreScanStats.rpc_log_records_) {
        LogRecord logRecord;
        if (!ToHidlRecordName(chreLogRecord.record_type_, &logRecord.recordName)) {
            return false;
        }
        logRecord.logTimeMs = chreLogRecord.timestamp_chre_ms_;
        logRecords.push_back(logRecord);
    }
    hidlScanStats->logRecord = logRecords;
    for (size_t i = 0; i < hidlScanStats->histogramChannelsScanned.elementCount(); i++) {
        hidlScanStats->histogramChannelsScanned[i] =
            chreScanStats.channel_histogram_.GetChannelScanCount(i);
    }
    return true;
}

bool ToChreScanConfig(const ScanParam& param, const ScanFilter& filter,
                      wifi_offload::ScanConfig* scanConfig) {
    scanConfig->scan_params_.disconnected_mode_scan_interval_ms_ =
        param.disconnectedModeScanIntervalMs;
    for (const auto& ssid : param.ssidList) {
        wifi_offload::Ssid chreSsid;
        chreSsid.SetData(ssid.data(), ssid.size());
        scanConfig->scan_params_.ssids_to_scan_.push_back(chreSsid);
    }
    for (const auto& freq : param.frequencyList) {
        scanConfig->scan_params_.frequencies_to_scan_mhz_.push_back(freq);
    }
    scanConfig->scan_filter_.min_rssi_threshold_dbm_ = filter.rssiThreshold;
    for (const auto& nwInfo : filter.preferredNetworkInfoList) {
        wifi_offload::PreferredNetwork chreNwInfo;
        chreNwInfo.security_modes_ = ToChreSecurityMode(nwInfo.flags);
        chreNwInfo.ssid_.SetData(nwInfo.ssid.data(), nwInfo.ssid.size());
        scanConfig->scan_filter_.networks_to_match_.push_back(std::move(chreNwInfo));
    }
    return true;
}

bool ToHidlErrorMessage(uint32_t errorCode, std::string* errorMessage) {
    bool reportError = true;
    switch (errorCode) {
        case wifi_offload::ErrorCode::FAILED_TO_ALLOCATE_MESSAGE_BUFFER:
            *errorMessage = "Failed to allocate message buffer";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SERIALIZE_MESSAGE:
            *errorMessage = "Failed to serialize message";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SEND_MESSAGE:
            *errorMessage = "Failed to send message";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_DESERIALIZE_SCAN_CONFIG:
            *errorMessage = "Failed to deserialize scan config";
            break;
        case wifi_offload::ErrorCode::INVALID_SUBSCRIBE_MESSAGE_SIZE:
            *errorMessage = "Invalid subscribe message size";
            break;
        case wifi_offload::ErrorCode::SCAN_CONFIG_NOT_INITIALIZED:
            *errorMessage = "Scan config not initialized";
            break;
        case wifi_offload::ErrorCode::UNSPECIFIED_HOST_ENDPOINT:
            *errorMessage = "Unspecified host end point";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SEND_SCAN_RESULTS:
            *errorMessage = "Failed to send scan results";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SEND_SCAN_STATS:
            *errorMessage = "Failed to send scan stats";
            break;
        case wifi_offload::ErrorCode::ONDEMAND_SCAN_NOT_SUPPORTED:
            *errorMessage = "On demand scans not supported";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST:
            *errorMessage = "Failed to send on demand scan request";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST_ASYNC:
            *errorMessage = "Failed to send on demand scan request async";
            break;
        case wifi_offload::ErrorCode::OUT_OF_ORDER_SCAN_RESULTS:
            *errorMessage = "Out of order scan results";
            break;
        case wifi_offload::ErrorCode::INCOMPLETE_SCAN_RESULTS_BEFORE_SCAN_REQUEST:
            *errorMessage = "Incomplete scan results before scan request";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_SET_SCAN_TIMER:
            *errorMessage = "Failed to set scan timer";
            break;
        case wifi_offload::ErrorCode::SCAN_MONITORING_NOT_SUPPORTED:
            *errorMessage = "Scan Monitoring not supported";
            break;
        case wifi_offload::ErrorCode::FAILED_TO_START_SCAN_MONITORING:
            *errorMessage = "Failed to start scan monitoring";
            reportError = false;
            break;
        case wifi_offload::ErrorCode::FAILED_TO_STOP_SCAN_MONITORING:
            *errorMessage = "Failed to stop scan monitoring";
            reportError = false;
            break;
        case wifi_offload::ErrorCode::FAILED_TO_CONFIGURE_SCAN_MONITORING_ASYNC:
            *errorMessage = "Failed to configure scan monitoring async";
            reportError = false;
            break;
        default:
            *errorMessage = "Invalid error code";
            reportError = false;
            break;
    }
    return reportError;
}

}  // namespace offload_utils
}  // namespace implementation
}  // namespace V1_0
}  // namespace offload
}  // namespace wifi
}  // namespace hardware
}  // namespace android