Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 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 
     17 #include <android-base/logging.h>
     18 
     19 #include "hidl_return_util.h"
     20 #include "wifi.h"
     21 #include "wifi_status_util.h"
     22 
     23 namespace {
     24 // Chip ID to use for the only supported chip.
     25 static constexpr android::hardware::wifi::V1_0::ChipId kChipId = 0;
     26 }  // namespace
     27 
     28 namespace android {
     29 namespace hardware {
     30 namespace wifi {
     31 namespace V1_0 {
     32 namespace implementation {
     33 using hidl_return_util::validateAndCall;
     34 
     35 Wifi::Wifi()
     36     : legacy_hal_(new legacy_hal::WifiLegacyHal()),
     37       mode_controller_(new mode_controller::WifiModeController()),
     38       run_state_(RunState::STOPPED) {}
     39 
     40 bool Wifi::isValid() {
     41   // This object is always valid.
     42   return true;
     43 }
     44 
     45 Return<void> Wifi::registerEventCallback(
     46     const sp<IWifiEventCallback>& event_callback,
     47     registerEventCallback_cb hidl_status_cb) {
     48   return validateAndCall(this,
     49                          WifiStatusCode::ERROR_UNKNOWN,
     50                          &Wifi::registerEventCallbackInternal,
     51                          hidl_status_cb,
     52                          event_callback);
     53 }
     54 
     55 Return<bool> Wifi::isStarted() {
     56   return run_state_ != RunState::STOPPED;
     57 }
     58 
     59 Return<void> Wifi::start(start_cb hidl_status_cb) {
     60   return validateAndCall(this,
     61                          WifiStatusCode::ERROR_UNKNOWN,
     62                          &Wifi::startInternal,
     63                          hidl_status_cb);
     64 }
     65 
     66 Return<void> Wifi::stop(stop_cb hidl_status_cb) {
     67   return validateAndCall(
     68       this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal, hidl_status_cb);
     69 }
     70 
     71 Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
     72   return validateAndCall(this,
     73                          WifiStatusCode::ERROR_UNKNOWN,
     74                          &Wifi::getChipIdsInternal,
     75                          hidl_status_cb);
     76 }
     77 
     78 Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
     79   return validateAndCall(this,
     80                          WifiStatusCode::ERROR_UNKNOWN,
     81                          &Wifi::getChipInternal,
     82                          hidl_status_cb,
     83                          chip_id);
     84 }
     85 
     86 WifiStatus Wifi::registerEventCallbackInternal(
     87     const sp<IWifiEventCallback>& event_callback) {
     88   if (!event_cb_handler_.addCallback(event_callback)) {
     89     return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
     90   }
     91   return createWifiStatus(WifiStatusCode::SUCCESS);
     92 }
     93 
     94 WifiStatus Wifi::startInternal() {
     95   if (run_state_ == RunState::STARTED) {
     96     return createWifiStatus(WifiStatusCode::SUCCESS);
     97   } else if (run_state_ == RunState::STOPPING) {
     98     return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
     99                             "HAL is stopping");
    100   }
    101   WifiStatus wifi_status = initializeLegacyHal();
    102   if (wifi_status.code == WifiStatusCode::SUCCESS) {
    103     // Create the chip instance once the HAL is started.
    104     chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_);
    105     run_state_ = RunState::STARTED;
    106     for (const auto& callback : event_cb_handler_.getCallbacks()) {
    107       if (!callback->onStart().isOk()) {
    108         LOG(ERROR) << "Failed to invoke onStart callback";
    109       };
    110     }
    111   } else {
    112     for (const auto& callback : event_cb_handler_.getCallbacks()) {
    113       if (!callback->onFailure(wifi_status).isOk()) {
    114         LOG(ERROR) << "Failed to invoke onFailure callback";
    115       }
    116     }
    117   }
    118   LOG(INFO) << "Wifi HAL started";
    119   return wifi_status;
    120 }
    121 
    122 WifiStatus Wifi::stopInternal() {
    123   if (run_state_ == RunState::STOPPED) {
    124     return createWifiStatus(WifiStatusCode::SUCCESS);
    125   } else if (run_state_ == RunState::STOPPING) {
    126     return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
    127                             "HAL is stopping");
    128   }
    129   WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController();
    130   if (wifi_status.code == WifiStatusCode::SUCCESS) {
    131     for (const auto& callback : event_cb_handler_.getCallbacks()) {
    132       if (!callback->onStop().isOk()) {
    133         LOG(ERROR) << "Failed to invoke onStop callback";
    134       };
    135     }
    136   } else {
    137     for (const auto& callback : event_cb_handler_.getCallbacks()) {
    138       if (!callback->onFailure(wifi_status).isOk()) {
    139         LOG(ERROR) << "Failed to invoke onFailure callback";
    140       }
    141     }
    142   }
    143   // Clear the chip object and its child objects since the HAL is now
    144   // stopped.
    145   if (chip_.get()) {
    146     chip_->invalidate();
    147     chip_.clear();
    148   }
    149   LOG(INFO) << "Wifi HAL stopped";
    150   return wifi_status;
    151 }
    152 
    153 std::pair<WifiStatus, std::vector<ChipId>> Wifi::getChipIdsInternal() {
    154   std::vector<ChipId> chip_ids;
    155   if (chip_.get()) {
    156     chip_ids.emplace_back(kChipId);
    157   }
    158   return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)};
    159 }
    160 
    161 std::pair<WifiStatus, sp<IWifiChip>> Wifi::getChipInternal(ChipId chip_id) {
    162   if (!chip_.get()) {
    163     return {createWifiStatus(WifiStatusCode::ERROR_NOT_STARTED), nullptr};
    164   }
    165   if (chip_id != kChipId) {
    166     return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
    167   }
    168   return {createWifiStatus(WifiStatusCode::SUCCESS), chip_};
    169 }
    170 
    171 WifiStatus Wifi::initializeLegacyHal() {
    172   legacy_hal::wifi_error legacy_status = legacy_hal_->initialize();
    173   if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    174     LOG(ERROR) << "Failed to initialize legacy HAL: "
    175                << legacyErrorToString(legacy_status);
    176     return createWifiStatusFromLegacyError(legacy_status);
    177   }
    178   return createWifiStatus(WifiStatusCode::SUCCESS);
    179 }
    180 
    181 WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController() {
    182   run_state_ = RunState::STOPPING;
    183   const auto on_complete_callback_ = [&]() { run_state_ = RunState::STOPPED; };
    184   legacy_hal::wifi_error legacy_status =
    185       legacy_hal_->stop(on_complete_callback_);
    186   if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    187     LOG(ERROR) << "Failed to stop legacy HAL: "
    188                << legacyErrorToString(legacy_status);
    189     return createWifiStatusFromLegacyError(legacy_status);
    190   }
    191   if (!mode_controller_->deinitialize()) {
    192     LOG(ERROR) << "Failed to deinitialize firmware mode controller";
    193     return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    194   }
    195   return createWifiStatus(WifiStatusCode::SUCCESS);
    196 }
    197 }  // namespace implementation
    198 }  // namespace V1_0
    199 }  // namespace wifi
    200 }  // namespace hardware
    201 }  // namespace android
    202