• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 <atomic>
18 #include <chrono>
19 #include <condition_variable>
20 #include <cstdint>
21 #include <deque>
22 #include <mutex>
23 #include <vector>
24 
25 #include <android-base/thread_annotations.h>
26 
27 #include "chpp/log.h"
28 #include "chpp/transport.h"
29 
30 using ::std::literals::chrono_literals::operator""ms;
31 
32 namespace chpp::test {
33 
34 /**
35  * Wrapper for a fake CHPP link layer which puts outgoing packets on a queue
36  * where they can be extracted and inspected.
37  */
38 class FakeLink {
39  public:
40   //! How long CHPP is expected to wait on an ACK for a transmitted packet
41   static constexpr auto kTransportTimeout =
42       std::chrono::duration_cast<std::chrono::milliseconds>(
43           std::chrono::nanoseconds(CHPP_TRANSPORT_TX_TIMEOUT_NS));
44 
45   // Our default timeout covers the retry timeout, plus some extra buffer to
46   // account for processing delays
47   static constexpr auto kDefaultTimeout = 10 * (kTransportTimeout + 5ms);
48 
49   /**
50    * Call from link send. Makes a copy of the provided buffer and
51    * appends it to the TX packet queue.
52    */
53   void appendTxPacket(uint8_t *data, size_t len);
54 
55   //! Returns the number of TX packets waiting to be popped
56   int getTxPacketCount();  // int to make EXPECT_EQ against a literal simpler
57                            // with -Wsign-compare enabled
58 
59   /**
60    * Wait up to the provided timeout for a packet to hit the TX queue, or return
61    * immediately if a packet is already waiting to be popped.
62    *
63    * @return true if a packet is waiting, false on timeout
64    */
65   bool waitForTxPacket(std::chrono::milliseconds timeout = kDefaultTimeout);
66 
67   /**
68    * Similar to waitForTxPacket, but the inverse (waits until the queue is
69    * empty).
70    */
71   bool waitForEmpty(std::chrono::milliseconds timeout = kDefaultTimeout);
72 
73   //! Pop and return the oldest packet on the TX queue, or assert if queue is
74   //! empty
75   std::vector<uint8_t> popTxPacket();
76 
77   //! Empties the TX packet queue
78   void reset();
79 
isEnabled()80   bool isEnabled() const {
81     return mEnabled.load();
82   }
83 
disable()84   void disable() {
85     CHPP_LOGI("Link disabled");
86     mEnabled.store(false);
87   }
88 
enable()89   void enable() {
90     CHPP_LOGI("Link enabled");
91     mEnabled.store(true);
92   }
93 
94  private:
95   std::mutex mMutex;
96   std::condition_variable mTxCondVar;
97   std::condition_variable mRxCondVar;
98   std::deque<std::vector<uint8_t>> mTxPackets GUARDED_BY(mMutex);
99 
100   std::atomic_bool mEnabled{true};
101 };
102 
103 }  // namespace chpp::test