1 // 2 // Copyright (C) 2014 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 #ifndef SHILL_WIFI_MAC80211_MONITOR_H_ 18 #define SHILL_WIFI_MAC80211_MONITOR_H_ 19 20 #include <time.h> 21 22 #include <string> 23 #include <vector> 24 25 #include <base/callback.h> 26 #include <base/cancelable_callback.h> 27 #include <base/files/file_path.h> 28 #include <base/macros.h> 29 #include <base/memory/weak_ptr.h> 30 #include <gtest/gtest_prod.h> // for FRIEND_TEST 31 32 namespace shill { 33 34 class EventDispatcher; 35 class Metrics; 36 class Time; 37 38 class Mac80211Monitor { 39 public: 40 struct QueueState { QueueStateQueueState41 QueueState(size_t queue_number_in, 42 uint32_t stop_flags_in, 43 size_t queue_length_in) 44 : queue_number(queue_number_in), stop_flags(stop_flags_in), 45 queue_length(queue_length_in) {} 46 47 size_t queue_number; 48 uint32_t stop_flags; 49 size_t queue_length; 50 }; 51 52 Mac80211Monitor(EventDispatcher* dispatcher, 53 const std::string& link_name, 54 size_t queue_length_limit, 55 const base::Closure& on_repair_callback, 56 Metrics* metrics); 57 virtual ~Mac80211Monitor(); 58 59 virtual void Start(const std::string& phy_name); 60 virtual void Stop(); 61 virtual void UpdateConnectedState(bool new_state); 62 link_name()63 const std::string& link_name() const { return link_name_; } 64 65 private: 66 friend class Mac80211MonitorTest; 67 FRIEND_TEST(Mac80211MonitorTest, CheckAreQueuesStuckMultipleReasons); 68 FRIEND_TEST(Mac80211MonitorTest, CheckAreQueuesStuckMultipleQueues); 69 FRIEND_TEST(Mac80211MonitorTest, CheckAreQueuesStuckNotStuck); 70 FRIEND_TEST(Mac80211MonitorTest, CheckAreQueuesStuckQueueLength); 71 FRIEND_TEST(Mac80211MonitorTest, 72 CheckAreQueuesStuckQueueLengthIgnoresUnstopped); 73 FRIEND_TEST(Mac80211MonitorTest, CheckAreQueuesStuckSingleReason); 74 FRIEND_TEST(Mac80211MonitorTest, ParseQueueStateBadInput); 75 FRIEND_TEST(Mac80211MonitorTest, ParseQueueStateSimple); 76 FRIEND_TEST(Mac80211MonitorTest, ParseQueueStateStopped); 77 78 static const size_t kMaxQueueStateSizeBytes; 79 static const char kQueueStatusPathFormat[]; 80 static const char kWakeQueuesPathFormat[]; 81 static const time_t kQueueStatePollIntervalSeconds; 82 static const time_t kMinimumTimeBetweenWakesSeconds; 83 84 // Values must be kept in sync with ieee80211_i.h. 85 enum QueueStopReason { 86 kStopReasonDriver, 87 kStopReasonPowerSave, 88 kStopReasonChannelSwitch, 89 kStopReasonAggregation, 90 kStopReasonSuspend, 91 kStopReasonBufferAdd, 92 kStopReasonChannelTypeChange, 93 kStopReasonMax = kStopReasonChannelTypeChange 94 }; 95 enum QueueStopFlag { 96 kStopFlagDriver = 1 << kStopReasonDriver, 97 kStopFlagPowerSave = 1 << kStopReasonPowerSave, 98 kStopFlagChannelSwitch = 1 << kStopReasonChannelSwitch, 99 kStopFlagAggregation = 1 << kStopReasonAggregation, 100 kStopFlagSuspend = 1 << kStopReasonSuspend, 101 kStopFlagBufferAdd = 1 << kStopReasonBufferAdd, 102 kStopFlagChannelTypeChange = 1 << kStopReasonChannelTypeChange, 103 kStopFlagInvalid 104 }; 105 106 void StartTimer(); 107 void StopTimer(); 108 109 // Check if queues need to be woken. If so, and we haven't woken them 110 // too recently, then wake them now. 111 void WakeQueuesIfNeeded(); 112 113 // Check |queue_states|, to determine if any queues are stuck. 114 // Returns a bitmask of QueueStopFlags. A flag will be set if 115 // any of the queues has that flag set, and is non-empty. 116 // A return value if 0 indicates no queues are stuck. 117 uint32_t CheckAreQueuesStuck(const std::vector<QueueState>& queue_states); 118 119 static std::vector<QueueState> ParseQueueState( 120 const std::string& state_string); 121 static QueueStopFlag GetFlagForReason(QueueStopReason reason); 122 123 Time* time_; // for mocking in tests 124 EventDispatcher* dispatcher_; 125 const std::string link_name_; 126 size_t queue_length_limit_; 127 base::Closure on_repair_callback_; 128 Metrics* metrics_; 129 std::string phy_name_; 130 time_t last_woke_queues_monotonic_seconds_; 131 bool is_running_; 132 bool have_ever_read_queue_state_file_; 133 base::FilePath queue_state_file_path_; 134 base::FilePath wake_queues_file_path_; 135 base::CancelableClosure check_queues_callback_; 136 bool is_device_connected_; 137 base::WeakPtrFactory<Mac80211Monitor> weak_ptr_factory_; // keep last 138 139 DISALLOW_COPY_AND_ASSIGN(Mac80211Monitor); 140 }; 141 142 } // namespace shill 143 144 #endif // SHILL_WIFI_MAC80211_MONITOR_H_ 145