/* * Copyright (C) 2022 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. */ #ifndef WIFI_CHIP_H_ #define WIFI_CHIP_H_ #include #include #include #include #include #include #include #include "aidl_callback_util.h" #include "ringbuffer.h" #include "wifi_ap_iface.h" #include "wifi_feature_flags.h" #include "wifi_legacy_hal.h" #include "wifi_mode_controller.h" #include "wifi_nan_iface.h" #include "wifi_p2p_iface.h" #include "wifi_rtt_controller.h" #include "wifi_sta_iface.h" namespace aidl { namespace android { namespace hardware { namespace wifi { /** * AIDL interface object used to control a Wifi HAL chip instance. * Since there is only a single chip instance used today, there is no * identifying handle information stored here. */ class WifiChip : public BnWifiChip { public: WifiChip(int32_t chip_id, bool is_primary, const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, const std::shared_ptr iface_util, const std::weak_ptr feature_flags, const std::function& subsystemCallbackHandler, bool using_dynamic_iface_combination); // Factory method - use instead of default constructor. static std::shared_ptr create( int32_t chip_id, bool is_primary, const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, const std::shared_ptr iface_util, const std::weak_ptr feature_flags, const std::function& subsystemCallbackHandler, bool using_dynamic_iface_combination); // AIDL does not provide a built-in mechanism to let the server invalidate // an AIDL interface object after creation. If any client process holds onto // a reference to the object in their context, any method calls on that // reference will continue to be directed to the server. // // However Wifi HAL needs to control the lifetime of these objects. So, add // a public |invalidate| method to |WifiChip| and its child objects. This // will be used to mark an object invalid when either: // a) Wifi HAL is stopped, or // b) Wifi Chip is reconfigured. // // All AIDL method implementations should check if the object is still // marked valid before processing them. void invalidate(); bool isValid(); std::set> getEventCallbacks(); // AIDL methods exposed. ndk::ScopedAStatus getId(int32_t* _aidl_return) override; ndk::ScopedAStatus registerEventCallback( const std::shared_ptr& in_callback) override; ndk::ScopedAStatus getFeatureSet(int32_t* _aidl_return) override; ndk::ScopedAStatus getAvailableModes(std::vector* _aidl_return) override; ndk::ScopedAStatus configureChip(int32_t in_modeId) override; ndk::ScopedAStatus getMode(int32_t* _aidl_return) override; ndk::ScopedAStatus requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) override; ndk::ScopedAStatus requestDriverDebugDump(std::vector* _aidl_return) override; ndk::ScopedAStatus requestFirmwareDebugDump(std::vector* _aidl_return) override; ndk::ScopedAStatus createApIface(std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus createBridgedApIface(std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus createApOrBridgedApIface( IfaceConcurrencyType in_ifaceType, const std::vector& in_vendorData, std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus getApIfaceNames(std::vector* _aidl_return) override; ndk::ScopedAStatus getApIface(const std::string& in_ifname, std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus removeApIface(const std::string& in_ifname) override; ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIface( const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) override; ndk::ScopedAStatus createNanIface(std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus getNanIfaceNames(std::vector* _aidl_return) override; ndk::ScopedAStatus getNanIface(const std::string& in_ifname, std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus removeNanIface(const std::string& in_ifname) override; ndk::ScopedAStatus createP2pIface(std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus getP2pIfaceNames(std::vector* _aidl_return) override; ndk::ScopedAStatus getP2pIface(const std::string& in_ifname, std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus removeP2pIface(const std::string& in_ifname) override; ndk::ScopedAStatus createStaIface(std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus getStaIfaceNames(std::vector* _aidl_return) override; ndk::ScopedAStatus getStaIface(const std::string& in_ifname, std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus removeStaIface(const std::string& in_ifname) override; ndk::ScopedAStatus createRttController( const std::shared_ptr& in_boundIface, std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus getDebugRingBuffersStatus( std::vector* _aidl_return) override; ndk::ScopedAStatus startLoggingToDebugRingBuffer( const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel, int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) override; ndk::ScopedAStatus forceDumpToDebugRingBuffer(const std::string& in_ringName) override; ndk::ScopedAStatus flushRingBufferToFile() override; ndk::ScopedAStatus stopLoggingToDebugRingBuffer() override; ndk::ScopedAStatus getDebugHostWakeReasonStats( WifiDebugHostWakeReasonStats* _aidl_return) override; ndk::ScopedAStatus enableDebugErrorAlerts(bool in_enable) override; ndk::ScopedAStatus selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) override; ndk::ScopedAStatus resetTxPowerScenario() override; ndk::ScopedAStatus setLatencyMode(IWifiChip::LatencyMode in_mode) override; ndk::ScopedAStatus setMultiStaPrimaryConnection(const std::string& in_ifName) override; ndk::ScopedAStatus setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) override; ndk::ScopedAStatus setCoexUnsafeChannels( const std::vector& in_unsafeChannels, int32_t in_restrictions) override; ndk::ScopedAStatus setCountryCode(const std::array& in_code) override; ndk::ScopedAStatus getUsableChannels(WifiBand in_band, int32_t in_ifaceModeMask, int32_t in_filterMask, std::vector* _aidl_return) override; ndk::ScopedAStatus setAfcChannelAllowance( const AfcChannelAllowance& afcChannelAllowance) override; ndk::ScopedAStatus triggerSubsystemRestart() override; ndk::ScopedAStatus getSupportedRadioCombinations( std::vector* _aidl_return) override; ndk::ScopedAStatus getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) override; ndk::ScopedAStatus enableStaChannelForPeerNetwork( int32_t in_channelCategoryEnableFlag) override; binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; ndk::ScopedAStatus setMloMode(const ChipMloMode in_mode) override; ndk::ScopedAStatus setVoipMode(const VoipMode in_mode) override; ndk::ScopedAStatus createApOrBridgedApIfaceWithParams( const ApIfaceParams& in_params, std::shared_ptr* _aidl_return) override; private: void invalidateAndRemoveAllIfaces(); // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are // invalidated & removed. void invalidateAndRemoveDependencies(const std::string& removed_iface_name); // Corresponding worker functions for the AIDL methods. std::pair getIdInternal(); ndk::ScopedAStatus registerEventCallbackInternal( const std::shared_ptr& event_callback); std::pair getFeatureSetInternal(); std::pair, ndk::ScopedAStatus> getAvailableModesInternal(); ndk::ScopedAStatus configureChipInternal(std::unique_lock* lock, int32_t mode_id); std::pair getModeInternal(); std::pair requestChipDebugInfoInternal(); std::pair, ndk::ScopedAStatus> requestDriverDebugDumpInternal(); std::pair, ndk::ScopedAStatus> requestFirmwareDebugDumpInternal(); std::shared_ptr newWifiApIface(std::string& ifname, bool usesMlo); ndk::ScopedAStatus createVirtualApInterface(const std::string& apVirtIf); std::pair, ndk::ScopedAStatus> createApIfaceInternal(); std::pair, ndk::ScopedAStatus> createBridgedApIfaceInternal( bool usesMlo); std::pair, ndk::ScopedAStatus> createApOrBridgedApIfaceInternal( IfaceConcurrencyType ifaceType, const std::vector& vendorData); std::pair, ndk::ScopedAStatus> createApOrBridgedApIfaceWithParamsInternal(const ApIfaceParams& params); std::pair, ndk::ScopedAStatus> getApIfaceNamesInternal(); std::pair, ndk::ScopedAStatus> getApIfaceInternal( const std::string& ifname); ndk::ScopedAStatus removeApIfaceInternal(const std::string& ifname); ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& brIfaceName, const std::string& ifInstanceName); std::pair, ndk::ScopedAStatus> createNanIfaceInternal(); std::pair, ndk::ScopedAStatus> getNanIfaceNamesInternal(); std::pair, ndk::ScopedAStatus> getNanIfaceInternal( const std::string& ifname); ndk::ScopedAStatus removeNanIfaceInternal(const std::string& ifname); std::pair, ndk::ScopedAStatus> createP2pIfaceInternal(); std::pair, ndk::ScopedAStatus> getP2pIfaceNamesInternal(); std::pair, ndk::ScopedAStatus> getP2pIfaceInternal( const std::string& ifname); ndk::ScopedAStatus removeP2pIfaceInternal(const std::string& ifname); std::pair, ndk::ScopedAStatus> createStaIfaceInternal(); std::pair, ndk::ScopedAStatus> getStaIfaceNamesInternal(); std::pair, ndk::ScopedAStatus> getStaIfaceInternal( const std::string& ifname); ndk::ScopedAStatus removeStaIfaceInternal(const std::string& ifname); std::pair, ndk::ScopedAStatus> createRttControllerInternal( const std::shared_ptr& bound_iface); std::pair, ndk::ScopedAStatus> getDebugRingBuffersStatusInternal(); ndk::ScopedAStatus startLoggingToDebugRingBufferInternal( const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes); ndk::ScopedAStatus forceDumpToDebugRingBufferInternal(const std::string& ring_name); ndk::ScopedAStatus flushRingBufferToFileInternal(); ndk::ScopedAStatus stopLoggingToDebugRingBufferInternal(); std::pair getDebugHostWakeReasonStatsInternal(); ndk::ScopedAStatus enableDebugErrorAlertsInternal(bool enable); ndk::ScopedAStatus selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario); ndk::ScopedAStatus resetTxPowerScenarioInternal(); ndk::ScopedAStatus setLatencyModeInternal(IWifiChip::LatencyMode mode); ndk::ScopedAStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname); ndk::ScopedAStatus setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case); ndk::ScopedAStatus setCoexUnsafeChannelsInternal( std::vector unsafe_channels, int32_t restrictions); ndk::ScopedAStatus setCountryCodeInternal(const std::array& in_code); std::pair, ndk::ScopedAStatus> getUsableChannelsInternal( WifiBand band, int32_t ifaceModeMask, int32_t filterMask); ndk::ScopedAStatus enableStaChannelForPeerNetworkInternal(int32_t channelCategoryEnableFlag); ndk::ScopedAStatus setAfcChannelAllowanceInternal( const AfcChannelAllowance& afcChannelAllowance); ndk::ScopedAStatus handleChipConfiguration(std::unique_lock* lock, int32_t mode_id); ndk::ScopedAStatus registerDebugRingBufferCallback(); ndk::ScopedAStatus registerRadioModeChangeCallback(); std::vector getCurrentModeConcurrencyCombinations(); std::map getCurrentConcurrencyCombination(); std::vector> expandConcurrencyCombinations( const ChipConcurrencyCombination& combination); bool canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes( const std::map& expanded_combo, IfaceConcurrencyType requested_type); bool canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type); bool canExpandedConcurrencyComboSupportConcurrencyCombo( const std::map& expanded_combo, const std::map& req_combo); bool canCurrentModeSupportConcurrencyCombo( const std::map& req_combo); bool canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type); bool isValidModeId(int32_t mode_id); bool isStaApConcurrencyAllowedInCurrentMode(); bool isDualStaConcurrencyAllowedInCurrentMode(); uint32_t startIdxOfApIface(); std::string getFirstActiveWlanIfaceName(); std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx); std::string allocateApIfaceName(); std::vector allocateBridgedApInstanceNames(bool usesMlo); std::string allocateStaIfaceName(); bool writeRingbufferFilesInternal(); std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx); void invalidateAndClearBridgedApAll(); void deleteApIface(const std::string& if_name); bool findUsingNameFromBridgedApInstances(const std::string& name); ndk::ScopedAStatus triggerSubsystemRestartInternal(); std::pair, ndk::ScopedAStatus> getSupportedRadioCombinationsInternal(); std::pair getWifiChipCapabilitiesInternal(); ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode); ndk::ScopedAStatus setVoipModeInternal(const VoipMode in_mode); void retrieveDynamicIfaceCombination(); void setWeakPtr(std::weak_ptr ptr); int32_t chip_id_; std::weak_ptr legacy_hal_; std::weak_ptr mode_controller_; std::shared_ptr iface_util_; std::vector> ap_ifaces_; std::vector> nan_ifaces_; std::vector> p2p_ifaces_; std::vector> sta_ifaces_; std::vector> rtt_controllers_; std::map ringbuffer_map_; bool is_valid_; // Members pertaining to chip configuration. int32_t current_mode_id_; std::mutex lock_t; std::vector modes_; // The legacy ring buffer callback API has only a global callback // registration mechanism. Use this to check if we have already // registered a callback. bool debug_ring_buffer_cb_registered_; bool using_dynamic_iface_combination_; aidl_callback_util::AidlCallbackHandler event_cb_handler_; std::weak_ptr weak_ptr_this_; const std::function subsystemCallbackHandler_; std::map> br_ifaces_ap_instances_; DISALLOW_COPY_AND_ASSIGN(WifiChip); }; } // namespace wifi } // namespace hardware } // namespace android } // namespace aidl #endif // WIFI_CHIP_H_