1 //
2 // Copyright (C) 2013 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_CELLULAR_ACTIVE_PASSIVE_OUT_OF_CREDITS_DETECTOR_H_
18 #define SHILL_CELLULAR_ACTIVE_PASSIVE_OUT_OF_CREDITS_DETECTOR_H_
19 
20 #include <memory>
21 #include <string>
22 
23 #include <base/time/time.h>
24 
25 #include "shill/cellular/out_of_credits_detector.h"
26 #include "shill/connection_health_checker.h"
27 
28 namespace shill {
29 
30 // Detects out-of-credits condition by monitoring for the following scenarios:
31 //   - Passively watch for network congestion and launch active probes to
32 //     determine if the network has stopped routing traffic.
33 //   - Watch for connect/disconnect loop.
34 class ActivePassiveOutOfCreditsDetector : public OutOfCreditsDetector {
35  public:
36   ActivePassiveOutOfCreditsDetector(EventDispatcher* dispatcher,
37                                     Manager* manager,
38                                     Metrics* metrics,
39                                     CellularService* service);
40   ~ActivePassiveOutOfCreditsDetector() override;
41 
42   void ResetDetector() override;
43   bool IsDetecting() const override;
44   void NotifyServiceStateChanged(
45       Service::ConnectState old_state,
46       Service::ConnectState new_state) override;
NotifySubscriptionStateChanged(uint32_t subscription_state)47   void NotifySubscriptionStateChanged(uint32_t subscription_state) override {}
48 
traffic_monitor()49   const TrafficMonitor* traffic_monitor() const {
50     return traffic_monitor_.get();
51   }
52 
GetServiceRpcIdentifier()53   const std::string& GetServiceRpcIdentifier() const {
54     return service_rpc_identifier_;
55   }
56 
57  private:
58   friend class ActivePassiveOutOfCreditsDetectorTest;
59   FRIEND_TEST(ActivePassiveOutOfCreditsDetectorTest,
60       ConnectDisconnectLoopDetectionIntermittentNetwork);
61   FRIEND_TEST(ActivePassiveOutOfCreditsDetectorTest,
62       ConnectDisconnectLoopDetectionNotSkippedAfterSlowResume);
63   FRIEND_TEST(ActivePassiveOutOfCreditsDetectorTest,
64       OnConnectionHealthCheckerResult);
65   FRIEND_TEST(ActivePassiveOutOfCreditsDetectorTest, OnNoNetworkRouting);
66   FRIEND_TEST(ActivePassiveOutOfCreditsDetectorTest, StopTrafficMonitor);
67 
68   static const int64_t kOutOfCreditsConnectionDropSeconds;
69   static const int kOutOfCreditsMaxConnectAttempts;
70   static const int64_t kOutOfCreditsResumeIgnoreSeconds;
71 
72   // Initiates traffic monitoring.
73   bool StartTrafficMonitor();
74 
75   // Stops traffic monitoring.
76   void StopTrafficMonitor();
77 
78   // Responds to a TrafficMonitor no-network-routing failure.
79   void OnNoNetworkRouting(int reason);
80 
81   // Initializes and configures the connection health checker.
82   void SetupConnectionHealthChecker();
83 
84   // Checks the network connectivity status by creating a TCP connection, and
85   // optionally sending a small amout of data.
86   void RequestConnectionHealthCheck();
87 
88   // Responds to the result from connection health checker in a device specific
89   // manner.
90   void OnConnectionHealthCheckerResult(ConnectionHealthChecker::Result result);
91 
92   // Performs out-of-credits detection by checking to see if we're stuck in a
93   // connect/disconnect loop.
94   void DetectConnectDisconnectLoop(Service::ConnectState curr_state,
95                                    Service::ConnectState new_state);
96   // Reconnects to the cellular service in the context of out-of-credits
97   // detection.
98   void OutOfCreditsReconnect();
99 
100   // Ownership of |traffic_monitor| is taken.
101   void set_traffic_monitor(TrafficMonitor* traffic_monitor);
102 
103   // Ownership of |healther_checker| is taken.
104   void set_connection_health_checker(ConnectionHealthChecker* health_checker);
105 
106   base::WeakPtrFactory<ActivePassiveOutOfCreditsDetector> weak_ptr_factory_;
107 
108   // Passively monitors network traffic for network failures.
109   std::unique_ptr<TrafficMonitor> traffic_monitor_;
110   // Determine network health through active probes.
111   std::unique_ptr<ConnectionHealthChecker> health_checker_;
112 
113   // The following members are used by the connect/disconnect loop detection.
114   // Time when the last connect request started.
115   base::Time connect_start_time_;
116   // Number of connect attempts.
117   int num_connect_attempts_;
118   // Flag indicating whether out-of-credits detection is in progress.
119   bool out_of_credits_detection_in_progress_;
120 
121   // String to hold service identifier for scoped logging.
122   std::string service_rpc_identifier_;
123 
124   DISALLOW_COPY_AND_ASSIGN(ActivePassiveOutOfCreditsDetector);
125 };
126 
127 }  // namespace shill
128 
129 #endif  // SHILL_CELLULAR_ACTIVE_PASSIVE_OUT_OF_CREDITS_DETECTOR_H_
130