Home | History | Annotate | Download | only in wifi_offload
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include "chre_interface.h"
     17 
     18 #include <android-base/logging.h>
     19 
     20 #include <chrono>
     21 
     22 #include "chre_host/host_protocol_host.h"
     23 
     24 using android::chre::getStringFromByteVector;
     25 using android::chre::HostProtocolHost;
     26 using flatbuffers::FlatBufferBuilder;
     27 
     28 namespace chre_constants = android::hardware::wifi::offload::V1_0::implementation::chre_constants;
     29 
     30 namespace fbs = ::chre::fbs;
     31 
     32 namespace android {
     33 namespace hardware {
     34 namespace wifi {
     35 namespace offload {
     36 namespace V1_0 {
     37 namespace implementation {
     38 
     39 SocketCallbacks::SocketCallbacks(ChreInterface* parent) : mParent(parent) {
     40 }
     41 
     42 void SocketCallbacks::onMessageReceived(const void* data, size_t length) {
     43     LOG(VERBOSE) << "Message received from CHRE socket";
     44     if (!HostProtocolHost::decodeMessageFromChre(data, length, *this)) {
     45         LOG(WARNING) << "Failed to decode message";
     46     }
     47 }
     48 
     49 void SocketCallbacks::onConnected() {
     50     LOG(INFO) << "Connected to CHRE socket";
     51     mParent->reportConnectionEvent(ChreInterfaceCallbacks::CONNECTED);
     52 }
     53 
     54 void SocketCallbacks::onConnectionAborted() {
     55     LOG(WARNING) << "Connection to CHRE socket Aborted";
     56     mParent->reportConnectionEvent(ChreInterfaceCallbacks::CONNECTION_ABORT);
     57 }
     58 
     59 void SocketCallbacks::onDisconnected() {
     60     LOG(WARNING) << "Disconnected from CHRE socket";
     61     mParent->reportConnectionEvent(ChreInterfaceCallbacks::DISCONNECTED);
     62 }
     63 
     64 void SocketCallbacks::handleNanoappMessage(const fbs::NanoappMessageT& message) {
     65     LOG(VERBOSE) << "handleNanoappMessage from appId: " << message.app_id;
     66     LOG(VERBOSE) << "HostEndPoint: " << message.host_endpoint;
     67     if (message.app_id == chre_constants::kWifiOffloadNanoAppId) {
     68         mParent->handleMessage(message.message_type, message.message.data(), message.message.size());
     69     }
     70 }
     71 
     72 void SocketCallbacks::handleHubInfoResponse(const fbs::HubInfoResponseT& response) {
     73     LOG(VERBOSE) << "Hub Info response";
     74     LOG(VERBOSE) << "Hub Info name: " << getStringFromByteVector(response.name);
     75     LOG(VERBOSE) << "Version : " << response.chre_platform_version;
     76     LOG(VERBOSE) << "Legacy Platform Version: " << response.platform_version;
     77     LOG(VERBOSE) << "Legacy Toolchain Version: " << response.toolchain_version;
     78     LOG(VERBOSE) << "Peak Mips: " << response.peak_mips;
     79     LOG(VERBOSE) << "Stopped Power: " << response.stopped_power;
     80     LOG(VERBOSE) << "Sleep Power: " << response.sleep_power;
     81     LOG(VERBOSE) << "Peak Power: " << response.peak_power;
     82     LOG(VERBOSE) << "Platform ID: " << response.platform_id;
     83     LOG(VERBOSE) << "Vendor : " << getStringFromByteVector(response.vendor);
     84     LOG(VERBOSE) << "Toolchain : " << getStringFromByteVector(response.toolchain);
     85     LOG(VERBOSE) << "maxMessageLen : " << response.max_msg_len;
     86     if (response.max_msg_len < chre_constants::kMaxMessageLen) {
     87         LOG(WARNING) << "Incorrect max message length";
     88     }
     89 }
     90 
     91 void SocketCallbacks::handleNanoappListResponse(const fbs::NanoappListResponseT& response) {
     92     LOG(VERBOSE) << "handleNanoAppListResponse";
     93     for (const std::unique_ptr<fbs::NanoappListEntryT>& nanoapp : response.nanoapps) {
     94         if (nanoapp == nullptr) {
     95             continue;
     96         }
     97         if (nanoapp->app_id == chre_constants::kWifiOffloadNanoAppId && nanoapp->enabled) {
     98             LOG(INFO) << "Wifi Offload Nano app found";
     99             LOG(INFO) << "Version: " << nanoapp->version;
    100             break;
    101         }
    102     }
    103 }
    104 
    105 void SocketCallbacks::handleLoadNanoappResponse(const fbs::LoadNanoappResponseT& response) {
    106     LOG(VERBOSE) << "Load Nano app response";
    107     LOG(VERBOSE) << "Transaction ID: " << response.transaction_id;
    108     LOG(VERBOSE) << "Status: " << response.success;
    109 }
    110 
    111 void SocketCallbacks::handleUnloadNanoappResponse(const fbs::UnloadNanoappResponseT& response) {
    112     LOG(VERBOSE) << "Unload Nano app response";
    113     LOG(VERBOSE) << "Transaction ID: " << response.transaction_id;
    114     LOG(VERBOSE) << "Status: " << response.success;
    115 }
    116 
    117 ChreInterface::ChreInterface(ChreInterfaceCallbacks* callback)
    118     : mSocketCallbacks(new SocketCallbacks(this)), mServerCallbacks(callback),
    119       mSocketConnected(false) {
    120     if (!mClient.connectInBackground(chre_constants::kSocketName, mSocketCallbacks)) {
    121         LOG(ERROR) << "Offload HAL is not connected to Chre";
    122     }
    123 }
    124 
    125 ChreInterface::~ChreInterface() {
    126     mClient.disconnect();
    127 }
    128 
    129 bool ChreInterface::isConnected() {
    130     std::lock_guard<std::mutex> lock(mChreInterfaceLock);
    131     return mSocketConnected;
    132 }
    133 
    134 void ChreInterface::reportConnectionEvent(ChreInterfaceCallbacks::ConnectionEvent event) {
    135     bool connectionStatus = false;
    136     switch (event) {
    137         case ChreInterfaceCallbacks::ConnectionEvent::CONNECTED:
    138             connectionStatus = true;
    139             if (!getHubInfo() || !getNanoAppList()) {
    140                 LOG(WARNING) << "Unable to get platform and nano app info";
    141             }
    142             break;
    143         case ChreInterfaceCallbacks::ConnectionEvent::DISCONNECTED:
    144         case ChreInterfaceCallbacks::ConnectionEvent::CONNECTION_ABORT:
    145             break;
    146         default:
    147             LOG(WARNING) << "Invalid connection event recieved";
    148             return;
    149     }
    150     {
    151         std::lock_guard<std::mutex> lock(mChreInterfaceLock);
    152         mSocketConnected = connectionStatus;
    153     }
    154     mServerCallbacks->handleConnectionEvents(event);
    155 }
    156 
    157 bool ChreInterface::sendCommandToApp(uint32_t messageType, const std::vector<uint8_t>& message) {
    158     FlatBufferBuilder builder(chre_constants::kMaxMessageLen);
    159     void* messageData = nullptr;
    160     size_t messageDataLen = message.size();
    161     if (messageDataLen > 0) {
    162         messageData = (void*)message.data();
    163     }
    164     HostProtocolHost::encodeNanoappMessage(builder, chre_constants::kWifiOffloadNanoAppId,
    165                                            messageType, 0, messageData, messageDataLen);
    166     if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
    167         LOG(WARNING) << "Failed to send message to Nano app";
    168         return false;
    169     }
    170     LOG(VERBOSE) << "Command sent " << messageType;
    171     return true;
    172 }
    173 
    174 void ChreInterface::handleMessage(uint32_t messageType, const void* messageData,
    175                                   size_t messageDataLen) {
    176     const uint8_t* messageBuf = reinterpret_cast<const uint8_t*>(messageData);
    177     std::vector<uint8_t> message(messageBuf, messageBuf + messageDataLen);
    178     mServerCallbacks->handleMessage(messageType, message);
    179 }
    180 
    181 bool ChreInterface::getHubInfo() {
    182     LOG(VERBOSE) << "getHubInfo";
    183 
    184     FlatBufferBuilder builder(chre_constants::kHubInfoRequestBufLen);
    185     HostProtocolHost::encodeHubInfoRequest(builder);
    186     if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
    187         LOG(WARNING) << "Failed to send Hub Info request";
    188         return false;
    189     }
    190     return true;
    191 }
    192 
    193 bool ChreInterface::getNanoAppList() {
    194     LOG(VERBOSE) << "getNanoAppList";
    195     FlatBufferBuilder builder(chre_constants::kNanoAppListRequestBufLen);
    196     HostProtocolHost::encodeNanoappListRequest(builder);
    197 
    198     if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
    199         LOG(WARNING) << "Unable to send Nano app List request";
    200         return false;
    201     }
    202     return true;
    203 }
    204 }  // namespace implementation
    205 }  // namespace V1_0
    206 }  // namespace offload
    207 }  // namespace wifi
    208 }  // namespace hardware
    209 }  // namespace android
    210