• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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_CORE_WIFI_REQUEST_MANAGER_H_
18 #define CHRE_CORE_WIFI_REQUEST_MANAGER_H_
19 
20 #include "chre/core/nanoapp.h"
21 #include "chre/platform/platform_wifi.h"
22 #include "chre/util/non_copyable.h"
23 
24 namespace chre {
25 
26 /**
27  * The WifiRequestManager handles requests from nanoapps for Wifi information.
28  * This includes multiplexing multiple requests into one for the platform to
29  * handle.
30  *
31  * This class is effectively a singleton as there can only be one instance of
32  * the PlatformWifi instance.
33  */
34 class WifiRequestManager : public NonCopyable {
35  public:
36    /**
37     * Initializes the WifiRequestManager with a default state and memory for any
38     * requests.
39     */
40   WifiRequestManager();
41 
42   /**
43    * @return the WiFi capabilities exposed by this platform.
44    */
45   uint32_t getCapabilities();
46 
47   /**
48    * Handles a request from a nanoapp to configure the scan monitor. This
49    * includes merging multiple requests for scan monitoring to the PAL (ie: if
50    * multiple apps enable the scan monitor the PAL is only enabled once).
51    *
52    * @param nanoapp The nanoapp that has requested that the scan monitor be
53    *        configured.
54    * @param enable true to enable scan monitoring, false to disable scan
55    *        monitoring.
56    * @param cookie A cookie that is round-tripped back to the nanoapp to
57    *        provide a context when making the request.
58    * @return true if the request was accepted. The result is delivered
59    *         asynchronously through a CHRE event.
60    */
61   bool configureScanMonitor(Nanoapp *nanoapp, bool enable, const void *cookie);
62 
63   /**
64    * Performs an active wifi scan.
65    *
66    * This is currently a 1:1 mapping into the PAL. If more than one nanoapp
67    * requests an active wifi scan, this will be an assertion failure for debug
68    * builds and a no-op in production (ie: subsequent requests are ignored).
69    *
70    * @param nanoapp The nanoapp that has requested an active wifi scan.
71    * @param params The parameters of the wifi scan.
72    * @param cookie A cookie that is round-tripped back to the nanoapp to provide
73    *        a context when making the request.
74    * @return true if the request was accepted. The result is delivered
75    *         asynchronously through a CHRE event.
76    */
77   bool requestScan(Nanoapp *nanoapp, const chreWifiScanParams *params,
78                    const void *cookie);
79 
80   /**
81    * Handles the result of a request to PlatformWifi to change the state of the
82    * scan monitor.
83    *
84    * @param enabled true if the result of the operation was an enabled scan
85    *        monitor.
86    * @param errorCode an error code that is provided to indicate success or what
87    *        type of error has occurred. See the chreError enum in the CHRE API
88    *        for additional details.
89    */
90   void handleScanMonitorStateChange(bool enabled, uint8_t errorCode);
91 
92   /**
93    * Handles the result of a request to the PlatformWifi to request an active
94    * Wifi scan.
95    *
96    * @param pending The result of the request was successful and the results
97    *        be sent via the handleScanEvent method.
98    * @param errorCode an error code that is used to indicate success or what
99    *        type of error has occurred. See the chreError enum in the CHRE API
100    *        for additional details.
101    */
102   void handleScanResponse(bool pending, uint8_t errorCode);
103 
104   /**
105    * Handles a CHRE wifi scan event.
106    *
107    * @param event The wifi scan event provided to the wifi request manager. This
108    *        memory is guaranteed not to be modified until it has been explicitly
109    *        released through the PlatformWifi instance.
110    */
111   void handleScanEvent(chreWifiScanEvent *event);
112 
113  private:
114   /**
115    * Tracks the state of the wifi scan monitor.
116    */
117   struct ScanMonitorStateTransition {
118     //! The nanoapp instance ID that prompted the change.
119     uint32_t nanoappInstanceId;
120 
121     //! The cookie provided to the CHRE API when the nanoapp requested a change
122     //! of state to the scan monitoring.
123     const void *cookie;
124 
125     //! The target state of the PAL scan monitor.
126     bool enable;
127   };
128 
129   //! The maximum number of scan monitor state transitions that can be queued.
130   static constexpr size_t kMaxScanMonitorStateTransitions = 8;
131 
132   //! The instance of the platform wifi interface.
133   PlatformWifi mPlatformWifi;
134 
135   //! The queue of state transition requests for the scan monitor. Only one
136   //! asynchronous scan monitor state transition can be in flight at one time.
137   //! Any further requests are queued here.
138   ArrayQueue<ScanMonitorStateTransition,
139              kMaxScanMonitorStateTransitions> mScanMonitorStateTransitions;
140 
141   //! The list of nanoapps who have enabled scan monitoring. This list is
142   //! maintained to ensure that nanoapps are always subscribed to wifi scan
143   //! results as requested. Note that a request for wifi scan monitoring can
144   //! exceed the duration of a single active wifi scan request. This makes it
145   //! insuitable only subscribe to wifi scan events when an active request is
146   //! made and the scan monitor must remain enabled when an active request has
147   //! completed.
148   DynamicVector<uint32_t> mScanMonitorNanoapps;
149 
150   // TODO: Support multiple requests for active wifi scans.
151   //! The instance ID of the nanoapp that has a pending active scan request. At
152   //! this time, only one nanoapp can have a pending request for an active WiFi
153   //! scan.
154   Optional<uint32_t> mScanRequestingNanoappInstanceId;
155 
156   //! The cookie passed in by a nanoapp making an active request for wifi scans.
157   //! Note that this will only be valid if the mScanRequestingNanoappInstanceId
158   //! is set.
159   const void *mScanRequestingNanoappCookie;
160 
161   //! This is set to true if the results of an active scan request are pending.
162   bool mScanRequestResultsArePending = false;
163 
164   //! Accumulates the number of scan event results to determine when the last
165   //! in a scan event stream has been received.
166   uint8_t mScanEventResultCountAccumulator = 0;
167 
168   /**
169    * @return true if the scan monitor is enabled by any nanoapps.
170    */
171   bool scanMonitorIsEnabled() const;
172 
173   /**
174    * @param instanceId the instance ID of the nanoapp.
175    * @param index an optional pointer to a size_t to populate with the index of
176    *        the nanoapp in the list of nanoapps.
177    * @return true if the nanoapp has an active request for scan monitoring.
178    */
179   bool nanoappHasScanMonitorRequest(uint32_t instanceId,
180                                     size_t *index = nullptr) const;
181 
182   /**
183    * @param requestedState The requested state to compare against.
184    * @param nanoappHasRequest The requesting nanoapp has an existing request.
185    * @return true if the scan monitor is in the requested state.
186    */
187   bool scanMonitorIsInRequestedState(bool requestedState,
188                                      bool nanoappHasRequest) const;
189 
190   /**
191    * @param requestedState The requested state to compare against.
192    * @param nanoappHasRequest The requesting nanoapp has an existing request.
193    * @return true if a state transition is required to reach the requested
194    * state.
195    */
196   bool scanMonitorStateTransitionIsRequired(bool requestedState,
197                                             bool nanoappHasRequest) const;
198 
199   /**
200    * Builds a scan monitor state transition and adds it to the queue of incoming
201    * requests.
202    * @param nanoapp A non-null pointer to a nanoapp that is requesting the
203    *        change.
204    * @param enable The target requested scan monitoring state.
205    * @param cookie The pointer cookie passed in by the calling nanoapp to return
206    *        to the nanoapp when the request completes.
207    * @return true if the request is enqueued or false if the queue is full.
208    */
209   bool addScanMonitorRequestToQueue(Nanoapp *nanoapp, bool enable,
210                                     const void *cookie);
211 
212   /**
213    * Adds a nanoapp to the list of nanoapps that are monitoring for wifi scans.
214    * @param enable true if enabling scan monitoring.
215    * @param instanceId The instance ID of the scan monitoring nanoapp.
216    * @return true if the nanoapp was added to the list.
217    */
218   bool updateNanoappScanMonitoringList(bool enable, uint32_t instanceId);
219 
220   /**
221    * Posts an event to a nanoapp indicating the result of a wifi scan monitoring
222    * configuration change.
223    *
224    * @param nanoappInstanceId The nanoapp instance ID to direct the event to.
225    * @param success If the request for a wifi resource was successful.
226    * @param enable The target state of the request. If enable is set to false
227    *        and the request was successful, the nanoapp is removed from the
228    *        list of nanoapps requesting scan monitoring.
229    * @param errorCode The error code when success is set to false.
230    * @param cookie The cookie to be provided to the nanoapp. This is
231    *        round-tripped from the nanoapp to provide context.
232    * @return true if the event was successfully posted to the event loop.
233    */
234   bool postScanMonitorAsyncResultEvent(
235       uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode,
236       const void *cookie);
237 
238   /**
239    * Calls through to postScanMonitorAsyncResultEvent but invokes the
240    * FATAL_ERROR macro if the event is not posted successfully. This is used in
241    * asynchronous contexts where a nanoapp could be stuck waiting for a response
242    * but CHRE failed to enqueue one. For parameter details,
243    * @see postScanMonitorAsyncResultEvent
244    */
245   void postScanMonitorAsyncResultEventFatal(
246       uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode,
247       const void *cookie);
248 
249   /**
250    * Posts an event to a nanoapp indicating the result of a request for an
251    * active wifi scan.
252    *
253    * @param nanoappInstanceId The nanoapp instance ID to direct the event to.
254    * @param success If the request for a wifi resource was successful.
255    * @param errorCode The error code when success is set to false.
256    * @param cookie The cookie to be provided to the nanoapp. This is
257    *        round-tripped from the nanoapp to provide context.
258    * @return true if the event was successfully posted to the event loop.
259    */
260   bool postScanRequestAsyncResultEvent(
261       uint32_t nanoappInstanceId, bool success, uint8_t errorCode,
262       const void *cookie);
263 
264   /**
265    * Calls through to postScanRequestAsyncResultEvent but invokes the
266    * FATAL_ERROR macro if the event is not posted successfully. This is used in
267    * asynchronous contexts where a nanoapp could be stuck waiting for a response
268    * but CHRE failed to enqueue one. For parameter details,
269    * @see postScanRequestAsyncResultEvent
270    */
271   void postScanRequestAsyncResultEventFatal(
272       uint32_t nanoappInstanceId, bool success, uint8_t errorCode,
273       const void *cookie);
274 
275   /**
276    * Posts a broadcast event containing the results of a wifi scan. Failure to
277    * post this event is a FATAL_ERROR. This is unrecoverable as the nanoapp will
278    * be stuck waiting for wifi scan results but there may be a gap.
279    *
280    * @param event the wifi scan event.
281    */
282   void postScanEventFatal(chreWifiScanEvent *event);
283 
284   /**
285    * Handles the result of a request to PlatformWifi to change the state of the
286    * scan monitor. See the handleScanMonitorStateChange method which may be
287    * called from any thread. This method is intended to be invoked on the CHRE
288    * event loop thread.
289    *
290    * @param enabled true if the result of the operation was an enabled scan
291    *        monitor.
292    * @param errorCode an error code that is provided to indicate success or what
293    *        type of error has occurred. See the chreError enum in the CHRE API
294    *        for additional details.
295    */
296   void handleScanMonitorStateChangeSync(bool enabled, uint8_t errorCode);
297 
298   /**
299    * Handles the result of a request to PlatformWifi to perform an active WiFi
300    * scan. See the handleScanResponse method which may be called from any
301    * thread. This method is intended to be invoked on the CHRE event loop
302    * thread.
303    *
304    * @param enabled true if the result of the operation was an enabled scan
305    *        monitor.
306    * @param errorCode an error code that is provided to indicate success or what
307    *        type of error has occurred. See the chreError enum in the CHRE API
308    *        for additional details.
309    */
310   void handleScanResponseSync(bool pending, uint8_t errorCode);
311 
312   /**
313    * Handles a WiFi scan event. See the handleScanEvent method with may be
314    * called from any thread. This method is intended to be invoked on the CHRE
315    * event loop thread.
316    *
317    * @param event The wifi event to distribute to nanoapps.
318    */
319   void handleScanEventSync(chreWifiScanEvent *event);
320 
321   /**
322    * TODO: this.
323    */
324   void handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent);
325 
326   /**
327    * Releases the memory associated with an asynchronous wifi event.
328    *
329    * @param eventType The type of event being freed.
330    * @param eventData A pointer to the data to release.
331    */
332   static void freeWifiAsyncResultCallback(uint16_t eventType, void *eventData);
333 
334   /**
335    * Releases a wifi scan event after nanoapps have consumed it.
336    *
337    * @param eventType the type of event being freed.
338    * @param eventData a pointer to the scan event to release.
339    */
340   static void freeWifiScanEventCallback(uint16_t eventType, void *eventData);
341 };
342 
343 }  // namespace chre
344 
345 #endif  // CHRE_CORE_WIFI_REQUEST_MANAGER_H_
346