Offload HAL Service: Handle messages from Nano app

The following messages from Nano app
- Error, Scan stats, Scan Results

Also invoke the appropriate callback to the client.

Bug: 32842314
Test: VTS
Change-Id: Ie69ef82fa21ccd87160c18c89e7504c08606610c
This commit is contained in:
Sohani Rao
2017-05-18 12:18:42 -07:00
parent db6fa29a16
commit 6445f68be6
2 changed files with 127 additions and 11 deletions

View File

@@ -8,6 +8,11 @@
#include "offload_utils.h"
using namespace android::hardware::wifi::offload::V1_0::implementation::chre_constants;
using android::hardware::wifi::offload::V1_0::OffloadStatus;
namespace {
constexpr auto kScanStatsTimeout = std::chrono::milliseconds(500);
}
namespace android {
namespace hardware {
@@ -27,7 +32,7 @@ OffloadServer::OffloadServer(ChreInterfaceFactory* factory)
OffloadStatus OffloadServer::configureScans(const ScanParam& param, const ScanFilter& filter) {
LOG(INFO) << "configureScans";
if (!mChreInterface->isConnected()) {
return createOffloadStatus(OffloadStatusCode::ERROR,
return createOffloadStatus(OffloadStatusCode::NO_CONNECTION,
"Not connected to hardware implementation");
}
wifi_offload::ScanConfig scanConfig;
@@ -50,14 +55,33 @@ OffloadStatus OffloadServer::configureScans(const ScanParam& param, const ScanFi
std::pair<OffloadStatus, ScanStats> OffloadServer::getScanStats() {
LOG(INFO) << "getScanStats";
OffloadStatus status = createOffloadStatus(OffloadStatusCode::OK);
return std::make_pair(status, mScanStats);
mScanStatsStatus = createOffloadStatus(OffloadStatusCode::OK);
if (!mChreInterface->isConnected()) {
return {createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Unable to send scan stats"),
{}};
}
if (!mChreInterface->sendCommandToApp(wifi_offload::HostMessageType::HOST_CMD_GET_SCAN_STATS,
{})) {
return {createOffloadStatus(OffloadStatusCode::ERROR, "Unable to send scan stats command"),
{}};
}
LOG(VERBOSE) << "Sent getScanStats command";
{
std::unique_lock<std::mutex> lock(mScanStatsLock);
auto timeout_status = mScanStatsCond.wait_for(lock, kScanStatsTimeout);
if (timeout_status == std::cv_status::timeout) {
std::lock_guard<std::mutex> lock(mOffloadLock);
LOG(WARNING) << "Timeout waiting for scan stats";
return {createOffloadStatus(OffloadStatusCode::TIMEOUT, "Scan stats not received"), {}};
}
}
return std::make_pair(mScanStatsStatus, mScanStats);
}
OffloadStatus OffloadServer::subscribeScanResults(uint32_t delayMs) {
LOG(INFO) << "subscribeScanResults with delay:" << delayMs;
if (!mChreInterface->isConnected()) {
return createOffloadStatus(OffloadStatusCode::ERROR, "Not connected to hardware");
return createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Not connected to hardware");
}
uint32_t* buffer = &delayMs;
std::vector<uint8_t> message(reinterpret_cast<uint8_t*>(buffer),
@@ -70,7 +94,6 @@ OffloadStatus OffloadServer::subscribeScanResults(uint32_t delayMs) {
}
bool OffloadServer::unsubscribeScanResults() {
bool result = false;
LOG(INFO) << "unsubscribeScanResults";
if (!mChreInterface->isConnected()) {
LOG(WARNING) << "Failed to send unsubscribe scan results message";
@@ -86,21 +109,29 @@ bool OffloadServer::unsubscribeScanResults() {
bool OffloadServer::setEventCallback(const sp<IOffloadCallback>& cb) {
LOG(INFO) << "Set Event callback";
bool result = false;
if (cb != nullptr) {
mEventCallback = cb;
result = true;
if (cb == nullptr) {
return false;
}
return result;
std::lock_guard<std::mutex> lock(mOffloadLock);
mEventCallback = cb;
return true;
}
void OffloadServer::clearEventCallback() {
std::lock_guard<std::mutex> lock(mOffloadLock);
if (mEventCallback != nullptr) {
mEventCallback.clear();
}
LOG(INFO) << "Event callback cleared";
}
void OffloadServer::invokeErrorCallback(const OffloadStatus& status) {
std::lock_guard<std::mutex> lock(mOffloadLock);
if (mEventCallback != nullptr) {
mEventCallback->onError(status);
}
}
ChreInterfaceCallbacksImpl::ChreInterfaceCallbacksImpl(OffloadServer* server) : mServer(server) {
}
@@ -109,12 +140,88 @@ ChreInterfaceCallbacksImpl::~ChreInterfaceCallbacksImpl() {
void ChreInterfaceCallbacksImpl::handleConnectionEvents(
ChreInterfaceCallbacks::ConnectionEvent event) {
LOG(VERBOSE) << "Connection event received " << (int)event;
switch (event) {
case ChreInterfaceCallbacks::ConnectionEvent::DISCONNECTED:
case ChreInterfaceCallbacks::ConnectionEvent::CONNECTION_ABORT: {
LOG(ERROR) << "Connection to socket lost";
mServer->invokeErrorCallback(
createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Connection to socket lost"));
} break;
case ChreInterfaceCallbacks::ConnectionEvent::CONNECTED: {
LOG(INFO) << "Connected to socket";
mServer->invokeErrorCallback(createOffloadStatus(OffloadStatusCode::OK));
} break;
default:
LOG(WARNING) << "Invalid connection event received " << (int)event;
break;
}
}
void OffloadServer::handleScanResult(const std::vector<uint8_t>& message) {
std::vector<wifi_offload::ScanResult> scanResults;
std::vector<ScanResult> hidlScanResults;
std::string errorMessage;
if (!wifi_offload::fbs::Deserialize((uint8_t*)message.data(), message.size(), &scanResults)) {
invokeErrorCallback(
createOffloadStatus(OffloadStatusCode::ERROR, "Cannot deserialize scan results"));
return;
}
if (!offload_utils::ToHidlScanResults(scanResults, &hidlScanResults)) {
invokeErrorCallback(createOffloadStatus(OffloadStatusCode::ERROR,
"Cannot convert scan results to HIDL format"));
return;
}
{
std::lock_guard<std::mutex> lock(mOffloadLock);
if (mEventCallback != nullptr) {
mEventCallback->onScanResult(hidlScanResults);
}
}
}
void OffloadServer::handleScanStats(const std::vector<uint8_t>& message) {
std::lock_guard<std::mutex> lock(mScanStatsLock);
wifi_offload::ScanStats stats;
OffloadStatus status;
// Deserialize scan stats
status = createOffloadStatus(OffloadStatusCode::OK);
LOG(VERBOSE) << "Received scan stats";
if (!wifi_offload::fbs::Deserialize((uint8_t*)message.data(), message.size(), &stats)) {
status = createOffloadStatus(OffloadStatusCode::ERROR, "Cannot deserailize scan stats");
} else if (!offload_utils::ToHidlScanStats(stats, &mScanStats)) {
status = createOffloadStatus(OffloadStatusCode::ERROR,
"Cannot convert Scan stats to HIDL format");
}
mScanStatsStatus = status;
mScanStatsCond.notify_all();
}
void ChreInterfaceCallbacksImpl::handleMessage(uint32_t messageType,
const std::vector<uint8_t>& message) {
LOG(VERBOSE) << "Message from Nano app " << messageType;
switch (messageType) {
case wifi_offload::HostMessageType::HOST_MSG_SCAN_RESULTS: {
LOG(INFO) << "Received scan results";
mServer->handleScanResult(message);
} break;
case wifi_offload::HostMessageType::HOST_MSG_SCAN_STATS:
LOG(VERBOSE) << "Received scan stats from Nano app";
mServer->handleScanStats(message);
break;
case wifi_offload::HostMessageType::HOST_MSG_ERROR:
LOG(VERBOSE) << "Received error message from Nano app";
{
std::string errorMessage;
if (offload_utils::ToHidlErrorMessage(message[0], &errorMessage)) {
mServer->invokeErrorCallback(
createOffloadStatus(OffloadStatusCode::ERROR, errorMessage));
}
}
break;
default:
LOG(WARNING) << "Unknown message received" << messageType;
break;
}
}
// Methods from ::android::hidl::base::V1_0::IBase follow.

View File

@@ -41,7 +41,16 @@ class OffloadServer {
void clearEventCallback();
private:
void invokeErrorCallback(const android::hardware::wifi::offload::V1_0::OffloadStatus& status);
void handleScanResult(const std::vector<uint8_t>& message);
void handleScanStats(const std::vector<uint8_t>& message);
ScanStats mScanStats;
std::mutex mScanStatsLock;
std::condition_variable mScanStatsCond;
std::mutex mOffloadLock;
OffloadStatus mScanStatsStatus;
std::unique_ptr<ChreInterfaceCallbacksImpl> mChreInterfaceCallbacks;
std::unique_ptr<ChreInterface> mChreInterface;
sp<IOffloadCallback> mEventCallback;