• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SocketCallbacks(ChreInterface * parent)39 SocketCallbacks::SocketCallbacks(ChreInterface* parent) : mParent(parent) {
40 }
41 
onMessageReceived(const void * data,size_t length)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 
onConnected()49 void SocketCallbacks::onConnected() {
50     LOG(INFO) << "Connected to CHRE socket";
51     mParent->reportConnectionEvent(ChreInterfaceCallbacks::CONNECTED);
52 }
53 
onConnectionAborted()54 void SocketCallbacks::onConnectionAborted() {
55     LOG(WARNING) << "Connection to CHRE socket Aborted";
56     mParent->reportConnectionEvent(ChreInterfaceCallbacks::CONNECTION_ABORT);
57 }
58 
onDisconnected()59 void SocketCallbacks::onDisconnected() {
60     LOG(WARNING) << "Disconnected from CHRE socket";
61     mParent->reportConnectionEvent(ChreInterfaceCallbacks::DISCONNECTED);
62 }
63 
handleNanoappMessage(const fbs::NanoappMessageT & message)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 
handleHubInfoResponse(const fbs::HubInfoResponseT & response)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 
handleNanoappListResponse(const fbs::NanoappListResponseT & response)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 
handleLoadNanoappResponse(const fbs::LoadNanoappResponseT & response)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 
handleUnloadNanoappResponse(const fbs::UnloadNanoappResponseT & response)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 
ChreInterface(ChreInterfaceCallbacks * callback)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 
~ChreInterface()125 ChreInterface::~ChreInterface() {
126     mClient.disconnect();
127 }
128 
isConnected()129 bool ChreInterface::isConnected() {
130     std::lock_guard<std::mutex> lock(mChreInterfaceLock);
131     return mSocketConnected;
132 }
133 
reportConnectionEvent(ChreInterfaceCallbacks::ConnectionEvent event)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 
sendCommandToApp(uint32_t messageType,const std::vector<uint8_t> & message)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 
handleMessage(uint32_t messageType,const void * messageData,size_t messageDataLen)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 
getHubInfo()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 
getNanoAppList()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