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