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/api_manager_common.h"
21 #include "chre/core/nanoapp.h"
22 #include "chre/core/settings.h"
23 #include "chre/core/timer_pool.h"
24 #include "chre/platform/platform_wifi.h"
25 #include "chre/util/buffer.h"
26 #include "chre/util/non_copyable.h"
27 #include "chre/util/optional.h"
28 #include "chre/util/system/debug_dump.h"
29 #include "chre/util/time.h"
30 #include "chre_api/chre/wifi.h"
31 
32 namespace chre {
33 
34 /**
35  * The WifiRequestManager handles requests from nanoapps for Wifi information.
36  * This includes multiplexing multiple requests into one for the platform to
37  * handle.
38  *
39  * This class is effectively a singleton as there can only be one instance of
40  * the PlatformWifi instance.
41  */
42 class WifiRequestManager : public NonCopyable {
43  public:
44   /**
45    * Specifies what type of ranging request is being issued.
46    *
47    * WIFI_AP denotes a ranging request to a (list of) device(s) via an access
48    * point. WIFI_AWARE denotes  a NAN ranging request to a single peer NAN
49    * device. Even though the abbreviation 'NAN' is used throughout the CHRE
50    * WiFi code and documentation, the simplified enumerator NAN is avoided here
51    * to prevent possible symbol/identifier clashes to a NAN (not-a-number)
52    * defines in clang and GCC's math header.
53    */
54   enum class RangingType { WIFI_AP, WIFI_AWARE };
55 
56   /**
57    * Initializes the WifiRequestManager with a default state and memory for any
58    * requests.
59    */
60   WifiRequestManager();
61 
62   /**
63    * Initializes the underlying platform-specific WiFi module. Must be called
64    * prior to invoking any other methods in this class.
65    */
66   void init();
67 
68   /**
69    * @return the WiFi capabilities exposed by this platform.
70    */
71   uint32_t getCapabilities();
72 
73   /**
74    * Handles a request from a nanoapp to configure the scan monitor. This
75    * includes merging multiple requests for scan monitoring to the PAL (ie: if
76    * multiple apps enable the scan monitor the PAL is only enabled once).
77    *
78    * @param nanoapp The nanoapp that has requested that the scan monitor be
79    *        configured.
80    * @param enable true to enable scan monitoring, false to disable scan
81    *        monitoring.
82    * @param cookie A cookie that is round-tripped back to the nanoapp to
83    *        provide a context when making the request.
84    *
85    * @return true if the request was accepted. The result is delivered
86    *         asynchronously through a CHRE event.
87    */
88   bool configureScanMonitor(Nanoapp *nanoapp, bool enable, const void *cookie);
89 
90   /**
91    * Handles a nanoapp's request for RTT ranging against a set of devices.
92    *
93    * @param rangingType Specifies if ranging is desired for a single NAN device
94    *        or an AP (access point) ranging request for a list of devices.
95    * @param nanoapp Nanoapp issuing the request.
96    * @param params Non-null pointer to parameters, supplied by the nanoapp via
97    *        chreWifiRequestRangingAsync() or chreWifiNanRequestRangingAsync().
98    * @param cookie Opaque pointer supplied by the nanoapp and passed back in the
99    *        async result.
100    *
101    * @return true if the request was accepted. The result is delivered
102    *         asynchronously through a CHRE event.
103    */
104   bool requestRanging(RangingType rangingType, Nanoapp *nanoapp,
105                       const void *params, const void *cookie);
106 
107   /**
108    * Performs an active wifi scan.
109    *
110    * This is currently a 1:1 mapping into the PAL. If more than one nanoapp
111    * requests an active wifi scan, this will be an assertion failure for
112    * debug builds and a no-op in production (ie: subsequent requests are
113    * ignored).
114    *
115    * @param nanoapp The nanoapp that has requested an active wifi scan.
116    * @param params Non-null pointer to the scan parameters structure
117    *        supplied by the nanoapp.
118    * @param cookie A cookie that is round-tripped back to the nanoapp to
119    *        provide a context when making the request.
120    * @return true if the request was accepted. The result is delivered
121    *         asynchronously through a CHRE event.
122    */
123   bool requestScan(Nanoapp *nanoapp, const chreWifiScanParams *params,
124                    const void *cookie);
125 
126   /**
127    * Subscribe to a NAN service.
128    *
129    * @param nanoapp The nanoapp that has requested a service subscription.
130    * @param config Service-specific nanoapp subscription configuration
131    *        parameters.
132    * @param cookie A cookie that is round-tripped back to the nanoapp to provide
133    *        a context when making the request.
134    * @return true if a subscription request was successful. The result is
135    *         provided asynchronously through a CHRE event.
136    */
137   bool nanSubscribe(Nanoapp *nanoapp,
138                     const struct chreWifiNanSubscribeConfig *config,
139                     const void *cookie);
140 
141   /**
142    * Cancel a NAN subscription.
143    *
144    * @param nanoapp The nanoapp that has requested a subscription cancelation.
145    * @param subscriptionId The subscription ID assigned by the NAN engine for
146    *        the original subscription request.
147    *        cancelation request was successful.
148    * @return true if the cancelation was successful, false otherwise.
149    */
150   bool nanSubscribeCancel(Nanoapp *nanoapp, uint32_t subscriptionId);
151 
152   /**
153    * Passes the result of an RTT ranging request on to the requesting nanoapp.
154    *
155    * @param errorCode Value from enum chreError
156    * @param event Event containing ranging results, or null if errorCode is not
157    *        chreError
158    */
159   void handleRangingEvent(uint8_t errorCode,
160                           struct chreWifiRangingEvent *event);
161 
162   /**
163    * Handles the result of a request to PlatformWifi to change the state of the
164    * scan monitor.
165    *
166    * @param enabled true if the result of the operation was an enabled scan
167    *        monitor.
168    * @param errorCode an error code that is provided to indicate success or what
169    *        type of error has occurred. See the chreError enum in the CHRE API
170    *        for additional details.
171    */
172   void handleScanMonitorStateChange(bool enabled, uint8_t errorCode);
173 
174   /**
175    * Handles the result of a request to the PlatformWifi to request an active
176    * Wifi scan.
177    *
178    * @param pending The result of the request was successful and the results
179    *        be sent via the handleScanEvent method.
180    * @param errorCode an error code that is used to indicate success or what
181    *        type of error has occurred. See the chreError enum in the CHRE API
182    *        for additional details.
183    */
184   void handleScanResponse(bool pending, uint8_t errorCode);
185 
186   /**
187    * Handles a CHRE wifi scan event.
188    *
189    * @param event The wifi scan event provided to the wifi request manager. This
190    *        memory is guaranteed not to be modified until it has been explicitly
191    *        released through the PlatformWifi instance.
192    */
193   void handleScanEvent(struct chreWifiScanEvent *event);
194 
195   /**
196    * Updates the NAN availability state.
197    *
198    * @param available Whether NAN is available to use.
199    */
200   void updateNanAvailability(bool available);
201 
202   /**
203    * Handles a NAN service identifier event. This event is the asynchronous
204    * result of a NAN subscription request by a nanoapp.
205    *
206    * @param errorCode CHRE_ERROR_NONE if the NAN engine was able to successfully
207    *        assign an ID to the subscription request, an appropriate error code
208    *        from @ref enum chreError otherwise.
209    * @param subscriptionId The ID assigned by the NAN engine to the subscription
210    *        request. Note that this argument is invalid if the errorCode is not
211    *        CHRE_ERROR_NONE.
212    */
213   void handleNanServiceIdentifierEvent(uint8_t errorCode,
214                                        uint32_t subscriptionId);
215 
216   /**
217    * Handles a NAN service discovery event. This event is invoked when a NAN
218    * publisher was found that conforms to the configuration parameters in the
219    * service subscription request.
220    *
221    * @param event Structure that contains information specific to the publisher
222    *        that was discovered.
223    */
224   void handleNanServiceDiscoveryEvent(struct chreWifiNanDiscoveryEvent *event);
225 
226   /**
227    * Handles a NAN service lost event that is initiated when a publisher has
228    * disappeared.
229    *
230    * @param subscriptionId The subscriber to notify of the publisher's
231    *        disappearance.
232    * @param publisherId The publisher who has gone away.
233    */
234   void handleNanServiceLostEvent(uint32_t subscriptionId, uint32_t publisherId);
235 
236   /**
237    * Handles a NAN service terminated event.
238    *
239    * @param errorCode A value in @ref enum chreError that indicates the reason
240    *        for the termination.
241    * @param subscriptionId The ID of the subscriber who should be notified of
242    *        the service termination.
243    */
244   void handleNanServiceTerminatedEvent(uint8_t errorCode,
245                                        uint32_t subscriptionId);
246 
247   /**
248    * Handles a NAN service subscription cancelation event.
249    *
250    * @param errorCode An error code from enum chreError, with CHRE_ERROR_NONE
251    *        indicating successfully canceling a subscription.
252    * @param subscriptionId The ID of the subscribe session which has now been
253    *        canceled.
254    */
255   void handleNanServiceSubscriptionCanceledEvent(uint8_t errorCode,
256                                                  uint32_t subscriptionId);
257 
258   /**
259    * Prints state in a string buffer. Must only be called from the context of
260    * the main CHRE thread.
261    *
262    * @param debugDump The debug dump wrapper where a string can be printed
263    *     into one of the buffers.
264    */
265   void logStateToBuffer(DebugDumpWrapper &debugDump) const;
266 
267   /**
268    * Invoked when the host notifies CHRE that there has been a change in the
269    * WiFi access via the user settings.
270    *
271    * @param setting The setting that changed.
272    * @param enabled Whether setting is enabled or not.
273    */
274   void onSettingChanged(Setting setting, bool enabled);
275 
276   /**
277    * Disables pending scan monitoring and NAN subscription for a nanoapp
278    *
279    * @param nanoapp A non-null pointer to the nanoapp.
280    *
281    * @return The number of subscriptions disabled.
282    */
283   uint32_t disableAllSubscriptions(Nanoapp *nanoapp);
284 
285   /**
286    * Get the number of current active NAN subscriptions.
287    *
288    * @return Number of active NAN subscriptions.
289    */
getNumNanSubscriptions()290   size_t getNumNanSubscriptions() const {
291     return mNanoappSubscriptions.size();
292   }
293 
294  private:
295   struct PendingRequestBase {
296     uint16_t nanoappInstanceId;  //!< ID of the Nanoapp issuing this request
297     const void *cookie;          //!< User data supplied by the nanoapp
298 
299     PendingRequestBase() = default;
PendingRequestBasePendingRequestBase300     PendingRequestBase(uint16_t nanoappInstanceId_, const void *cookie_)
301         : nanoappInstanceId(nanoappInstanceId_), cookie(cookie_) {}
302   };
303 
304   struct PendingRangingRequestBase : public PendingRequestBase {
305     RangingType type;
306   };
307 
308   struct PendingNanSubscribeRequest : public PendingRequestBase {
309     uint8_t type;
310     Buffer<char> service;
311     Buffer<uint8_t> serviceSpecificInfo;
312     Buffer<uint8_t> matchFilter;
313   };
314 
315   /**
316    * Structure used to store ranging target information in the ranging
317    * requests pending queue. Since NAN and AP ranging target params are
318    * heterogeneous structures (NAN ranging params is a small subset of an AP
319    * ranging target), both structures are included in the pending request
320    * with the appropriate structure populated based on the ranging type.
321    */
322   struct PendingRangingRequest : public PendingRangingRequestBase {
323     //! If the request was queued, a variable-length list of devices to
324     //! perform ranging against (used to reconstruct chreWifiRangingParams).
325     Buffer<struct chreWifiRangingTarget> targetList;
326 
327     //! Structure which contains the MAC address of a peer NAN device with
328     //! which ranging is desired.
329     struct chreWifiNanRangingParams nanRangingParams;
330   };
331 
332   struct PendingScanMonitorRequest : public PendingRequestBase {
333     bool enable;  //!< Requested scan monitor state
334   };
335 
336   struct PendingScanRequest : public PendingRequestBase {
337     struct chreWifiScanParams scanParams;
338 
PendingScanRequestPendingScanRequest339     PendingScanRequest(uint16_t nanoappInstanceId_, const void *cookie_,
340                        const struct chreWifiScanParams *scanParams_)
341         : PendingRequestBase(nanoappInstanceId_, cookie_),
342           scanParams(*scanParams_) {}
343   };
344 
345   //! An internal struct to hold scan request data for logging
346   struct WifiScanRequestLog {
WifiScanRequestLogWifiScanRequestLog347     WifiScanRequestLog(Nanoseconds timestampIn, uint16_t instanceIdIn,
348                        chreWifiScanType scanTypeIn, Milliseconds maxScanAgeMsIn)
349         : timestamp(timestampIn),
350           instanceId(instanceIdIn),
351           scanType(scanTypeIn),
352           maxScanAgeMs(maxScanAgeMsIn) {}
353 
354     Nanoseconds timestamp;
355     uint16_t instanceId;
356     enum chreWifiScanType scanType;
357     Milliseconds maxScanAgeMs;
358   };
359 
360   struct NanoappNanSubscriptions {
361     uint16_t nanoappInstanceId;
362     uint32_t subscriptionId;
363 
NanoappNanSubscriptionsNanoappNanSubscriptions364     NanoappNanSubscriptions(uint16_t nappId, uint32_t subId)
365         : nanoappInstanceId(nappId), subscriptionId(subId) {}
366   };
367 
368   enum class PendingNanConfigType { UNKNOWN, ENABLE, DISABLE };
369 
370   static constexpr size_t kMaxPendingScanRequest = 4;
371   static constexpr size_t kMaxScanMonitorStateTransitions = 8;
372   static constexpr size_t kMaxPendingRangingRequests = 4;
373   static constexpr size_t kMaxPendingNanSubscriptionRequests = 4;
374 
375   PlatformWifi mPlatformWifi;
376 
377   //! The queue of state transition requests for the scan monitor. Only one
378   //! asynchronous scan monitor state transition can be in flight at one time.
379   //! Any further requests are queued here.
380   ArrayQueue<PendingScanMonitorRequest, kMaxScanMonitorStateTransitions>
381       mPendingScanMonitorRequests;
382 
383   //! The queue of scan request. Only one asynchronous scan monitor state
384   //! transition can be in flight at one time. Any further requests are queued
385   //! here.
386   ArrayQueue<PendingScanRequest, kMaxPendingScanRequest> mPendingScanRequests;
387 
388   //! The list of nanoapps who have enabled scan monitoring. This list is
389   //! maintained to ensure that nanoapps are always subscribed to wifi scan
390   //! results as requested. Note that a request for wifi scan monitoring can
391   //! exceed the duration of a single active wifi scan request. This makes it
392   //! insuitable only subscribe to wifi scan events when an active request is
393   //! made and the scan monitor must remain enabled when an active request has
394   //! completed.
395   DynamicVector<uint16_t> mScanMonitorNanoapps;
396 
397   //! The list of nanoapps that have an active NAN subscription. The pair
398   //! format that is used is <subscriptionId, nanoappInstanceId>.
399   DynamicVector<NanoappNanSubscriptions> mNanoappSubscriptions;
400 
401   //! This is set to true if the results of an active scan request are pending.
402   bool mScanRequestResultsArePending = false;
403 
404   //! Accumulates the number of scan event results to determine when the last
405   //! in a scan event stream has been received.
406   uint8_t mScanEventResultCountAccumulator = 0;
407 
408   bool mNanIsAvailable = false;
409   bool mNanConfigRequestToHostPending = false;
410   PendingNanConfigType mNanConfigRequestToHostPendingType =
411       PendingNanConfigType::UNKNOWN;
412 
413   //! Tracks the in-flight ranging request and any others queued up behind it
414   ArrayQueue<PendingRangingRequest, kMaxPendingRangingRequests>
415       mPendingRangingRequests;
416 
417   //! Tracks pending NAN subscribe requests.
418   ArrayQueue<PendingNanSubscribeRequest, kMaxPendingNanSubscriptionRequests>
419       mPendingNanSubscribeRequests;
420 
421   //! List of most recent wifi scan request logs
422   static constexpr size_t kNumWifiRequestLogs = 10;
423   ArrayQueue<WifiScanRequestLog, kNumWifiRequestLogs> mWifiScanRequestLogs;
424 
425   //! Manages the timer when a ranging request is dispatched to the PAL.
426   TimerHandle mRequestRangingTimeoutHandle;
427 
428   //! Manages the timer that starts when a configure scan monitor request is
429   //! dispatched to the PAL.
430   TimerHandle mConfigureScanMonitorTimeoutHandle;
431 
432   //! Manages the timer that starts when a configure scan request is dispatched
433   //! to the PAL.
434   TimerHandle mScanRequestTimeoutHandle = CHRE_TIMER_INVALID;
435 
436   //! System time when the last WiFi scan event was received.
437   Milliseconds mLastScanEventTime;
438 
439   //! ErrorCode Histogram for collected errors, the index of this array
440   //! corresponds to the type of the errorcode
441   uint32_t mScanMonitorErrorHistogram[CHRE_ERROR_SIZE] = {0};
442   uint32_t mActiveScanErrorHistogram[CHRE_ERROR_SIZE] = {0};
443 
444   /**
445    * @return true if the scan monitor is enabled by any nanoapps.
446    */
447   bool scanMonitorIsEnabled() const;
448 
449   /**
450    * Check if a nanoapp already has a pending scan request.
451    *
452    * @param instanceId the instance ID of the nanoapp.
453    * @return true if the nanoapp already has a pending scan request in queue.
454    */
455   bool nanoappHasPendingScanRequest(uint16_t instanceId) const;
456 
457   /**
458    * @param instanceId the instance ID of the nanoapp.
459    * @param index an optional pointer to a size_t to populate with the index of
460    *        the nanoapp in the list of nanoapps.
461    *
462    * @return true if the nanoapp has an active request for scan monitoring.
463    */
464   bool nanoappHasScanMonitorRequest(uint16_t instanceId,
465                                     size_t *index = nullptr) const;
466 
467   /**
468    * Returns whether the nanoapp has a pending activation for scan monitoring.
469    *
470    * @param instanceId the instance ID of the nanoapp.
471    *
472    * @return whether the nanoapp has a pending request for scan monitoring.
473    */
474   bool nanoappHasPendingScanMonitorRequest(uint16_t instanceId) const;
475 
476   /**
477    * @param requestedState The requested state to compare against.
478    * @param nanoappHasRequest The requesting nanoapp has an existing request.
479    *
480    * @return true if the scan monitor is in the requested state.
481    */
482   bool scanMonitorIsInRequestedState(bool requestedState,
483                                      bool nanoappHasRequest) const;
484 
485   /**
486    * @param requestedState The requested state to compare against.
487    * @param nanoappHasRequest The requesting nanoapp has an existing request.
488    *
489    * @return true if a state transition is required to reach the requested
490    * state.
491    */
492   bool scanMonitorStateTransitionIsRequired(bool requestedState,
493                                             bool nanoappHasRequest) const;
494 
495   /**
496    * Builds a scan monitor state transition and adds it to the queue of incoming
497    * requests.
498    * @param nanoapp A non-null pointer to a nanoapp that is requesting the
499    *        change.
500    * @param enable The target requested scan monitoring state.
501    * @param cookie The pointer cookie passed in by the calling nanoapp to return
502    *        to the nanoapp when the request completes.
503    *
504    * @return true if the request is enqueued or false if the queue is full.
505    */
506   bool addScanMonitorRequestToQueue(Nanoapp *nanoapp, bool enable,
507                                     const void *cookie);
508 
509   /**
510    * Adds a nanoapp to the list of nanoapps that are monitoring for wifi scans.
511    * @param enable true if enabling scan monitoring.
512    * @param instanceId The instance ID of the scan monitoring nanoapp.
513    *
514    * @return true if the nanoapp was added to the list.
515    */
516   bool updateNanoappScanMonitoringList(bool enable, uint16_t instanceId);
517 
518   /**
519    * Posts an event to a nanoapp indicating the result of a wifi scan monitoring
520    * configuration change.
521    *
522    * @param nanoappInstanceId The nanoapp instance ID to direct the event to.
523    * @param success If the request for a wifi resource was successful.
524    * @param enable The target state of the request. If enable is set to false
525    *        and the request was successful, the nanoapp is removed from the
526    *        list of nanoapps requesting scan monitoring.
527    * @param errorCode The error code when success is set to false.
528    * @param cookie The cookie to be provided to the nanoapp. This is
529    *        round-tripped from the nanoapp to provide context.
530    *
531    * @return true if the event was successfully posted to the event loop.
532    */
533   bool postScanMonitorAsyncResultEvent(uint16_t nanoappInstanceId, bool success,
534                                        bool enable, uint8_t errorCode,
535                                        const void *cookie);
536 
537   /**
538    * Calls through to postScanMonitorAsyncResultEvent but invokes the
539    * FATAL_ERROR macro if the event is not posted successfully. This is used in
540    * asynchronous contexts where a nanoapp could be stuck waiting for a response
541    * but CHRE failed to enqueue one. For parameter details,
542    * @see postScanMonitorAsyncResultEvent
543    */
544   void postScanMonitorAsyncResultEventFatal(uint16_t nanoappInstanceId,
545                                             bool success, bool enable,
546                                             uint8_t errorCode,
547                                             const void *cookie);
548 
549   /**
550    * Posts an event to a nanoapp indicating the result of a request for an
551    * active wifi scan.
552    *
553    * @param nanoappInstanceId The nanoapp instance ID to direct the event to.
554    * @param success If the request for a wifi resource was successful.
555    * @param errorCode The error code when success is set to false.
556    * @param cookie The cookie to be provided to the nanoapp. This is
557    *        round-tripped from the nanoapp to provide context.
558    *
559    * @return true if the event was successfully posted to the event loop.
560    */
561   bool postScanRequestAsyncResultEvent(uint16_t nanoappInstanceId, bool success,
562                                        uint8_t errorCode, const void *cookie);
563 
564   /**
565    * Calls through to postScanRequestAsyncResultEvent but invokes the
566    * FATAL_ERROR macro if the event is not posted successfully. This is used in
567    * asynchronous contexts where a nanoapp could be stuck waiting for a response
568    * but CHRE failed to enqueue one. For parameter details,
569    * @see postScanRequestAsyncResultEvent
570    */
571   void postScanRequestAsyncResultEventFatal(uint16_t nanoappInstanceId,
572                                             bool success, uint8_t errorCode,
573                                             const void *cookie);
574 
575   /**
576    * Posts a broadcast event containing the results of a wifi scan. Failure to
577    * post this event is a FATAL_ERROR. This is unrecoverable as the nanoapp will
578    * be stuck waiting for wifi scan results but there may be a gap.
579    *
580    * @param event the wifi scan event.
581    */
582   void postScanEventFatal(chreWifiScanEvent *event);
583 
584   /**
585    * Posts an event to a nanoapp indicating the async result of a NAN operation.
586    *
587    * @param nanoappInstanceId Instance ID of the nanoapp to post the event to.
588    * @param requestType A value in @ref enum chreWifiRequestType that indicates
589    *        the type of the NAN request this event is a response to.
590    * @param success true if the request was successful, false otherwise.
591    * @param errorCode A value in @ref enum chreError that indicates a failure
592    *        reason (if any, CHRE_ERROR_NONE indicates success) for the request.
593    * @param cookie A cookie that is round-tripped back to the nanoapp to
594    *        provide a context when making the request.
595    */
596   void postNanAsyncResultEvent(uint16_t nanoappInstanceId, uint8_t requestType,
597                                bool success, uint8_t errorCode,
598                                const void *cookie);
599 
600   /**
601    * Handles the result of a request to PlatformWifi to change the state of the
602    * scan monitor. See the handleScanMonitorStateChange method which may be
603    * called from any thread. This method is intended to be invoked on the CHRE
604    * event loop thread.
605    *
606    * @param enabled true if the result of the operation was an enabled scan
607    *        monitor.
608    * @param errorCode an error code that is provided to indicate success or what
609    *        type of error has occurred. See the chreError enum in the CHRE API
610    *        for additional details.
611    */
612   void handleScanMonitorStateChangeSync(bool enabled, uint8_t errorCode);
613 
614   /**
615    * Handles the result of a request to PlatformWifi to perform an active WiFi
616    * scan. See the handleScanResponse method which may be called from any
617    * thread. This method is intended to be invoked on the CHRE event loop
618    * thread.
619    *
620    * @param enabled true if the result of the operation was an enabled scan
621    *        monitor.
622    * @param errorCode an error code that is provided to indicate success or what
623    *        type of error has occurred. See the chreError enum in the CHRE API
624    *        for additional details.
625    */
626   void handleScanResponseSync(bool pending, uint8_t errorCode);
627 
628   /**
629    * Handles the result of a NAN subscription request.
630    *
631    * @param errorCode A value in @ref enum chrError that indicates the status
632    *        of the operation, with CHRE_ERROR_NONE indicating success.
633    * @param subscriptionId An identifier that is assigned to the subscribing
634    *        NAN service after a subscription request. This ID is only valid
635    *        if the errorCode is CHRE_ERROR_NONE.
636    */
637   void handleNanServiceIdentifierEventSync(uint8_t errorCode,
638                                            uint32_t subscriptionId);
639 
640   /**
641    * Handles the result of the successful discovery of a publishing service
642    * that matches the configuration specified by the subscription request.
643    *
644    * @param event Structure containing information specific to the publishing
645    *        service. CHRE retains ownership of the memory associated with this
646    *        structure until it releases it via a call to the function
647    *        freeNanDiscoveryEventCallback().
648    */
649   void handleNanServiceDiscoveryEventSync(
650       struct chreWifiNanDiscoveryEvent *event);
651 
652   /**
653    * Handles the event informing CHRE that a publishing service has gone away.
654    *
655    * @param subscriptionId The ID of the subscribing service which will be
656    *        informed of the publisher's disappearance.
657    * @param publisherId The ID of the publishing service that has gone away.
658    */
659   void handleNanServiceLostEventSync(uint32_t subscriptionId,
660                                      uint32_t publisherId);
661 
662   /**
663    * Handles the event informing CHRE that a subscription has been terminated.
664    *
665    * @param errorCode A value in @ref enum chreError that indicates the reason
666    *        for the service's subscription termination.
667    * @param subscriptionId The ID of the service whose subscription has ended.
668    */
669   void handleNanServiceTerminatedEventSync(uint8_t errorCode,
670                                            uint32_t subscriptionId);
671 
672   /**
673    * Handles the event informing CHRE the result of a subscription cancelation.
674    *
675    * @param errorCode A value in @ref enum chreError with CHRE_ERROR_NONE
676    *        indicating successful cancelation, an error code otherwise.
677    * @param subscriptionId The ID of the service whose subscription has been
678    *        canceled.
679    */
680   void handleNanServiceSubscriptionCanceledEventSync(uint8_t errorCode,
681                                                      uint32_t subscriptionId);
682 
683   /**
684    * Handles event informing CHRE whether NAN is available.
685    *
686    * @param available Whether NAN is available to use.
687    */
688   void handleNanAvailabilitySync(bool available);
689 
690   /**
691    * Sends CHRE_EVENT_WIFI_ASYNC_RESULT for the ranging request at the head
692    * of the pending queue.
693    *
694    * @param errorCode Indicates the overall result of the ranging operation
695    *
696    * @return true on success
697    */
698   bool postRangingAsyncResult(uint8_t errorCode);
699 
700   /**
701    * Keep issuing pending configure scan monitor request to the platform in
702    * queued order util a successful dispatch or the queue is empty
703    */
704   void dispatchQueuedConfigureScanMonitorRequests();
705 
706   /**
707    * Issues the pending scan requests to the platform in queued order until one
708    * dispatched successfully or the queue is empty.
709    *
710    * @param postAsyncResult if a dispatch failure should post a async result.
711    * @return true if successfully dispatched one request.
712    */
713   bool dispatchQueuedScanRequests(bool postAsyncResult);
714 
715   /**
716    * Issues the next pending ranging request to the platform.
717    *
718    * @return Result of PlatformWifi::requestRanging()
719    */
720   bool dispatchQueuedRangingRequest();
721 
722   /**
723    * Issues the next pending NAN ranging request to the platform.
724    */
725   bool dispatchQueuedNanSubscribeRequest();
726 
727   /**
728    * If a failure while dispatching the NAN subscribe requests, tries to
729    * dispatch it again until the first one succeeds.
730    */
731   void dispatchQueuedNanSubscribeRequestWithRetry();
732 
733   /**
734    * Processes the result of a ranging request within the context of the CHRE
735    * thread.
736    *
737    * @param errorCode Result of the ranging operation
738    * @param event On success, pointer to event data provided by platform
739    */
740   void handleRangingEventSync(uint8_t errorCode,
741                               struct chreWifiRangingEvent *event);
742 
743   /**
744    * Handles the releasing of a WiFi scan event and unsubscribes a nanoapp who
745    * has made an active request for a wifi scan from WiFi scan events in the
746    * future (if it has not subscribed to passive events).
747    *
748    * @param scanEvent The scan event to release.
749    */
750   void handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent);
751 
752   /**
753    * Adds a wifi scan request log onto list possibly kicking earliest log out
754    * if full.
755    *
756    * @param nanoappInstanceId The instance Id of the requesting nanoapp
757    * @param params The chre wifi scan params
758    */
759   void addWifiScanRequestLog(uint16_t nanoappInstanceId,
760                              const chreWifiScanParams *params);
761 
762   /**
763    * Releases a wifi event (scan, ranging, NAN discovery) after nanoapps have
764    * consumed it.
765    *
766    * @param eventType the type of event being freed.
767    * @param eventData a pointer to the scan event to release.
768    */
769   static void freeWifiScanEventCallback(uint16_t eventType, void *eventData);
770   static void freeWifiRangingEventCallback(uint16_t eventType, void *eventData);
771   static void freeNanDiscoveryEventCallback(uint16_t eventType,
772                                             void *eventData);
773 
774   /**
775    * Copy a NAN subscription configuration to a pending NAN subscription
776    * request before dispatch.
777    *
778    * @param request The pending subscribe request being queued up for dispatch.
779    * @param config NAN service subscription configuration parameters.
780    * @return true if the copy was successful, false otherwise.
781    */
782   bool copyNanSubscribeConfigToRequest(
783       PendingNanSubscribeRequest &request,
784       const struct chreWifiNanSubscribeConfig *config);
785 
786   /**
787    * Rebuild a NAN subscription configuration from a dequed subscription
788    * request.
789    *
790    * @param request The pending NAN subscription request that was dequeued.
791    * @param config The subscription configuration that is to be built from
792    *        the pending request.
793    */
794   void buildNanSubscribeConfigFromRequest(
795       const PendingNanSubscribeRequest &request,
796       struct chreWifiNanSubscribeConfig *config);
797 
798   /**
799    * Scan through the nanoapp-subscription ID pair list to find the nanoapp
800    * that holds a subscription ID.
801    *
802    * @param subscriptionId The subscription ID that the nanoapp being searched
803    *        for owns.
804    * @return The instance ID of the nanoapp which owns the subscription ID if
805    *         it was found in the list, an invalid value otherwise.
806    */
807   bool getNappIdFromSubscriptionId(uint32_t subscriptionId,
808                                    uint16_t *nanoappInstanceId);
809 
810   /**
811    * Sends an AP (access point) or NAN ranging request to the platform.
812    *
813    * @param rangingType A value in WifiRequestManager::RangingType that denotes
814    *        the type of the ranging request.
815    * @param rangingParams The parameters of the ranging request.
816    */
817   bool requestRangingByType(RangingType rangingType, const void *rangingParams);
818 
819   /**
820    * Update a ranging request with the provided ranging parameters.
821    *
822    * @param rangingType A value in WifiRequestManager::RangingType that denotes
823    *        the type of the ranging request.
824    * @param request A pending ranging request which needs to be updated with the
825    *        provided ranging parameters.
826    * @param rangingParams The parameters of the ranging request.
827    */
828   bool updateRangingRequest(RangingType rangingType,
829                             PendingRangingRequest &request,
830                             const void *rangingParams);
831 
832   /**
833    * Send a pending AP or NAN ranging request to the platform.
834    *
835    * @param request A pending ranging request which needs to be updated with the
836    *        provided ranging parameters.
837    * @return true if the request was successfully sent, false otherwise.
838    */
839   bool sendRangingRequest(PendingRangingRequest &request);
840 
841   /**
842    * Helper function to determine if all the settings required for a ranging
843    * request (viz. Location, WiFi-available) are enabled.
844    *
845    * @return true if the necessary settings are enabled, false otherwise.
846    */
847   bool areRequiredSettingsEnabled();
848 
849   /**
850    * Helper function to cancel all existing nanoapp NAN subscriptions and
851    * inform the nanoapps owning the subscriptions of the cancelation with
852    * a NAN session terminated event.
853    */
854   void cancelNanSubscriptionsAndInformNanoapps();
855 
856   /**
857    * Helper function to cancel all pending NAN subscription requests and
858    * inform the nanoapps making the request of the cancelation with a WiFi
859    * async result event.
860    */
861   void cancelNanPendingRequestsAndInformNanoapps();
862 
863   /**
864    * Sends a config request to the host to enable or disable NAN functionality.
865    * The function checks if a request is already pending or if the pending
866    * request type opposes the current request and only then sends the request
867    * across to avoid duplicate requests.
868    *
869    * @param enable Indicates if a NAN enable or disable is being requested.
870    */
871   void sendNanConfiguration(bool enable);
872 
873   /**
874    * Invoked on no response for a configure scan monitor request in the expected
875    * window.
876    */
877   void handleConfigureScanMonitorTimeout();
878 
879   /**
880    * Sets up the system timer that invokes handleConfigureScanMonitorTimeout
881    * when the PAL does not respond to configure scan monitor request on time.
882    *
883    * @return TimerHandle that can be used later to cancel the timer if the PAL
884    * has responded in the expected time window.
885    */
886   TimerHandle setConfigureScanMonitorTimer();
887 
888   /**
889    * Invoked on no response for a ranging request in the expected window.
890    */
891   void handleRangingRequestTimeout();
892 
893   /**
894    * Sets up the system timer that invokes handleRangingRequestTimeout when the
895    * PAL does not respond on time.
896    *
897    * @return TimerHandle that can be used later to cancel the timer if the PAL
898    * has responded in the expected time window.
899    */
900   TimerHandle setRangingRequestTimer();
901 
902   /**
903    * Invoked on no response for a scan request in the expected window.
904    */
905   void handleScanRequestTimeout();
906 
907   /**
908    * Sets up the system timer that invokes handleScanRequestTimeout when the
909    * PAL does not respond on time.
910    *
911    * @return TimerHandle that can be used later to cancel the timer if the PAL
912    * has responded in the expected time window.
913    */
914   TimerHandle setScanRequestTimer();
915 };
916 
917 }  // namespace chre
918 
919 #endif  // CHRE_CORE_WIFI_REQUEST_MANAGER_H_
920