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 #ifndef CHRE_PLATFORM_LINUX_PAL_NAN_H_
18 #define CHRE_PLATFORM_LINUX_PAL_NAN_H_
19 
20 #include <unordered_set>
21 #include "chre/pal/wifi.h"
22 #include "chre/platform/assert.h"
23 #include "chre/util/memory.h"
24 #include "chre/util/non_copyable.h"
25 #include "chre/util/singleton.h"
26 #include "chre_api/chre/wifi.h"
27 
28 namespace chre {
29 
30 /**
31  * @brief Fake NAN engine to verify core NAN functionality.
32  *
33  * This class implements a fake NAN engine to verify core functionality, with
34  * functionality limited to creating (meaningless) subscription and publisher
35  * IDs, along with creating and destroying discovery events.
36  *
37  * This class is intended to be used for simulation tests only.
38  */
39 
40 class PalNanEngine : public NonCopyable {
41  public:
42   /**
43    * Flags that instruct the engine to fail operations for testing. Note
44    * that they must be set before calling any APIs in this class. The flags
45    * also are not reset upon exiting an API call - it is the responsibility
46    * of the entity setting the flags to do this.
47    */
48   enum Flags : uint32_t {
49     NONE = 0,
50     FAIL_SUBSCRIBE = (0x1 << 0),
51   };
52 
53   /**
54    * Obtain a subscription ID.
55    *
56    * This method returns a subscription ID to the caller by reference,
57    * implemented by a simple up-counter.
58    *
59    * The method will succeed unless @ref SetFlags as been called aith the value
60    * FAIL_SUBSCRIBE to simulater a failure.
61    *
62    * @param config The Nan service subscription config, currently unused.
63    * @param subscriptionId populated with the next value of a running counter.
64    * @return an error code that is a value in @ref enum chreError
65    */
66   uint8_t subscribe(const struct chreWifiNanSubscribeConfig *config,
67                     uint32_t *subscriptionId);
68 
69   /**
70    * Cancels an active subscription.
71    *
72    * @return whether the subscription is successfully cancelled - that is if
73    *          a subscription with the passed id is currently active.
74    */
75   bool subscribeCancel(uint32_t subscriptionId);
76 
77   /**
78    * Returns whether a subscription is active.
79    *
80    * @return whether the subscription is active.
81    */
82   bool isSubscriptionActive(uint32_t subscriptionId);
83 
84   /**
85    * Send a service discovery event.
86    *
87    * Sends a discovery event with the passed in subscription ID, a
88    * publisher ID implemented by a simple down-counter, a static MAC address
89    * for the publisher, and un-filled (but not NULL) service specific info.
90    *
91    * @param subscriptionId The ID of the subscriber to simulate a discovery
92    *        for.
93    */
94   void sendDiscoveryEvent(uint32_t subscriptionId);
95 
96   /**
97    * Destroy a discovery event object created by @ref createDiscoveryEvent.
98    *
99    * @param event The NAN discovery event that was created by
100    *        createDiscoveryEvent.
101    */
102   void destroyDiscoveryEvent(chreWifiNanDiscoveryEvent *event);
103 
104   /**
105    * Triggered from the test framework to simulate the loss of a publishing
106    * service.
107    *
108    * @param subscribeId Id of the subscribing service.
109    * @param publishId Id of the service that has been lost.
110    */
111   void onServiceLost(uint32_t subscribeId, uint32_t publishId);
112 
113   /**
114    * Triggered from the test framework to simulate a subscription termination.
115    *
116    * @param subscribeId Id of the subscribing service that has been terminated.
117    */
118   void onServiceTerminated(uint32_t subscribeId);
119 
120   /**
121    * Set the Platform Wifi Callbacks object
122    *
123    * Maintain a copy of the Pal WiFi callbacks here: this is particularly
124    * useful for triggering events that are designed to be asynchronous (like
125    * discovery events) synchronously from the test/simulation framework.
126    *
127    * @param api Pointer to the Pal WiFi callbacks structure.
128    */
setPlatformWifiCallbacks(const struct chrePalWifiCallbacks * api)129   void setPlatformWifiCallbacks(const struct chrePalWifiCallbacks *api) {
130     mWifiCallbacks = api;
131   }
132 
133   /**
134    * Set flags from the test framework to instruct the engine to take
135    * appropriate actions. Flags must be a value in @ref enum Flags, and
136    * multiple flags can be specified at once. Note that it is the
137    * responsibility of the test framework to reset the flags by calling
138    * the function again with Flags::NONE.
139    *
140    * @param flags Flags to be set.
141    */
setFlags(uint32_t flags)142   void setFlags(uint32_t flags) {
143     mFlags = flags;
144   }
145 
146  private:
147   static constexpr uint8_t kSomePublishMac[CHRE_WIFI_BSSID_LEN] = {
148       0x1, 0x2, 0x3, 0x4, 0x5, 0x6};
149   uint32_t mSubscriptionIdCounter = 1;
150   uint32_t mPublisherIdCounter = 0xcafe;
151   uint32_t mFlags;
152   std::unordered_set<uint32_t> mActiveSubscriptions;
153 
154   const struct chrePalWifiCallbacks *mWifiCallbacks = nullptr;
155 };
156 
157 //! Provide an alias to the PalNanEngine singleton.
158 typedef Singleton<PalNanEngine> PalNanEngineSingleton;
159 
160 }  // namespace chre
161 
162 #endif  // CHRE_PLATFORM_LINUX_PAL_NAN_H_